mirror of
https://github.com/n8n-io/n8n.git
synced 2026-08-28 17:22:01 +08:00
refactor(editor): Extract otel into a frontend module package (no-changelog) (#36679)
Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: multica-agent <github@multica.ai> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: alexgrozav <6179477+alexgrozav@users.noreply.github.com> Co-authored-by: CharlieKolb <13814565+CharlieKolb@users.noreply.github.com>
This commit is contained in:
@@ -44,6 +44,7 @@ export const sourcePackages = [
|
||||
*/
|
||||
export const modulePackages: Array<{ name: string; dir: string; entry?: boolean }> = [
|
||||
{ name: '@n8n/frontend-module-instance-registry', dir: 'modules/instance-registry/frontend' },
|
||||
{ name: '@n8n/frontend-module-otel', dir: 'modules/otel/frontend' },
|
||||
];
|
||||
|
||||
// The code below makes the Vite aliases from the two tables. Keep this code in the same file as
|
||||
|
||||
@@ -2,6 +2,31 @@ import { defineConfig } from 'eslint/config';
|
||||
import { frontendConfig } from '@n8n/eslint-config/frontend';
|
||||
import oxlint from 'eslint-plugin-oxlint';
|
||||
|
||||
/**
|
||||
* Extraction ratchet: a feature that has become a module package must not reappear
|
||||
* under `src/features/`. Append one entry per extraction — this list only grows.
|
||||
*
|
||||
* The old path no longer resolves, so this is about the message, not the failure: it
|
||||
* names the package and it says that the shell reaches a module through
|
||||
* `src/app/modules.manifest.ts`, not through a deep path.
|
||||
*
|
||||
* Spread into every block that sets `no-restricted-imports`. Flat-config replaces
|
||||
* rule options rather than merging them, so a scoped block that omits these patterns
|
||||
* would switch the ratchet off for its own files.
|
||||
*/
|
||||
const extractedFeatures = [
|
||||
{
|
||||
group: ['@/features/instanceRegistry', '@/features/instanceRegistry/*'],
|
||||
message:
|
||||
'instanceRegistry is the @n8n/frontend-module-instance-registry package. The shell registers a module through src/app/modules.manifest.ts.',
|
||||
},
|
||||
{
|
||||
group: ['@/features/settings/otel', '@/features/settings/otel/*'],
|
||||
message:
|
||||
'otel is the @n8n/frontend-module-otel package. The shell registers a module through src/app/modules.manifest.ts.',
|
||||
},
|
||||
];
|
||||
|
||||
export default defineConfig(
|
||||
frontendConfig,
|
||||
{
|
||||
@@ -238,6 +263,7 @@ export default defineConfig(
|
||||
'@typescript-eslint/no-unsafe-argument': 'warn',
|
||||
'@typescript-eslint/no-unsafe-member-access': 'warn',
|
||||
'@typescript-eslint/no-unsafe-return': 'warn',
|
||||
'@typescript-eslint/no-restricted-imports': ['error', { patterns: extractedFeatures }],
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -299,6 +325,7 @@ export default defineConfig(
|
||||
'error',
|
||||
{
|
||||
patterns: [
|
||||
...extractedFeatures,
|
||||
{
|
||||
group: ['**/ndv/runData/components/RunData.vue'],
|
||||
message:
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
"@n8n/design-system": "workspace:*",
|
||||
"@n8n/frontend-constants": "workspace:*",
|
||||
"@n8n/frontend-module-instance-registry": "workspace:*",
|
||||
"@n8n/frontend-module-otel": "workspace:*",
|
||||
"@n8n/frontend-module-sdk": "workspace:*",
|
||||
"@n8n/frontend-utils": "workspace:*",
|
||||
"@n8n/i18n": "workspace:*",
|
||||
|
||||
@@ -5,9 +5,9 @@ import { MCPModule } from '@/features/ai/mcpAccess/module.descriptor';
|
||||
import { ChatModule } from '@/features/ai/chatHub/module.descriptor';
|
||||
import { InstanceAiModule } from '@/features/ai/instanceAi/module.descriptor';
|
||||
import { AgentsModule } from '@/features/agents/module.descriptor';
|
||||
import { OtelModule } from '@/features/settings/otel/module.descriptor';
|
||||
import { WorkflowReviewsModule } from '@/features/workflow-reviews/module.descriptor';
|
||||
import { InstanceRegistryModule } from '@n8n/frontend-module-instance-registry';
|
||||
import { OtelModule } from '@n8n/frontend-module-otel';
|
||||
|
||||
/**
|
||||
* Hard-coding modules list until we have a dynamic way to load modules.
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import { OtelModule } from '@n8n/frontend-module-otel';
|
||||
import { useRBACStore } from '@n8n/stores/rbac.store';
|
||||
import { useSettingsStore } from '@n8n/stores/settings.store';
|
||||
import { createPinia, setActivePinia } from 'pinia';
|
||||
|
||||
import { useUIStore } from '@/app/stores/ui.store';
|
||||
|
||||
/**
|
||||
* Guards the shell half of the settings-sidebar gate: `settingsSidebarItems` drops
|
||||
* the pages of a module the instance has not activated.
|
||||
*
|
||||
* Driven with a real module descriptor rather than a fixture, because the gate only
|
||||
* holds if the descriptor's `id` is the same id `/rest/module-settings` reports.
|
||||
* The scope half of the old gate lives in the descriptor's `available` getter and is
|
||||
* covered by `otel.module.test.ts` in the module package.
|
||||
*/
|
||||
describe('uiStore.settingsSidebarItems', () => {
|
||||
const registerOtel = ({ moduleActive }: { moduleActive: boolean }) => {
|
||||
const settingsStore = useSettingsStore();
|
||||
settingsStore.settings = {
|
||||
...settingsStore.settings,
|
||||
activeModules: moduleActive ? [OtelModule.id] : [],
|
||||
};
|
||||
|
||||
useRBACStore().setGlobalScopes(['otel:manage']);
|
||||
|
||||
const uiStore = useUIStore();
|
||||
uiStore.registerSettingsPages(OtelModule.id, OtelModule.settingsPages ?? []);
|
||||
|
||||
return uiStore;
|
||||
};
|
||||
|
||||
const otelItem = (uiStore: ReturnType<typeof useUIStore>) =>
|
||||
uiStore.settingsSidebarItems.find((item) => item.id === 'settings-opentelemetry');
|
||||
|
||||
beforeEach(() => {
|
||||
setActivePinia(createPinia());
|
||||
});
|
||||
|
||||
it('should list the pages of an active module', () => {
|
||||
const uiStore = registerOtel({ moduleActive: true });
|
||||
|
||||
expect(otelItem(uiStore)?.available).toBe(true);
|
||||
});
|
||||
|
||||
it('should drop the pages of an inactive module, even when the user holds the scope', () => {
|
||||
const uiStore = registerOtel({ moduleActive: false });
|
||||
|
||||
expect(otelItem(uiStore)).toBeUndefined();
|
||||
});
|
||||
});
|
||||
@@ -1,98 +0,0 @@
|
||||
import { createPinia, setActivePinia } from 'pinia';
|
||||
import { useRBACStore } from '@n8n/stores/rbac.store';
|
||||
import { useSettingsStore } from '@n8n/stores/settings.store';
|
||||
import type { Scope } from '@n8n/permissions';
|
||||
|
||||
import { useUIStore } from '@/app/stores/ui.store';
|
||||
import { OtelModule } from './module.descriptor';
|
||||
import { OTEL_SETTINGS_VIEW } from './otel.constants';
|
||||
|
||||
/**
|
||||
* Guards the shell-to-descriptor move of the otel settings sidebar item.
|
||||
*
|
||||
* The old gate lived in `useSettingsItems.ts` as
|
||||
* `isModuleActive('otel') && hasPermission(['rbac'], { rbac: { scope: 'otel:manage' } })`.
|
||||
* It is now split: `ui.store`'s `settingsSidebarItems` owns the module-active
|
||||
* half, and the descriptor's `available` getter owns the scope half. These tests
|
||||
* exercise the real stores so the two halves together still equal the old gate.
|
||||
*/
|
||||
describe('OtelModule settings sidebar item', () => {
|
||||
const registerOtel = ({
|
||||
moduleActive,
|
||||
scopes,
|
||||
}: {
|
||||
moduleActive: boolean;
|
||||
scopes: Scope[];
|
||||
}) => {
|
||||
const settingsStore = useSettingsStore();
|
||||
settingsStore.settings = {
|
||||
...settingsStore.settings,
|
||||
activeModules: moduleActive ? ['otel'] : [],
|
||||
};
|
||||
|
||||
useRBACStore().setGlobalScopes(scopes);
|
||||
|
||||
const uiStore = useUIStore();
|
||||
uiStore.registerSettingsPages(OtelModule.id, OtelModule.settingsPages ?? []);
|
||||
|
||||
return uiStore;
|
||||
};
|
||||
|
||||
const otelItem = (uiStore: ReturnType<typeof useUIStore>) =>
|
||||
uiStore.settingsSidebarItems.find((item) => item.id === 'settings-opentelemetry');
|
||||
|
||||
beforeEach(() => {
|
||||
setActivePinia(createPinia());
|
||||
});
|
||||
|
||||
it('should hide the item from a user without the otel:manage scope', () => {
|
||||
const uiStore = registerOtel({ moduleActive: true, scopes: [] });
|
||||
|
||||
expect(otelItem(uiStore)?.available).toBe(false);
|
||||
});
|
||||
|
||||
it('should hide the item from a user holding only an unrelated scope', () => {
|
||||
const uiStore = registerOtel({ moduleActive: true, scopes: ['workflow:read'] });
|
||||
|
||||
expect(otelItem(uiStore)?.available).toBe(false);
|
||||
});
|
||||
|
||||
it('should show the item to a user with the otel:manage scope', () => {
|
||||
const uiStore = registerOtel({ moduleActive: true, scopes: ['otel:manage'] });
|
||||
|
||||
expect(otelItem(uiStore)?.available).toBe(true);
|
||||
});
|
||||
|
||||
it('should hide the item when the otel module is inactive, even with the scope', () => {
|
||||
const uiStore = registerOtel({ moduleActive: false, scopes: ['otel:manage'] });
|
||||
|
||||
expect(otelItem(uiStore)).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should re-evaluate availability when scopes change after registration', () => {
|
||||
const uiStore = registerOtel({ moduleActive: true, scopes: [] });
|
||||
expect(otelItem(uiStore)?.available).toBe(false);
|
||||
|
||||
useRBACStore().addGlobalScope('otel:manage');
|
||||
|
||||
expect(otelItem(uiStore)?.available).toBe(true);
|
||||
});
|
||||
|
||||
it('should keep routing to the unchanged SettingsOpenTelemetryView route name', () => {
|
||||
const uiStore = registerOtel({ moduleActive: true, scopes: ['otel:manage'] });
|
||||
|
||||
expect(OTEL_SETTINGS_VIEW).toBe('SettingsOpenTelemetryView');
|
||||
expect(otelItem(uiStore)?.route).toEqual({ to: { name: 'SettingsOpenTelemetryView' } });
|
||||
expect(OtelModule.routes?.[0]).toMatchObject({
|
||||
path: 'opentelemetry',
|
||||
name: 'SettingsOpenTelemetryView',
|
||||
});
|
||||
});
|
||||
|
||||
it('should keep the route rbac middleware, which gates direct URL access', () => {
|
||||
expect(OtelModule.routes?.[0].meta).toMatchObject({
|
||||
middleware: ['authenticated', 'rbac', 'custom'],
|
||||
middlewareOptions: { rbac: { scope: 'otel:manage' } },
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -31,6 +31,8 @@
|
||||
"@n8n/frontend-module-instance-registry/*": [
|
||||
"../../modules/instance-registry/frontend/src/*"
|
||||
],
|
||||
"@n8n/frontend-module-otel": ["../../modules/otel/frontend/src/index.ts"],
|
||||
"@n8n/frontend-module-otel/*": ["../../modules/otel/frontend/src/*"],
|
||||
"@n8n/frontend-utils*": ["../@n8n/frontend-utils/src*"],
|
||||
"@n8n/frontend-constants*": ["../@n8n/frontend-constants/src*"],
|
||||
"@n8n/chat*": ["../@n8n/chat/src*"],
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
# @n8n/frontend-module-otel
|
||||
|
||||
Frontend feature module for the OpenTelemetry settings page. Consumed from source
|
||||
by the editor-ui shell through `src/app/modules.manifest.ts`; there is no build
|
||||
step and no `dist`.
|
||||
|
||||
```bash
|
||||
pnpm turbo typecheck --filter=@n8n/frontend-module-otel
|
||||
pnpm turbo lint --filter=@n8n/frontend-module-otel
|
||||
pnpm turbo test --filter=@n8n/frontend-module-otel
|
||||
```
|
||||
|
||||
Go through turbo, not `pnpm --filter <pkg> typecheck`: this package is consumed
|
||||
from source, and on a cold tree its platform dependencies have not been built
|
||||
yet. Turbo builds them first; the bare pnpm form does not.
|
||||
|
||||
## What this module contributes
|
||||
|
||||
This is the first extracted module with a UI surface. Its descriptor declares a
|
||||
lazy route (`SettingsOpenTelemetryView`) and a `settingsPages` entry. The shell
|
||||
gates both on `isModuleActive('otel')`; the sidebar item additionally gates on
|
||||
the `otel:manage` scope through the descriptor's `available` getter.
|
||||
|
||||
The route name is owned here (`OTEL_SETTINGS_VIEW` in `otel.constants.ts`), not
|
||||
by the shared `VIEWS` enum. `assertUniqueRouteNames` in `@n8n/frontend-module-sdk`
|
||||
keeps the names collision-free.
|
||||
|
||||
Strings still live in the central `@n8n/i18n` `en.json` under
|
||||
`settings.opentelemetry.*`. Per-module locales are a later wave.
|
||||
|
||||
## Import rules
|
||||
|
||||
- Depend on foundation and platform packages only (`@n8n/design-system`,
|
||||
`@n8n/stores`, `@n8n/composables`, `@n8n/i18n`, `@n8n/rest-api-client`,
|
||||
`@n8n/frontend-module-sdk`). Never import another `@n8n/frontend-module-*`,
|
||||
and never import `@/…` from the shell.
|
||||
- `@n8n/stores` and `@n8n/composables` are **subpath-only** — import
|
||||
`@n8n/stores/settings.store`, not `@n8n/stores`.
|
||||
- The no-cross-module rule is currently a convention: the shared tsconfig base
|
||||
omits sibling modules from `paths`, which blocks an accidental import but not
|
||||
a deliberate one (declaring the dependency makes it typecheck clean). The
|
||||
ESLint rule that actually enforces it is CAT-3692.
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"$schema": "../../../../node_modules/@biomejs/biome/configuration_schema.json",
|
||||
"extends": ["../../../../biome.jsonc"]
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
import { defineConfig } from 'eslint/config';
|
||||
import { frontendConfig } from '@n8n/eslint-config/frontend';
|
||||
|
||||
export default defineConfig(frontendConfig);
|
||||
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"name": "@n8n/frontend-module-otel",
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
"main": "src/index.ts",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "rimraf .turbo",
|
||||
"typecheck": "vue-tsc --noEmit",
|
||||
"test": "vitest run",
|
||||
"test:changed": "janitor test-scoped",
|
||||
"test:dev": "vitest",
|
||||
"lint": "eslint src --quiet",
|
||||
"lint:fix": "eslint src --fix",
|
||||
"lint:styles": "stylelint \"src/**/*.{scss,sass,vue}\" --cache",
|
||||
"lint:styles:fix": "stylelint \"src/**/*.{scss,sass,vue}\" --fix --cache",
|
||||
"format": "biome format --write . && prettier --write . --ignore-path ../../../../.prettierignore",
|
||||
"format:check": "biome ci . && prettier --check . --ignore-path ../../../../.prettierignore"
|
||||
},
|
||||
"dependencies": {
|
||||
"@n8n/composables": "workspace:*",
|
||||
"@n8n/design-system": "workspace:*",
|
||||
"@n8n/frontend-module-sdk": "workspace:*",
|
||||
"@n8n/i18n": "workspace:*",
|
||||
"@n8n/rest-api-client": "workspace:*",
|
||||
"@n8n/stores": "workspace:*",
|
||||
"pinia": "catalog:frontend",
|
||||
"vue": "catalog:frontend",
|
||||
"vue-router": "catalog:frontend"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify/json": "catalog:",
|
||||
"@n8n/eslint-config": "workspace:*",
|
||||
"@n8n/frontend-vite-config": "workspace:*",
|
||||
"@n8n/permissions": "workspace:*",
|
||||
"@n8n/playwright-janitor": "workspace:*",
|
||||
"@n8n/stylelint-config": "workspace:*",
|
||||
"@n8n/typescript-config": "workspace:*",
|
||||
"@n8n/vitest-config": "workspace:*",
|
||||
"@pinia/testing": "^0.1.6",
|
||||
"@testing-library/jest-dom": "catalog:frontend",
|
||||
"@testing-library/user-event": "catalog:frontend",
|
||||
"@testing-library/vue": "catalog:frontend",
|
||||
"@vitejs/plugin-vue": "catalog:frontend",
|
||||
"eslint": "catalog:",
|
||||
"stylelint": "catalog:",
|
||||
"typescript": "catalog:",
|
||||
"unplugin-icons": "catalog:frontend",
|
||||
"vite": "catalog:",
|
||||
"vite-svg-loader": "catalog:frontend",
|
||||
"vitest": "catalog:",
|
||||
"vue-tsc": "catalog:frontend"
|
||||
},
|
||||
"license": "LicenseRef-n8n-sustainable-use"
|
||||
}
|
||||
+4
-1
@@ -1,7 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, useCssModule } from 'vue';
|
||||
import { N8nButton, N8nDropdownMenu, N8nIcon } from '@n8n/design-system';
|
||||
import { useI18n } from '@n8n/i18n';
|
||||
import { computed, useCssModule } from 'vue';
|
||||
|
||||
import OtelStatusDot from './OtelStatusDot.vue';
|
||||
|
||||
/*
|
||||
@@ -22,6 +23,8 @@ withDefaults(
|
||||
);
|
||||
|
||||
const emit = defineEmits<{
|
||||
// Vue's `v-model:enabled` contract fixes this name, and no naming format allows a colon.
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
'update:enabled': [enabled: boolean];
|
||||
}>();
|
||||
|
||||
+16
-15
@@ -1,10 +1,11 @@
|
||||
import { createTestingPinia } from '@pinia/testing';
|
||||
import { waitFor } from '@testing-library/vue';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { createComponentRenderer } from '@/__tests__/render';
|
||||
import { waitFor } from '@testing-library/vue';
|
||||
|
||||
import { createComponentRenderer } from './__tests__/render';
|
||||
import type { OtelSettingsResponse } from './otel.api';
|
||||
import { useOtelStore } from './otel.store';
|
||||
import SettingsOpenTelemetryView from './SettingsOpenTelemetryView.vue';
|
||||
import type { OtelSettingsResponse } from './otel.api';
|
||||
|
||||
const showMessage = vi.fn();
|
||||
const showError = vi.fn();
|
||||
@@ -17,10 +18,6 @@ vi.mock('@n8n/composables/useTelemetry', () => ({
|
||||
useTelemetry: () => ({ track: telemetryTrack }),
|
||||
}));
|
||||
|
||||
vi.mock('@/app/composables/useDocumentTitle', () => ({
|
||||
useDocumentTitle: () => ({ set: vi.fn() }),
|
||||
}));
|
||||
|
||||
vi.mock('@n8n/stores/useRootStore', () => ({
|
||||
useRootStore: () => ({ restApiContext: { baseUrl: '', pushRef: '' } }),
|
||||
}));
|
||||
@@ -38,14 +35,18 @@ vi.mock('vue-router', async (importOriginal) => {
|
||||
};
|
||||
});
|
||||
|
||||
const getOtelSettingsMock = vi.fn();
|
||||
const updateOtelSettingsMock = vi.fn();
|
||||
const sendOtelTestTraceMock = vi.fn();
|
||||
// Typed, so the factory below returns `Promise<unknown>` rather than the `any` a bare
|
||||
// `vi.fn()` yields — the module package lints `no-unsafe-return` at error level.
|
||||
type ApiMock = (...args: unknown[]) => Promise<unknown>;
|
||||
|
||||
const getOtelSettingsMock = vi.fn<ApiMock>();
|
||||
const updateOtelSettingsMock = vi.fn<ApiMock>();
|
||||
const sendOtelTestTraceMock = vi.fn<ApiMock>();
|
||||
|
||||
vi.mock('./otel.api', () => ({
|
||||
getOtelSettings: (...args: unknown[]) => getOtelSettingsMock(...args),
|
||||
updateOtelSettings: (...args: unknown[]) => updateOtelSettingsMock(...args),
|
||||
sendOtelTestTrace: (...args: unknown[]) => sendOtelTestTraceMock(...args),
|
||||
getOtelSettings: async (...args: unknown[]) => await getOtelSettingsMock(...args),
|
||||
updateOtelSettings: async (...args: unknown[]) => await updateOtelSettingsMock(...args),
|
||||
sendOtelTestTrace: async (...args: unknown[]) => await sendOtelTestTraceMock(...args),
|
||||
}));
|
||||
|
||||
const makeSettings = (overrides: Partial<OtelSettingsResponse> = {}): OtelSettingsResponse => ({
|
||||
@@ -198,7 +199,7 @@ describe('SettingsOpenTelemetryView', () => {
|
||||
|
||||
await waitFor(() => {
|
||||
expect(showError).toHaveBeenCalledWith(expect.any(Error), expect.any(String));
|
||||
expect(store.settings!.enabled).toBe(false);
|
||||
expect(store.settings.enabled).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -375,7 +376,7 @@ describe('SettingsOpenTelemetryView', () => {
|
||||
await userEvent.type(keyInput, 'x-api-key');
|
||||
|
||||
await waitFor(() => {
|
||||
expect(store.settings!.exporterHeaders).toContain('x-api-key');
|
||||
expect(store.settings.exporterHeaders).toContain('x-api-key');
|
||||
});
|
||||
});
|
||||
|
||||
+14
-7
@@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch, onMounted } from 'vue';
|
||||
import { onBeforeRouteLeave, type NavigationGuardNext } from 'vue-router';
|
||||
import { useDocumentTitle } from '@n8n/composables/useDocumentTitle';
|
||||
import { useTelemetry } from '@n8n/composables/useTelemetry';
|
||||
import { useToast } from '@n8n/composables/useToast';
|
||||
import {
|
||||
N8nButton,
|
||||
N8nCheckbox,
|
||||
@@ -17,11 +18,12 @@ import {
|
||||
N8nSettingsSection,
|
||||
} from '@n8n/design-system';
|
||||
import { useI18n } from '@n8n/i18n';
|
||||
import { useTelemetry } from '@n8n/composables/useTelemetry';
|
||||
import { useToast } from '@n8n/composables/useToast';
|
||||
import { useDocumentTitle } from '@/app/composables/useDocumentTitle';
|
||||
import { useOtelStore, headersStringToPairs, headersPairsToString } from './otel.store';
|
||||
import { useSettingsStore } from '@n8n/stores/settings.store';
|
||||
import { computed, ref, watch, onMounted } from 'vue';
|
||||
import { onBeforeRouteLeave, type NavigationGuardNext } from 'vue-router';
|
||||
|
||||
import { OTEL_FIELD_ENV_VARS, OTEL_TEST_SPAN_NAME } from './otel.constants';
|
||||
import { useOtelStore, headersStringToPairs, headersPairsToString } from './otel.store';
|
||||
import { createSampleRateFormat } from './otel.utils';
|
||||
import OtelSettingsRow from './OtelSettingsRow.vue';
|
||||
import OtelStatusControl from './OtelStatusControl.vue';
|
||||
@@ -31,7 +33,12 @@ const OTEL_DOCS_URL = 'https://docs.n8n.io/hosting/logging-monitoring/openteleme
|
||||
const i18n = useI18n();
|
||||
const telemetry = useTelemetry();
|
||||
const toast = useToast();
|
||||
const documentTitle = useDocumentTitle();
|
||||
// The shell's wrapper adds a claim guard for `setDocumentTitle`, which only the
|
||||
// canvas calls. This view calls `set`, so it uses the platform composable directly
|
||||
// and passes the release channel the wrapper would have supplied.
|
||||
const documentTitle = useDocumentTitle({
|
||||
releaseChannel: useSettingsStore().settings.releaseChannel,
|
||||
});
|
||||
const otelStore = useOtelStore();
|
||||
|
||||
const headerPairs = ref<Array<{ key: string; value: string }>>([]);
|
||||
@@ -0,0 +1,36 @@
|
||||
import { N8nPlugin } from '@n8n/design-system';
|
||||
import { i18nInstance } from '@n8n/i18n';
|
||||
import { render, type RenderOptions as TestingLibraryRenderOptions } from '@testing-library/vue';
|
||||
import type { Pinia } from 'pinia';
|
||||
import { PiniaVuePlugin } from 'pinia';
|
||||
|
||||
/**
|
||||
* The shell's `@/__tests__/render` cannot come with the module: it provides the
|
||||
* workflow-document store and installs shell-only plugins. This module renders one
|
||||
* settings view built from design-system components, so it needs the design-system
|
||||
* directives, i18n and a pinia — nothing else.
|
||||
*/
|
||||
export type RenderOptions<T> = Omit<TestingLibraryRenderOptions<T>, 'props'> & {
|
||||
pinia?: Pinia;
|
||||
props?: Partial<TestingLibraryRenderOptions<T>['props']>;
|
||||
};
|
||||
|
||||
export function createComponentRenderer<T>(component: T, defaultOptions: RenderOptions<T> = {}) {
|
||||
return (options: RenderOptions<T> = {}) => {
|
||||
const { pinia, ...renderOptions } = { ...defaultOptions, ...options };
|
||||
|
||||
return render(component, {
|
||||
...renderOptions,
|
||||
global: {
|
||||
...renderOptions.global,
|
||||
plugins: [
|
||||
i18nInstance,
|
||||
PiniaVuePlugin,
|
||||
N8nPlugin,
|
||||
...(renderOptions.global?.plugins ?? []),
|
||||
...(pinia ? [pinia] : []),
|
||||
],
|
||||
},
|
||||
} as TestingLibraryRenderOptions<T>);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// The shared jsdom harness — observers, matchMedia, canvas, timers, teardown guards.
|
||||
import '@n8n/vitest-config/setup/frontend';
|
||||
|
||||
import { loadLanguage, type LocaleMessages } from '@n8n/i18n';
|
||||
import englishBaseText from '@n8n/i18n/locales/en.json';
|
||||
import { createPinia, setActivePinia } from 'pinia';
|
||||
import { beforeEach } from 'vitest';
|
||||
|
||||
// Framework boot stays per-package on purpose: `@n8n/i18n` devDepends on
|
||||
// `@n8n/vitest-config`, so booting i18n from inside the shared harness would
|
||||
// close a turbo build cycle.
|
||||
//
|
||||
// `useI18n()` reads a module-level singleton, so this runs once at import and
|
||||
// needs no app instance — but `baseText` returns the key itself until the
|
||||
// messages are loaded, and this module's strings still live in the central
|
||||
// `en.json` (per-module locales are a later wave).
|
||||
loadLanguage('en', englishBaseText as unknown as LocaleMessages);
|
||||
|
||||
beforeEach(() => {
|
||||
setActivePinia(createPinia());
|
||||
});
|
||||
@@ -0,0 +1,4 @@
|
||||
// The module's only public entry. The shell imports the descriptor from here via
|
||||
// `modules.manifest.ts`; anything else the shell (or a test) needs must be exported
|
||||
// here too — deep paths into `src/` are not part of the contract.
|
||||
export { OtelModule } from './otel.module';
|
||||
+1
@@ -1,5 +1,6 @@
|
||||
import type { IRestApiContext } from '@n8n/rest-api-client';
|
||||
import { makeRestApiRequest } from '@n8n/rest-api-client';
|
||||
|
||||
import { getOtelSettings, updateOtelSettings, sendOtelTestTrace } from './otel.api';
|
||||
import type { OtelSettingsResponse, OtelTestConnection } from './otel.api';
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
import type { Scope } from '@n8n/permissions';
|
||||
import { useRBACStore } from '@n8n/stores/rbac.store';
|
||||
import { createPinia, setActivePinia } from 'pinia';
|
||||
|
||||
import { OTEL_SETTINGS_VIEW } from './otel.constants';
|
||||
import { OtelModule } from './otel.module';
|
||||
|
||||
/**
|
||||
* Guards the descriptor half of the shell-to-descriptor move of the otel settings
|
||||
* sidebar item.
|
||||
*
|
||||
* The old gate lived in the shell's `useSettingsItems.ts` as
|
||||
* `isModuleActive('otel') && hasPermission(['rbac'], { rbac: { scope: 'otel:manage' } })`.
|
||||
* It is now split: the descriptor's `available` getter owns the scope half, which is
|
||||
* what this file covers, and `ui.store`'s `settingsSidebarItems` owns the
|
||||
* module-active half, covered by `ui.store.settingsPages.test.ts` in the shell.
|
||||
*/
|
||||
describe('OtelModule', () => {
|
||||
const settingsPage = () =>
|
||||
OtelModule.settingsPages?.find((item) => item.id === 'settings-opentelemetry');
|
||||
|
||||
const withScopes = (scopes: Scope[]) => {
|
||||
useRBACStore().setGlobalScopes(scopes);
|
||||
return settingsPage();
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
setActivePinia(createPinia());
|
||||
});
|
||||
|
||||
describe('settings sidebar item', () => {
|
||||
it('should hide the item from a user without the otel:manage scope', () => {
|
||||
expect(withScopes([])?.available).toBe(false);
|
||||
});
|
||||
|
||||
it('should hide the item from a user holding only an unrelated scope', () => {
|
||||
expect(withScopes(['workflow:read'])?.available).toBe(false);
|
||||
});
|
||||
|
||||
it('should show the item to a user with the otel:manage scope', () => {
|
||||
expect(withScopes(['otel:manage'])?.available).toBe(true);
|
||||
});
|
||||
|
||||
it('should re-evaluate availability when scopes change after registration', () => {
|
||||
const item = withScopes([]);
|
||||
expect(item?.available).toBe(false);
|
||||
|
||||
useRBACStore().addGlobalScope('otel:manage');
|
||||
|
||||
expect(item?.available).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('route', () => {
|
||||
it('should keep routing to the unchanged SettingsOpenTelemetryView route name', () => {
|
||||
expect(OTEL_SETTINGS_VIEW).toBe('SettingsOpenTelemetryView');
|
||||
expect(settingsPage()?.route).toEqual({ to: { name: 'SettingsOpenTelemetryView' } });
|
||||
expect(OtelModule.routes?.[0]).toMatchObject({
|
||||
path: 'opentelemetry',
|
||||
name: 'SettingsOpenTelemetryView',
|
||||
});
|
||||
});
|
||||
|
||||
it('should keep the route rbac middleware, which gates direct URL access', () => {
|
||||
expect(OtelModule.routes?.[0].meta).toMatchObject({
|
||||
middleware: ['authenticated', 'rbac', 'custom'],
|
||||
middlewareOptions: { rbac: { scope: 'otel:manage' } },
|
||||
});
|
||||
});
|
||||
|
||||
it('should load the view lazily, so the shell does not pull it in at boot', () => {
|
||||
expect(typeof OtelModule.routes?.[0].component).toBe('function');
|
||||
});
|
||||
});
|
||||
});
|
||||
+4
-1
@@ -1,11 +1,14 @@
|
||||
import { useI18n } from '@n8n/i18n';
|
||||
import type { FrontendModuleDescription } from '@n8n/frontend-module-sdk';
|
||||
import { useI18n } from '@n8n/i18n';
|
||||
import { useRBACStore } from '@n8n/stores/rbac.store';
|
||||
|
||||
import { OTEL_SETTINGS_VIEW } from './otel.constants';
|
||||
|
||||
const i18n = useI18n();
|
||||
|
||||
// typescript-eslint reads an SFC import as `any`, because only vue-tsc can type one.
|
||||
// `pnpm turbo typecheck` is what checks this component for real.
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||
const SettingsOpenTelemetryView = async () => await import('./SettingsOpenTelemetryView.vue');
|
||||
|
||||
export const OtelModule: FrontendModuleDescription = {
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
import { createPinia, setActivePinia } from 'pinia';
|
||||
|
||||
import * as otelApi from './otel.api';
|
||||
import { useOtelStore, headersStringToPairs, headersPairsToString } from './otel.store';
|
||||
import type { OtelSettingsResponse } from './otel.api';
|
||||
import { useOtelStore, headersStringToPairs, headersPairsToString } from './otel.store';
|
||||
|
||||
vi.mock('./otel.api', () => ({
|
||||
getOtelSettings: vi.fn(),
|
||||
@@ -138,7 +138,7 @@ describe('useOtelStore', () => {
|
||||
|
||||
store.settings.exporterEndpoint = 'https://changed.io';
|
||||
|
||||
expect(store.savedSettings!.exporterEndpoint).toBe('https://original.io');
|
||||
expect(store.savedSettings.exporterEndpoint).toBe('https://original.io');
|
||||
});
|
||||
|
||||
it('sets loading to true during the call and resets it after', async () => {
|
||||
+2
-1
@@ -1,6 +1,7 @@
|
||||
import { useRootStore } from '@n8n/stores/useRootStore';
|
||||
import { defineStore } from 'pinia';
|
||||
import { ref, computed } from 'vue';
|
||||
import { useRootStore } from '@n8n/stores/useRootStore';
|
||||
|
||||
import { getOtelSettings, updateOtelSettings, sendOtelTestTrace } from './otel.api';
|
||||
import type { OtelSettings, OtelSettingsResponse } from './otel.api';
|
||||
import { OTEL_STORE } from './otel.constants';
|
||||
@@ -0,0 +1,9 @@
|
||||
import { baseConfig } from '@n8n/stylelint-config/base';
|
||||
|
||||
export default {
|
||||
...baseConfig,
|
||||
rules: {
|
||||
...baseConfig.rules,
|
||||
'@n8n/css-var-naming': [true, { severity: 'error' }],
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"extends": "@n8n/typescript-config/tsconfig.frontend-module.json",
|
||||
"compilerOptions": {
|
||||
// `rootDirs`, `types` and `include` cannot be inherited from the base: relative entries in
|
||||
// them resolve against this file, so a copy in the base would point at the base's directory.
|
||||
// (`paths` is the exception and does come from the base.)
|
||||
"rootDirs": [".", "../../../frontend/@n8n/design-system/src"],
|
||||
// The two `.d.ts` entries are ambient declarations this package never imports, so nothing
|
||||
// pulls them into the program: `~icons/*` and `markdown-it-task-lists` for design-system's
|
||||
// source, `window.BASE_PATH` for `@n8n/stores`'s. Consuming those packages from source is
|
||||
// what makes them the consumer's problem — a built `dist` would have carried them.
|
||||
"types": [
|
||||
"vite/client",
|
||||
"vitest/globals",
|
||||
"unplugin-icons/types/vue",
|
||||
"../../../frontend/@n8n/design-system/src/shims-modules.d.ts",
|
||||
"../../../frontend/@n8n/stores/src/shims.d.ts"
|
||||
]
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.vue", "vite.config.ts"]
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
import vue from '@vitejs/plugin-vue';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { resolve } from 'node:path';
|
||||
import icons from 'unplugin-icons/vite';
|
||||
import svgLoader from 'vite-svg-loader';
|
||||
import { defineConfig, mergeConfig } from 'vite';
|
||||
import { frontendAliases } from '@n8n/frontend-vite-config';
|
||||
import { vitestConfig } from '@n8n/vitest-config/frontend';
|
||||
|
||||
const packageDir = fileURLToPath(new URL('.', import.meta.url));
|
||||
const packagesDir = resolve(packageDir, '..', '..', '..');
|
||||
|
||||
export default mergeConfig(
|
||||
defineConfig({
|
||||
// `@n8n/design-system`'s icon set reaches for two things Vite does not handle on its
|
||||
// own: `~icons/lucide/*` virtual modules and `./custom/*.svg` single-file components.
|
||||
// Consuming design-system from source makes both the consumer's problem — without
|
||||
// `svgLoader` an `.svg` import returns a data-URI string, which Vue then renders as a
|
||||
// tag name and jsdom rejects. Every module that renders a design-system component
|
||||
// needs these two plugins.
|
||||
plugins: [
|
||||
vue(),
|
||||
// Off, so a test never reaches the network for a missing collection.
|
||||
icons({ compiler: 'vue3', autoInstall: false }),
|
||||
svgLoader({
|
||||
svgoConfig: {
|
||||
plugins: [
|
||||
{
|
||||
name: 'preset-default',
|
||||
params: {
|
||||
overrides: {
|
||||
// The icons rely on their ids, and on a viewBox to stay scalable.
|
||||
cleanupIds: false,
|
||||
removeViewBox: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
],
|
||||
resolve: {
|
||||
// The same platform mapping the editor-ui dev server uses, so a test resolves
|
||||
// `@n8n/stores/...` from source rather than from a stale `dist` — the two disagreeing is
|
||||
// what put 1,111 specifiers on the wrong side of the src/dist line. Sibling modules are
|
||||
// deliberately absent: nothing here should make a cross-module import resolve.
|
||||
alias: frontendAliases(packagesDir),
|
||||
},
|
||||
}),
|
||||
vitestConfig,
|
||||
);
|
||||
Generated
+252
-130
@@ -14,7 +14,7 @@ catalogs:
|
||||
version: 5.0.31
|
||||
'@ai-sdk/anthropic':
|
||||
specifier: ^4.0.32
|
||||
version: 4.0.32
|
||||
version: 4.0.39
|
||||
'@ai-sdk/azure':
|
||||
specifier: ^4.0.21
|
||||
version: 4.0.21
|
||||
@@ -29,7 +29,7 @@ catalogs:
|
||||
version: 4.0.60
|
||||
'@ai-sdk/google':
|
||||
specifier: ^4.0.24
|
||||
version: 4.0.24
|
||||
version: 4.0.39
|
||||
'@ai-sdk/google-vertex':
|
||||
specifier: ^5.0.47
|
||||
version: 5.0.48
|
||||
@@ -50,13 +50,13 @@ catalogs:
|
||||
version: 4.0.20
|
||||
'@ai-sdk/openai-compatible':
|
||||
specifier: ^3.0.14
|
||||
version: 3.0.14
|
||||
version: 3.0.28
|
||||
'@ai-sdk/otel':
|
||||
specifier: ^1.0.66
|
||||
version: 1.0.74
|
||||
'@ai-sdk/provider-utils':
|
||||
specifier: ^5.0.27
|
||||
version: 5.0.27
|
||||
version: 5.0.28
|
||||
'@ai-sdk/xai':
|
||||
specifier: ^4.0.18
|
||||
version: 4.0.18
|
||||
@@ -913,7 +913,7 @@ importers:
|
||||
version: 7.0.3
|
||||
eslint:
|
||||
specifier: 'catalog:'
|
||||
version: 9.29.0(jiti@2.6.1)(supports-color@8.1.1)
|
||||
version: 9.29.0(jiti@2.6.1)(supports-color@5.5.0)
|
||||
get-tsconfig:
|
||||
specifier: 'catalog:'
|
||||
version: 4.13.0
|
||||
@@ -940,7 +940,7 @@ importers:
|
||||
version: 5.0.1
|
||||
stylelint:
|
||||
specifier: 'catalog:'
|
||||
version: 16.23.0(supports-color@8.1.1)(typescript@6.0.2)
|
||||
version: 16.23.0(supports-color@5.5.0)(typescript@6.0.2)
|
||||
supertest:
|
||||
specifier: ^7.1.1
|
||||
version: 7.1.1(supports-color@8.1.1)
|
||||
@@ -973,7 +973,7 @@ importers:
|
||||
version: 5.0.31(zod@3.25.76)
|
||||
'@ai-sdk/anthropic':
|
||||
specifier: 'catalog:'
|
||||
version: 4.0.32(zod@3.25.76)
|
||||
version: 4.0.39(zod@3.25.76)
|
||||
'@ai-sdk/azure':
|
||||
specifier: 'catalog:'
|
||||
version: 4.0.21(zod@3.25.76)
|
||||
@@ -988,7 +988,7 @@ importers:
|
||||
version: 4.0.60(zod@3.25.76)
|
||||
'@ai-sdk/google':
|
||||
specifier: 'catalog:'
|
||||
version: 4.0.24(zod@3.25.76)
|
||||
version: 4.0.39(zod@3.25.76)
|
||||
'@ai-sdk/google-vertex':
|
||||
specifier: 'catalog:'
|
||||
version: 5.0.48(supports-color@8.1.1)(zod@3.25.76)
|
||||
@@ -1009,13 +1009,13 @@ importers:
|
||||
version: 4.0.20(zod@3.25.76)
|
||||
'@ai-sdk/openai-compatible':
|
||||
specifier: 'catalog:'
|
||||
version: 3.0.14(zod@3.25.76)
|
||||
version: 3.0.28(zod@3.25.76)
|
||||
'@ai-sdk/otel':
|
||||
specifier: 'catalog:'
|
||||
version: 1.0.74(zod@3.25.76)
|
||||
'@ai-sdk/provider-utils':
|
||||
specifier: 'catalog:'
|
||||
version: 5.0.27(zod@3.25.76)
|
||||
version: 5.0.28(zod@3.25.76)
|
||||
'@ai-sdk/xai':
|
||||
specifier: 'catalog:'
|
||||
version: 4.0.18(zod@3.25.76)
|
||||
@@ -1152,7 +1152,7 @@ importers:
|
||||
version: 1.0.27(@aws-sdk/credential-provider-node@3.972.80)(@langchain/core@1.2.8(@opentelemetry/api@1.9.1)(@opentelemetry/exporter-trace-otlp-proto@0.221.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.10.0(@opentelemetry/api@1.9.1))(openai@6.46.0(@aws-sdk/credential-provider-node@3.972.80)(@smithy/signature-v4@5.7.2)(ws@8.21.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))(ws@8.21.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@opentelemetry/api@1.9.1)(@opentelemetry/exporter-trace-otlp-proto@0.221.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.10.0(@opentelemetry/api@1.9.1))(@smithy/signature-v4@5.7.2)(cheerio@1.1.0)(openai@6.46.0(@aws-sdk/credential-provider-node@3.972.80)(@smithy/signature-v4@5.7.2)(ws@8.21.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))(ws@8.21.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))
|
||||
'@langchain/community':
|
||||
specifier: 'catalog:'
|
||||
version: 1.1.27(2af036a866615d639e1d6409476fa500)
|
||||
version: 1.1.27(6cc31e45a82b311205f2bf99fec67d91)
|
||||
'@langchain/core':
|
||||
specifier: 'catalog:'
|
||||
version: 1.2.8(@opentelemetry/api@1.9.1)(@opentelemetry/exporter-trace-otlp-proto@0.221.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.10.0(@opentelemetry/api@1.9.1))(openai@6.46.0(@aws-sdk/credential-provider-node@3.972.80)(@smithy/signature-v4@5.7.2)(ws@8.21.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))(ws@8.21.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))
|
||||
@@ -4142,10 +4142,10 @@ importers:
|
||||
version: 1.4.2(supports-color@8.1.1)
|
||||
'@ai-sdk/anthropic':
|
||||
specifier: 'catalog:'
|
||||
version: 4.0.32(zod@3.25.76)
|
||||
version: 4.0.39(zod@3.25.76)
|
||||
'@ai-sdk/openai-compatible':
|
||||
specifier: 'catalog:'
|
||||
version: 3.0.14(zod@3.25.76)
|
||||
version: 3.0.28(zod@3.25.76)
|
||||
'@apidevtools/json-schema-ref-parser':
|
||||
specifier: 12.0.2
|
||||
version: 12.0.2
|
||||
@@ -6010,6 +6010,9 @@ importers:
|
||||
'@n8n/frontend-module-instance-registry':
|
||||
specifier: workspace:*
|
||||
version: link:../../modules/instance-registry/frontend
|
||||
'@n8n/frontend-module-otel':
|
||||
specifier: workspace:*
|
||||
version: link:../../modules/otel/frontend
|
||||
'@n8n/frontend-module-sdk':
|
||||
specifier: workspace:*
|
||||
version: link:../@n8n/frontend-module-sdk
|
||||
@@ -6487,6 +6490,100 @@ importers:
|
||||
specifier: ^2.2.8
|
||||
version: 2.2.8(patch_hash=e2aee939ccac8a57fe449bfd92bedd8117841579526217bc39aca26c6b8c317f)(typescript@6.0.2)
|
||||
|
||||
packages/modules/otel/frontend:
|
||||
dependencies:
|
||||
'@n8n/composables':
|
||||
specifier: workspace:*
|
||||
version: link:../../../frontend/@n8n/composables
|
||||
'@n8n/design-system':
|
||||
specifier: workspace:*
|
||||
version: link:../../../frontend/@n8n/design-system
|
||||
'@n8n/frontend-module-sdk':
|
||||
specifier: workspace:*
|
||||
version: link:../../../frontend/@n8n/frontend-module-sdk
|
||||
'@n8n/i18n':
|
||||
specifier: workspace:*
|
||||
version: link:../../../frontend/@n8n/i18n
|
||||
'@n8n/rest-api-client':
|
||||
specifier: workspace:*
|
||||
version: link:../../../frontend/@n8n/rest-api-client
|
||||
'@n8n/stores':
|
||||
specifier: workspace:*
|
||||
version: link:../../../frontend/@n8n/stores
|
||||
pinia:
|
||||
specifier: catalog:frontend
|
||||
version: 2.2.4(typescript@6.0.2)(vue@3.5.26(typescript@6.0.2))
|
||||
vue:
|
||||
specifier: catalog:frontend
|
||||
version: 3.5.26(typescript@6.0.2)
|
||||
vue-router:
|
||||
specifier: catalog:frontend
|
||||
version: 4.5.0(vue@3.5.26(typescript@6.0.2))
|
||||
devDependencies:
|
||||
'@iconify/json':
|
||||
specifier: 'catalog:'
|
||||
version: 2.2.488
|
||||
'@n8n/eslint-config':
|
||||
specifier: workspace:*
|
||||
version: link:../../../@n8n/eslint-config
|
||||
'@n8n/frontend-vite-config':
|
||||
specifier: workspace:*
|
||||
version: link:../../../frontend/@n8n/frontend-vite-config
|
||||
'@n8n/permissions':
|
||||
specifier: workspace:*
|
||||
version: link:../../../@n8n/permissions
|
||||
'@n8n/playwright-janitor':
|
||||
specifier: workspace:*
|
||||
version: link:../../../testing/janitor
|
||||
'@n8n/stylelint-config':
|
||||
specifier: workspace:*
|
||||
version: link:../../../@n8n/stylelint-config
|
||||
'@n8n/typescript-config':
|
||||
specifier: workspace:*
|
||||
version: link:../../../@n8n/typescript-config
|
||||
'@n8n/vitest-config':
|
||||
specifier: workspace:*
|
||||
version: link:../../../@n8n/vitest-config
|
||||
'@pinia/testing':
|
||||
specifier: ^0.1.6
|
||||
version: 0.1.6(pinia@2.2.4(typescript@6.0.2)(vue@3.5.26(typescript@6.0.2)))(vue@3.5.26(typescript@6.0.2))
|
||||
'@testing-library/jest-dom':
|
||||
specifier: catalog:frontend
|
||||
version: 6.6.3
|
||||
'@testing-library/user-event':
|
||||
specifier: catalog:frontend
|
||||
version: 14.6.1(@testing-library/dom@10.4.0)
|
||||
'@testing-library/vue':
|
||||
specifier: catalog:frontend
|
||||
version: 8.1.0(@vue/compiler-sfc@3.5.26)(vue@3.5.26(typescript@6.0.2))
|
||||
'@vitejs/plugin-vue':
|
||||
specifier: catalog:frontend
|
||||
version: 6.0.8(vite@8.0.2(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3))(vue@3.5.26(typescript@6.0.2))
|
||||
eslint:
|
||||
specifier: 'catalog:'
|
||||
version: 9.29.0(jiti@2.6.1)(supports-color@8.1.1)
|
||||
stylelint:
|
||||
specifier: 'catalog:'
|
||||
version: 16.23.0(supports-color@8.1.1)(typescript@6.0.2)
|
||||
typescript:
|
||||
specifier: 'catalog:'
|
||||
version: 6.0.2
|
||||
unplugin-icons:
|
||||
specifier: catalog:frontend
|
||||
version: 23.0.1(@vue/compiler-sfc@3.5.26)
|
||||
vite:
|
||||
specifier: 'catalog:'
|
||||
version: 8.0.2(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3)
|
||||
vite-svg-loader:
|
||||
specifier: catalog:frontend
|
||||
version: 5.1.0(vue@3.5.26(typescript@6.0.2))
|
||||
vitest:
|
||||
specifier: 'catalog:'
|
||||
version: 4.1.9(@opentelemetry/api@1.9.1)(@types/node@20.19.41)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(jsdom@23.0.1(bufferutil@4.0.9)(supports-color@8.1.1)(utf-8-validate@5.0.10))(vite@8.0.2(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3))
|
||||
vue-tsc:
|
||||
specifier: ^2.2.8
|
||||
version: 2.2.8(patch_hash=e2aee939ccac8a57fe449bfd92bedd8117841579526217bc39aca26c6b8c317f)(typescript@6.0.2)
|
||||
|
||||
packages/node-dev:
|
||||
dependencies:
|
||||
'@n8n/di':
|
||||
@@ -7435,12 +7532,6 @@ packages:
|
||||
peerDependencies:
|
||||
zod: 3.25.76
|
||||
|
||||
'@ai-sdk/anthropic@4.0.32':
|
||||
resolution: {integrity: sha512-uEUIL71aGteKFQewN0Tkx6o5dxc7pSA+vcW23oOQOxvmUT1BPNo+S7V+kC/gn0B/2awwVTg/1lz+aMHJBY1gtQ==}
|
||||
engines: {node: '>=22'}
|
||||
peerDependencies:
|
||||
zod: 3.25.76
|
||||
|
||||
'@ai-sdk/anthropic@4.0.36':
|
||||
resolution: {integrity: sha512-Wg5jfray0X4+qkrr73GZ7U7K2JNGx+S+rNY9LorVlXhkhTqnvtNLYWRA1WxSxlCDCw3yjRCJdL9kyc+b7naAog==}
|
||||
engines: {node: '>=22'}
|
||||
@@ -7483,12 +7574,6 @@ packages:
|
||||
peerDependencies:
|
||||
zod: 3.25.76
|
||||
|
||||
'@ai-sdk/google@4.0.24':
|
||||
resolution: {integrity: sha512-W+kTGb/RRe2SEYwbKcKYM3N2EQryS2Iqjgou6wPsyP/2BwBU7Q23CF6/YWE8k7xtseDLcSY59jsR2MDpY4azRg==}
|
||||
engines: {node: '>=22'}
|
||||
peerDependencies:
|
||||
zod: 3.25.76
|
||||
|
||||
'@ai-sdk/google@4.0.39':
|
||||
resolution: {integrity: sha512-+mRx7UBZn9PkJ4J6YXowaRZKMZYa290cknVqqOw/roZaDg186IUOLn9JHNQkvgaj91/MLW1AZNESy1ZD2yXDCg==}
|
||||
engines: {node: '>=22'}
|
||||
@@ -7547,12 +7632,6 @@ packages:
|
||||
peerDependencies:
|
||||
zod: 3.25.76
|
||||
|
||||
'@ai-sdk/provider-utils@5.0.22':
|
||||
resolution: {integrity: sha512-1wEGi9RDCYdNtkSNybUR2BG2UC1tJ3M9do8DNMdc1EtNcHBEgvD8rz6CTfsMIzVGQRFhTv2/m2yKPpxhvbX1zA==}
|
||||
engines: {node: '>=22'}
|
||||
peerDependencies:
|
||||
zod: 3.25.76
|
||||
|
||||
'@ai-sdk/provider-utils@5.0.25':
|
||||
resolution: {integrity: sha512-xscPPHCSjCHWrdhai25sbHCJeKNLW/3D1uSpUZa4cEtTKXA8OnPQ3+Rfu1SmM5Ea/Mf8Dfn3cllw9zeMzo/zFA==}
|
||||
engines: {node: '>=22'}
|
||||
@@ -7575,10 +7654,6 @@ packages:
|
||||
resolution: {integrity: sha512-e0CpNWJUY7OxAFAnCZkw+ri9QOHWwTs1tXP42782KFGCU07qt8NiXCrCVowyCB5dP2r5/Uls+g2oPd8kOJn9dw==}
|
||||
engines: {node: '>=22'}
|
||||
|
||||
'@ai-sdk/provider@4.0.5':
|
||||
resolution: {integrity: sha512-9WAerTaPU2jcVi8dh8x27tySEuLur1Kfg7Go74GuCmsC/2MDSvrTkrK8ZrXWjryEevKfcPPmO1enveE7eqlzoA==}
|
||||
engines: {node: '>=22'}
|
||||
|
||||
'@ai-sdk/provider@4.0.7':
|
||||
resolution: {integrity: sha512-6or44XprPzKbr8zkmzosowSE0pxkvJcoojBL+mCZvPUt3kvXp3XSNqeVun9golb1acEfSo6yaEBRT18h2VU+1Q==}
|
||||
engines: {node: '>=22'}
|
||||
@@ -8306,10 +8381,6 @@ packages:
|
||||
resolution: {integrity: sha512-xmCA9kP3IhySsqhzwIdWGlDN/1A4cCKNBO/uwZx/3YzmDoMePwno2Q5/Bq0q+tYaKbeF940YiKV/kaW8Mzvpjw==}
|
||||
engines: {node: ^22.18.0 || >=24.11.0}
|
||||
|
||||
'@babel/helper-string-parser@7.27.1':
|
||||
resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-string-parser@7.29.7':
|
||||
resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
@@ -8346,11 +8417,6 @@ packages:
|
||||
resolution: {integrity: sha512-wfbi91pM3py96oIiJEz7qIpyXDytgr9zQC1HEWwlGNVRAEmItuU/0a41ZUKu1sJGyhhOIpc4t5vk4PYzt8wpsg==}
|
||||
engines: {node: ^22.18.0 || >=24.11.0}
|
||||
|
||||
'@babel/parser@7.29.2':
|
||||
resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
hasBin: true
|
||||
|
||||
'@babel/parser@7.29.8':
|
||||
resolution: {integrity: sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
@@ -8836,10 +8902,6 @@ packages:
|
||||
resolution: {integrity: sha512-bZnmqzGG8UZneG1lLxBoWIH0G6Gr1D846Yu4/3XnY6FhCndMR49u26nTY08u/dAxWmLWF9vGQOuC+84FfIUoeg==}
|
||||
engines: {node: ^22.18.0 || >=24.11.0}
|
||||
|
||||
'@babel/types@7.29.0':
|
||||
resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/types@7.29.8':
|
||||
resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
@@ -12555,10 +12617,6 @@ packages:
|
||||
resolution: {integrity: sha512-o9VycsYNtgC+Dy3I0yrwCqv9CWicDnke0L7EVOrZtJpjb2t0EjaEofmMrYc0T1Kn3yk32zm6cspxF9u9Bj7e5w==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
|
||||
'@smithy/core@3.30.0':
|
||||
resolution: {integrity: sha512-dl2yRglDxfzH9uJ4fSo4zTaAHa0zH7+V7BZMRWy8hEYIKT1BiqMUK/CN6T3ADQ3kbA5N1tmUulroJ2UtONS7Kw==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
|
||||
'@smithy/core@3.33.2':
|
||||
resolution: {integrity: sha512-CUGXpnPkVdjUCbix+83sWLW9VFgQOm44MDOx/ihITJMAnOZKvL8YYIc7DR9pP/tZ8CIRvMiON/TucvygqbHO3w==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
@@ -12718,10 +12776,6 @@ packages:
|
||||
resolution: {integrity: sha512-787F3yzE2UiJIQ+wYW1CVg2odHjmaWLGksnKQHUrK/lYZSEcy1msuLVvxaR/sI2/aDe9U+TBuLsXnr3vod1g0g==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
|
||||
'@smithy/types@4.16.1':
|
||||
resolution: {integrity: sha512-0JFs3V2y2M9tKW5na/qxe69Zv+uxLMO7QBbhxF/FHu/Gp2NFZAAL9tWl9PU02xxo07pb3G9FTyjNc6D5uZrJIg==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
|
||||
'@smithy/types@4.17.2':
|
||||
resolution: {integrity: sha512-FOKpVZob9MPTn2znRzGrnsMHv7BOsKVw3XiP/cOyYLDVZ9qKp4nifIiSCuUU/fIj5Vu0UOAxCFr+qRAtG0NUkA==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
@@ -24145,12 +24199,6 @@ snapshots:
|
||||
'@ai-sdk/provider-utils': 5.0.12(zod@3.25.76)
|
||||
zod: 3.25.76
|
||||
|
||||
'@ai-sdk/anthropic@4.0.32(zod@3.25.76)':
|
||||
dependencies:
|
||||
'@ai-sdk/provider': 4.0.5
|
||||
'@ai-sdk/provider-utils': 5.0.22(zod@3.25.76)
|
||||
zod: 3.25.76
|
||||
|
||||
'@ai-sdk/anthropic@4.0.36(zod@3.25.76)':
|
||||
dependencies:
|
||||
'@ai-sdk/provider': 4.0.7
|
||||
@@ -24202,12 +24250,6 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@ai-sdk/google@4.0.24(zod@3.25.76)':
|
||||
dependencies:
|
||||
'@ai-sdk/provider': 4.0.3
|
||||
'@ai-sdk/provider-utils': 5.0.12(zod@3.25.76)
|
||||
zod: 3.25.76
|
||||
|
||||
'@ai-sdk/google@4.0.39(zod@3.25.76)':
|
||||
dependencies:
|
||||
'@ai-sdk/provider': 4.0.7
|
||||
@@ -24273,15 +24315,6 @@ snapshots:
|
||||
eventsource-parser: 3.0.8
|
||||
zod: 3.25.76
|
||||
|
||||
'@ai-sdk/provider-utils@5.0.22(zod@3.25.76)':
|
||||
dependencies:
|
||||
'@ai-sdk/provider': 4.0.5
|
||||
'@standard-schema/spec': 1.1.0
|
||||
'@workflow/serde': 4.1.0
|
||||
eventsource-parser: 3.0.8
|
||||
undici: 7.29.0
|
||||
zod: 3.25.76
|
||||
|
||||
'@ai-sdk/provider-utils@5.0.25(zod@3.25.76)':
|
||||
dependencies:
|
||||
'@ai-sdk/provider': 4.0.7
|
||||
@@ -24313,10 +24346,6 @@ snapshots:
|
||||
dependencies:
|
||||
json-schema: 0.4.0
|
||||
|
||||
'@ai-sdk/provider@4.0.5':
|
||||
dependencies:
|
||||
json-schema: 0.4.0
|
||||
|
||||
'@ai-sdk/provider@4.0.7':
|
||||
dependencies:
|
||||
json-schema: 0.4.0
|
||||
@@ -24937,7 +24966,7 @@ snapshots:
|
||||
'@aws-sdk/util-user-agent-browser': 3.936.0
|
||||
'@aws-sdk/util-user-agent-node': 3.936.0
|
||||
'@smithy/config-resolver': 4.4.3
|
||||
'@smithy/core': 3.30.0
|
||||
'@smithy/core': 3.33.2
|
||||
'@smithy/fetch-http-handler': 5.3.15
|
||||
'@smithy/hash-node': 4.2.5
|
||||
'@smithy/invalid-dependency': 4.2.5
|
||||
@@ -25381,7 +25410,7 @@ snapshots:
|
||||
'@smithy/types': 4.13.1
|
||||
'@smithy/util-middleware': 4.2.12
|
||||
'@smithy/util-stream': 4.5.20
|
||||
'@smithy/util-utf8': 4.2.2
|
||||
'@smithy/util-utf8': 4.4.14
|
||||
tslib: 2.8.1
|
||||
|
||||
'@aws-sdk/middleware-host-header@3.804.0':
|
||||
@@ -25445,7 +25474,7 @@ snapshots:
|
||||
'@smithy/util-config-provider': 4.2.0
|
||||
'@smithy/util-middleware': 4.2.12
|
||||
'@smithy/util-stream': 4.5.20
|
||||
'@smithy/util-utf8': 4.2.2
|
||||
'@smithy/util-utf8': 4.4.14
|
||||
tslib: 2.8.1
|
||||
|
||||
'@aws-sdk/middleware-sdk-s3@3.972.74':
|
||||
@@ -26090,7 +26119,7 @@ snapshots:
|
||||
|
||||
'@babel/helper-annotate-as-pure@7.27.3':
|
||||
dependencies:
|
||||
'@babel/types': 7.29.0
|
||||
'@babel/types': 7.29.8
|
||||
|
||||
'@babel/helper-annotate-as-pure@8.0.0':
|
||||
dependencies:
|
||||
@@ -26323,14 +26352,14 @@ snapshots:
|
||||
'@babel/helper-skip-transparent-expression-wrappers@7.27.1(supports-color@5.5.0)':
|
||||
dependencies:
|
||||
'@babel/traverse': 7.29.0(supports-color@5.5.0)
|
||||
'@babel/types': 7.29.0
|
||||
'@babel/types': 7.29.8
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/helper-skip-transparent-expression-wrappers@7.27.1(supports-color@8.1.1)':
|
||||
dependencies:
|
||||
'@babel/traverse': 7.29.0(supports-color@8.1.1)
|
||||
'@babel/types': 7.29.0
|
||||
'@babel/types': 7.29.8
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -26339,8 +26368,6 @@ snapshots:
|
||||
'@babel/traverse': 8.0.4
|
||||
'@babel/types': 8.0.4
|
||||
|
||||
'@babel/helper-string-parser@7.27.1': {}
|
||||
|
||||
'@babel/helper-string-parser@7.29.7': {}
|
||||
|
||||
'@babel/helper-string-parser@8.0.0': {}
|
||||
@@ -26379,10 +26406,6 @@ snapshots:
|
||||
'@babel/template': 8.0.0
|
||||
'@babel/types': 8.0.4
|
||||
|
||||
'@babel/parser@7.29.2':
|
||||
dependencies:
|
||||
'@babel/types': 7.29.0
|
||||
|
||||
'@babel/parser@7.29.8':
|
||||
dependencies:
|
||||
'@babel/types': 7.29.8
|
||||
@@ -27396,14 +27419,14 @@ snapshots:
|
||||
dependencies:
|
||||
'@babel/core': 7.29.0(supports-color@5.5.0)
|
||||
'@babel/helper-plugin-utils': 7.28.6
|
||||
'@babel/types': 7.29.0
|
||||
'@babel/types': 7.29.8
|
||||
esutils: 2.0.3
|
||||
|
||||
'@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.29.0(supports-color@8.1.1))':
|
||||
dependencies:
|
||||
'@babel/core': 7.29.0(supports-color@8.1.1)
|
||||
'@babel/helper-plugin-utils': 7.28.6
|
||||
'@babel/types': 7.29.0
|
||||
'@babel/types': 7.29.8
|
||||
esutils: 2.0.3
|
||||
|
||||
'@babel/preset-react@8.0.1(@babel/core@8.0.1)':
|
||||
@@ -27472,11 +27495,6 @@ snapshots:
|
||||
'@babel/types': 8.0.4
|
||||
obug: 2.1.3
|
||||
|
||||
'@babel/types@7.29.0':
|
||||
dependencies:
|
||||
'@babel/helper-string-parser': 7.27.1
|
||||
'@babel/helper-validator-identifier': 7.29.7
|
||||
|
||||
'@babel/types@7.29.8':
|
||||
dependencies:
|
||||
'@babel/helper-string-parser': 7.29.7
|
||||
@@ -28291,6 +28309,11 @@ snapshots:
|
||||
eslint: 8.57.1(supports-color@8.1.1)
|
||||
eslint-visitor-keys: 3.4.3
|
||||
|
||||
'@eslint-community/eslint-utils@4.7.0(eslint@9.29.0(jiti@2.6.1)(supports-color@5.5.0))':
|
||||
dependencies:
|
||||
eslint: 9.29.0(jiti@2.6.1)(supports-color@5.5.0)
|
||||
eslint-visitor-keys: 3.4.3
|
||||
|
||||
'@eslint-community/eslint-utils@4.7.0(eslint@9.29.0(jiti@2.6.1)(supports-color@8.1.1))':
|
||||
dependencies:
|
||||
eslint: 9.29.0(jiti@2.6.1)(supports-color@8.1.1)
|
||||
@@ -28298,6 +28321,14 @@ snapshots:
|
||||
|
||||
'@eslint-community/regexpp@4.12.1': {}
|
||||
|
||||
'@eslint/config-array@0.20.1(supports-color@5.5.0)':
|
||||
dependencies:
|
||||
'@eslint/object-schema': 2.1.6
|
||||
debug: 4.4.3(supports-color@5.5.0)
|
||||
minimatch: 5.1.8
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@eslint/config-array@0.20.1(supports-color@8.1.1)':
|
||||
dependencies:
|
||||
'@eslint/object-schema': 2.1.6
|
||||
@@ -28334,6 +28365,20 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@eslint/eslintrc@3.3.1(supports-color@5.5.0)':
|
||||
dependencies:
|
||||
ajv: 6.15.0
|
||||
debug: 4.4.3(supports-color@5.5.0)
|
||||
espree: 10.4.0
|
||||
globals: 14.0.0
|
||||
ignore: 5.3.2
|
||||
import-fresh: 3.3.0
|
||||
js-yaml: 4.3.1
|
||||
minimatch: 5.1.8
|
||||
strip-json-comments: 3.1.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@eslint/eslintrc@3.3.1(supports-color@8.1.1)':
|
||||
dependencies:
|
||||
ajv: 6.15.0
|
||||
@@ -28640,7 +28685,7 @@ snapshots:
|
||||
'@inquirer/external-editor@2.0.4(@types/node@20.19.41)':
|
||||
dependencies:
|
||||
chardet: 2.1.1
|
||||
iconv-lite: 0.7.2
|
||||
iconv-lite: 0.7.3
|
||||
optionalDependencies:
|
||||
'@types/node': 20.19.41
|
||||
|
||||
@@ -28884,7 +28929,7 @@ snapshots:
|
||||
- aws-crt
|
||||
- encoding
|
||||
|
||||
'@langchain/community@1.1.27(2af036a866615d639e1d6409476fa500)':
|
||||
'@langchain/community@1.1.27(6cc31e45a82b311205f2bf99fec67d91)':
|
||||
dependencies:
|
||||
'@browserbasehq/stagehand': empty-npm-package@1.0.0
|
||||
'@ibm-cloud/watsonx-ai': 1.1.2(supports-color@8.1.1)
|
||||
@@ -29462,7 +29507,7 @@ snapshots:
|
||||
'@memlab/e2e@2.0.1(bufferutil@4.0.9)(supports-color@8.1.1)(typescript@7.0.2)(utf-8-validate@5.0.10)':
|
||||
dependencies:
|
||||
'@babel/generator': 7.29.1
|
||||
'@babel/parser': 7.29.2
|
||||
'@babel/parser': 7.29.8
|
||||
'@babel/template': 7.28.6
|
||||
'@babel/traverse': 7.29.0(supports-color@8.1.1)
|
||||
'@memlab/core': 2.0.1(bufferutil@4.0.9)(supports-color@8.1.1)(typescript@7.0.2)(utf-8-validate@5.0.10)
|
||||
@@ -31558,15 +31603,10 @@ snapshots:
|
||||
'@smithy/util-body-length-browser': 4.2.2
|
||||
'@smithy/util-middleware': 4.2.12
|
||||
'@smithy/util-stream': 4.5.20
|
||||
'@smithy/util-utf8': 4.2.2
|
||||
'@smithy/util-utf8': 4.4.14
|
||||
'@smithy/uuid': 1.1.2
|
||||
tslib: 2.8.1
|
||||
|
||||
'@smithy/core@3.30.0':
|
||||
dependencies:
|
||||
'@smithy/types': 4.16.1
|
||||
tslib: 2.8.1
|
||||
|
||||
'@smithy/core@3.33.2':
|
||||
dependencies:
|
||||
'@smithy/types': 4.17.2
|
||||
@@ -31646,13 +31686,13 @@ snapshots:
|
||||
dependencies:
|
||||
'@smithy/types': 4.13.1
|
||||
'@smithy/util-buffer-from': 4.2.2
|
||||
'@smithy/util-utf8': 4.2.2
|
||||
'@smithy/util-utf8': 4.4.14
|
||||
tslib: 2.8.1
|
||||
|
||||
'@smithy/hash-stream-node@4.0.2':
|
||||
dependencies:
|
||||
'@smithy/types': 4.13.1
|
||||
'@smithy/util-utf8': 4.2.2
|
||||
'@smithy/util-utf8': 4.4.14
|
||||
tslib: 2.8.1
|
||||
|
||||
'@smithy/invalid-dependency@4.2.5':
|
||||
@@ -31675,7 +31715,7 @@ snapshots:
|
||||
'@smithy/md5-js@4.0.2':
|
||||
dependencies:
|
||||
'@smithy/types': 4.13.1
|
||||
'@smithy/util-utf8': 4.2.2
|
||||
'@smithy/util-utf8': 4.4.14
|
||||
tslib: 2.8.1
|
||||
|
||||
'@smithy/middleware-content-length@4.2.5':
|
||||
@@ -31823,10 +31863,6 @@ snapshots:
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
|
||||
'@smithy/types@4.16.1':
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
|
||||
'@smithy/types@4.17.2':
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
@@ -31840,7 +31876,7 @@ snapshots:
|
||||
'@smithy/util-base64@4.3.2':
|
||||
dependencies:
|
||||
'@smithy/util-buffer-from': 4.2.2
|
||||
'@smithy/util-utf8': 4.2.2
|
||||
'@smithy/util-utf8': 4.4.14
|
||||
tslib: 2.8.1
|
||||
|
||||
'@smithy/util-body-length-browser@4.2.2':
|
||||
@@ -31924,7 +31960,7 @@ snapshots:
|
||||
'@smithy/util-base64': 4.3.2
|
||||
'@smithy/util-buffer-from': 4.2.2
|
||||
'@smithy/util-hex-encoding': 4.2.2
|
||||
'@smithy/util-utf8': 4.2.2
|
||||
'@smithy/util-utf8': 4.4.14
|
||||
tslib: 2.8.1
|
||||
|
||||
'@smithy/util-uri-escape@1.1.0':
|
||||
@@ -33929,7 +33965,7 @@ snapshots:
|
||||
'@vue/language-core@2.1.10(typescript@5.9.3)':
|
||||
dependencies:
|
||||
'@volar/language-core': 2.4.12
|
||||
'@vue/compiler-dom': 3.5.26
|
||||
'@vue/compiler-dom': 3.5.40
|
||||
'@vue/compiler-vue2': 2.7.16
|
||||
'@vue/shared': 3.5.40
|
||||
alien-signals: 0.2.2
|
||||
@@ -33942,7 +33978,7 @@ snapshots:
|
||||
'@vue/language-core@2.2.0(typescript@6.0.2)':
|
||||
dependencies:
|
||||
'@volar/language-core': 2.4.12
|
||||
'@vue/compiler-dom': 3.5.26
|
||||
'@vue/compiler-dom': 3.5.40
|
||||
'@vue/compiler-vue2': 2.7.16
|
||||
'@vue/shared': 3.5.40
|
||||
alien-signals: 0.4.14
|
||||
@@ -34631,7 +34667,7 @@ snapshots:
|
||||
|
||||
ast-kit@2.2.0:
|
||||
dependencies:
|
||||
'@babel/parser': 7.29.2
|
||||
'@babel/parser': 7.29.8
|
||||
pathe: 2.0.3
|
||||
|
||||
ast-module-types@6.0.1: {}
|
||||
@@ -34907,7 +34943,7 @@ snapshots:
|
||||
content-type: 2.0.0
|
||||
debug: 4.4.3(supports-color@8.1.1)
|
||||
http-errors: 2.0.1
|
||||
iconv-lite: 0.7.2
|
||||
iconv-lite: 0.7.3
|
||||
on-finished: 2.4.1
|
||||
qs: 6.15.2
|
||||
raw-body: 3.0.2
|
||||
@@ -37144,6 +37180,48 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
eslint@9.29.0(jiti@2.6.1)(supports-color@5.5.0):
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@2.6.1)(supports-color@5.5.0))
|
||||
'@eslint-community/regexpp': 4.12.1
|
||||
'@eslint/config-array': 0.20.1(supports-color@5.5.0)
|
||||
'@eslint/config-helpers': 0.2.3
|
||||
'@eslint/core': 0.14.0
|
||||
'@eslint/eslintrc': 3.3.1(supports-color@5.5.0)
|
||||
'@eslint/js': 9.29.0
|
||||
'@eslint/plugin-kit': 0.3.2
|
||||
'@humanfs/node': 0.16.6
|
||||
'@humanwhocodes/module-importer': 1.0.1
|
||||
'@humanwhocodes/retry': 0.4.3
|
||||
'@types/estree': 1.0.8
|
||||
'@types/json-schema': 7.0.15
|
||||
ajv: 6.15.0
|
||||
chalk: 4.1.2
|
||||
cross-spawn: 7.0.6
|
||||
debug: 4.4.3(supports-color@5.5.0)
|
||||
escape-string-regexp: 4.0.0
|
||||
eslint-scope: 8.4.0
|
||||
eslint-visitor-keys: 4.2.1
|
||||
espree: 10.4.0
|
||||
esquery: 1.7.0
|
||||
esutils: 2.0.3
|
||||
fast-deep-equal: 3.1.3
|
||||
file-entry-cache: 8.0.0
|
||||
find-up: 5.0.0
|
||||
glob-parent: 6.0.2
|
||||
ignore: 5.3.2
|
||||
imurmurhash: 0.1.4
|
||||
is-glob: 4.0.3
|
||||
json-stable-stringify-without-jsonify: 1.0.1
|
||||
lodash.merge: 4.6.2
|
||||
minimatch: 5.1.8
|
||||
natural-compare: 1.4.0
|
||||
optionator: 0.9.3
|
||||
optionalDependencies:
|
||||
jiti: 2.6.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
eslint@9.29.0(jiti@2.6.1)(supports-color@8.1.1):
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@2.6.1)(supports-color@8.1.1))
|
||||
@@ -42228,7 +42306,7 @@ snapshots:
|
||||
dependencies:
|
||||
bytes: 3.1.2
|
||||
http-errors: 2.0.1
|
||||
iconv-lite: 0.7.2
|
||||
iconv-lite: 0.7.3
|
||||
unpipe: 1.0.0
|
||||
|
||||
rc@1.2.8:
|
||||
@@ -42642,8 +42720,8 @@ snapshots:
|
||||
rolldown-plugin-dts@0.17.8(@typescript/typescript6@6.0.2)(rolldown@1.0.0-beta.50(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1))(vue-tsc@2.2.8(patch_hash=e2aee939ccac8a57fe449bfd92bedd8117841579526217bc39aca26c6b8c317f)(@typescript/typescript6@6.0.2)):
|
||||
dependencies:
|
||||
'@babel/generator': 7.29.1
|
||||
'@babel/parser': 7.29.2
|
||||
'@babel/types': 7.29.0
|
||||
'@babel/parser': 7.29.8
|
||||
'@babel/types': 7.29.8
|
||||
ast-kit: 2.2.0
|
||||
birpc: 2.8.0
|
||||
dts-resolver: 2.1.3
|
||||
@@ -42660,8 +42738,8 @@ snapshots:
|
||||
rolldown-plugin-dts@0.17.8(rolldown@1.0.0-beta.50(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1))(typescript@6.0.2)(vue-tsc@2.2.8(patch_hash=e2aee939ccac8a57fe449bfd92bedd8117841579526217bc39aca26c6b8c317f)(typescript@6.0.2)):
|
||||
dependencies:
|
||||
'@babel/generator': 7.29.1
|
||||
'@babel/parser': 7.29.2
|
||||
'@babel/types': 7.29.0
|
||||
'@babel/parser': 7.29.8
|
||||
'@babel/types': 7.29.8
|
||||
ast-kit: 2.2.0
|
||||
birpc: 2.8.0
|
||||
dts-resolver: 2.1.3
|
||||
@@ -43744,6 +43822,50 @@ snapshots:
|
||||
postcss-value-parser: 4.2.0
|
||||
stylelint: 16.23.0(supports-color@8.1.1)(typescript@7.0.2)
|
||||
|
||||
stylelint@16.23.0(supports-color@5.5.0)(typescript@6.0.2):
|
||||
dependencies:
|
||||
'@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4)
|
||||
'@csstools/css-tokenizer': 3.0.4
|
||||
'@csstools/media-query-list-parser': 4.0.3(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)
|
||||
'@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.0)
|
||||
'@dual-bundle/import-meta-resolve': 4.1.0
|
||||
balanced-match: 2.0.0
|
||||
colord: 2.9.3
|
||||
cosmiconfig: 9.0.0(typescript@6.0.2)
|
||||
css-functions-list: 3.2.3
|
||||
css-tree: 3.1.0
|
||||
debug: 4.4.3(supports-color@5.5.0)
|
||||
fast-glob: 3.3.3
|
||||
fastest-levenshtein: 1.0.16
|
||||
file-entry-cache: 10.1.3
|
||||
global-modules: 2.0.0
|
||||
globby: 11.1.0
|
||||
globjoin: 0.1.4
|
||||
html-tags: 3.3.1
|
||||
ignore: 7.0.5
|
||||
imurmurhash: 0.1.4
|
||||
is-plain-object: 5.0.0
|
||||
known-css-properties: 0.37.0
|
||||
mathml-tag-names: 2.1.3
|
||||
meow: 13.2.0
|
||||
micromatch: 4.0.8
|
||||
normalize-path: 3.0.0
|
||||
picocolors: 1.1.1
|
||||
postcss: 8.5.23
|
||||
postcss-resolve-nested-selector: 0.1.6
|
||||
postcss-safe-parser: 7.0.1(postcss@8.5.23)
|
||||
postcss-selector-parser: 7.1.0
|
||||
postcss-value-parser: 4.2.0
|
||||
resolve-from: 5.0.0
|
||||
string-width: 4.2.3
|
||||
supports-hyperlinks: 3.2.0
|
||||
svg-tags: 1.0.0
|
||||
table: 6.9.0
|
||||
write-file-atomic: 5.0.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
stylelint@16.23.0(supports-color@8.1.1)(typescript@6.0.2):
|
||||
dependencies:
|
||||
'@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4)
|
||||
@@ -45117,9 +45239,9 @@ snapshots:
|
||||
|
||||
vue-docgen-api@4.76.0(vue@3.5.26(typescript@6.0.2)):
|
||||
dependencies:
|
||||
'@babel/parser': 7.29.2
|
||||
'@babel/types': 7.29.0
|
||||
'@vue/compiler-dom': 3.5.26
|
||||
'@babel/parser': 7.29.8
|
||||
'@babel/types': 7.29.8
|
||||
'@vue/compiler-dom': 3.5.40
|
||||
'@vue/compiler-sfc': 3.5.26
|
||||
ast-types: 0.16.1
|
||||
esm-resolve: 1.0.8
|
||||
|
||||
Reference in New Issue
Block a user