diff --git a/packages/testing/playwright/composables/TestEntryComposer.ts b/packages/testing/playwright/composables/TestEntryComposer.ts new file mode 100644 index 0000000000..ad8dab2da5 --- /dev/null +++ b/packages/testing/playwright/composables/TestEntryComposer.ts @@ -0,0 +1,54 @@ +import type { n8nPage } from '../pages/n8nPage'; + +/** + * Composer for UI test entry points. All methods in this class navigate to or verify UI state. + * For API-only testing, use the standalone `api` fixture directly instead. + */ +export class TestEntryComposer { + constructor(private readonly n8n: n8nPage) {} + + /** + * Start UI test from the home page and navigate to canvas + */ + async fromHome() { + await this.n8n.goHome(); + await this.n8n.page.waitForURL('/home/workflows'); + } + + /** + * Start UI test from a blank canvas (assumes already on canvas) + */ + async fromBlankCanvas() { + await this.n8n.goHome(); + await this.n8n.workflows.clickAddWorkflowButton(); + // Verify we're on canvas + await this.n8n.canvas.canvasPane().isVisible(); + } + + /** + * Start UI test from a workflow in a new project + */ + async fromNewProject() { + // Enable features to allow us to create a new project + await this.n8n.api.enableFeature('projectRole:admin'); + await this.n8n.api.enableFeature('projectRole:editor'); + await this.n8n.api.setMaxTeamProjectsQuota(-1); + + // Create a project using the API + const response = await this.n8n.api.projectApi.createProject(); + + const projectId = response.id; + await this.n8n.page.goto(`workflow/new?projectId=${projectId}`); + await this.n8n.canvas.canvasPane().isVisible(); + } + + /** + * Start UI test from the canvas of an imported workflow + * Returns the workflow import result for use in the test + */ + async fromImportedWorkflow(workflowFile: string) { + const workflowImportResult = await this.n8n.api.workflowApi.importWorkflow(workflowFile); + await this.n8n.page.goto(`workflow/${workflowImportResult.workflowId}`); + return workflowImportResult; + } +} diff --git a/packages/testing/playwright/fixtures/base.ts b/packages/testing/playwright/fixtures/base.ts index 81510ad089..7e22439948 100644 --- a/packages/testing/playwright/fixtures/base.ts +++ b/packages/testing/playwright/fixtures/base.ts @@ -61,7 +61,6 @@ export const test = base.extend({ const envBaseURL = process.env.N8N_BASE_URL; if (envBaseURL) { - console.log(`Using external N8N_BASE_URL: ${envBaseURL}`); await use(null as unknown as N8NStack); return; } @@ -141,8 +140,8 @@ export const test = base.extend({ await page.close(); }, - n8n: async ({ page }, use) => { - const n8nInstance = new n8nPage(page); + n8n: async ({ page, api }, use) => { + const n8nInstance = new n8nPage(page, api); await use(n8nInstance); }, diff --git a/packages/testing/playwright/package.json b/packages/testing/playwright/package.json index 3dbcd0c6a6..1013da56fe 100644 --- a/packages/testing/playwright/package.json +++ b/packages/testing/playwright/package.json @@ -24,13 +24,16 @@ }, "devDependencies": { "@currents/playwright": "^1.15.3", + "@n8n/api-types": "workspace:^", "@playwright/test": "1.54.2", "@types/lodash": "catalog:", "eslint-plugin-playwright": "2.2.2", "generate-schema": "2.6.0", + "n8n": "workspace:*", "n8n-containers": "workspace:*", + "n8n-core": "workspace:*", + "n8n-workflow": "workspace:*", "nanoid": "catalog:", - "tsx": "catalog:", - "@n8n/api-types": "workspace:^" + "tsx": "catalog:" } } diff --git a/packages/testing/playwright/pages/WorkflowsPage.ts b/packages/testing/playwright/pages/WorkflowsPage.ts index a478d84e2c..ebe6accb89 100644 --- a/packages/testing/playwright/pages/WorkflowsPage.ts +++ b/packages/testing/playwright/pages/WorkflowsPage.ts @@ -3,10 +3,6 @@ import type { Locator } from '@playwright/test'; import { BasePage } from './BasePage'; export class WorkflowsPage extends BasePage { - async clickNewWorkflowCard() { - await this.clickByTestId('new-workflow-card'); - } - async clickAddFirstProjectButton() { await this.clickByTestId('add-first-project-button'); } @@ -15,10 +11,20 @@ export class WorkflowsPage extends BasePage { await this.clickByTestId('project-plus-button'); } + /** + * This is the add workflow button on the workflows page, visible when there are already workflows. + */ async clickAddWorkflowButton() { await this.clickByTestId('add-resource-workflow'); } + /** + * This is the new workflow button on the workflows page, visible when there are no workflows. + */ + async clickNewWorkflowCard() { + await this.clickByTestId('new-workflow-card'); + } + getNewWorkflowCard() { return this.page.getByTestId('new-workflow-card'); } diff --git a/packages/testing/playwright/pages/n8nPage.ts b/packages/testing/playwright/pages/n8nPage.ts index 969e9af5fa..8ceeffe1ce 100644 --- a/packages/testing/playwright/pages/n8nPage.ts +++ b/packages/testing/playwright/pages/n8nPage.ts @@ -19,11 +19,14 @@ import { WorkflowSharingModal } from './WorkflowSharingModal'; import { WorkflowsPage } from './WorkflowsPage'; import { CanvasComposer } from '../composables/CanvasComposer'; import { ProjectComposer } from '../composables/ProjectComposer'; +import { TestEntryComposer } from '../composables/TestEntryComposer'; import { WorkflowComposer } from '../composables/WorkflowComposer'; +import type { ApiHelpers } from '../services/api-helper'; // eslint-disable-next-line @typescript-eslint/naming-convention export class n8nPage { readonly page: Page; + readonly api: ApiHelpers; // Pages readonly aiAssistant: AIAssistantPage; @@ -51,9 +54,11 @@ export class n8nPage { readonly workflowComposer: WorkflowComposer; readonly projectComposer: ProjectComposer; readonly canvasComposer: CanvasComposer; + readonly start: TestEntryComposer; - constructor(page: Page) { + constructor(page: Page, api: ApiHelpers) { this.page = page; + this.api = api; // Pages this.aiAssistant = new AIAssistantPage(page); @@ -81,6 +86,7 @@ export class n8nPage { this.workflowComposer = new WorkflowComposer(this); this.projectComposer = new ProjectComposer(this); this.canvasComposer = new CanvasComposer(this); + this.start = new TestEntryComposer(this); } async goHome() { diff --git a/packages/testing/playwright/playwright.config.ts b/packages/testing/playwright/playwright.config.ts index 6c9ac8412c..1afb317a18 100644 --- a/packages/testing/playwright/playwright.config.ts +++ b/packages/testing/playwright/playwright.config.ts @@ -27,7 +27,9 @@ export default defineConfig({ retries: IS_CI ? 2 : 0, workers: WORKERS, timeout: 60000, - + expect: { + timeout: 10000, + }, projects: getProjects(), // We use this if an n8n url is passed in. If the server is already running, we reuse it. diff --git a/packages/testing/playwright/services/api-helper.ts b/packages/testing/playwright/services/api-helper.ts index 0810c65a2c..98e9d82c5b 100644 --- a/packages/testing/playwright/services/api-helper.ts +++ b/packages/testing/playwright/services/api-helper.ts @@ -9,6 +9,7 @@ import { INSTANCE_ADMIN_CREDENTIALS, } from '../config/test-users'; import { TestError } from '../Types'; +import { ProjectApiHelper } from './project-api-helper'; import { WorkflowApiHelper } from './workflow-api-helper'; export interface LoginResponseData { @@ -33,10 +34,12 @@ const DB_TAGS = { export class ApiHelpers { request: APIRequestContext; workflowApi: WorkflowApiHelper; + projectApi: ProjectApiHelper; constructor(requestContext: APIRequestContext) { this.request = requestContext; this.workflowApi = new WorkflowApiHelper(this); + this.projectApi = new ProjectApiHelper(this); } // ===== MAIN SETUP METHODS ===== diff --git a/packages/testing/playwright/services/project-api-helper.ts b/packages/testing/playwright/services/project-api-helper.ts new file mode 100644 index 0000000000..ddfdb12291 --- /dev/null +++ b/packages/testing/playwright/services/project-api-helper.ts @@ -0,0 +1,30 @@ +import { nanoid } from 'nanoid'; + +import type { ApiHelpers } from './api-helper'; +import { TestError } from '../Types'; + +export class ProjectApiHelper { + constructor(private api: ApiHelpers) {} + + /** + * Create a new project with a unique name + * @param projectName Optional base name for the project. If not provided, generates a default name. + * @returns The created project data + */ + async createProject(projectName?: string) { + const uniqueName = projectName ? `${projectName} (${nanoid(8)})` : `Test Project ${nanoid(8)}`; + + const response = await this.api.request.post('/rest/projects', { + data: { + name: uniqueName, + }, + }); + + if (!response.ok()) { + throw new TestError(`Failed to create project: ${await response.text()}`); + } + + const result = await response.json(); + return result.data ?? result; + } +} diff --git a/packages/testing/playwright/services/webhook-helper.ts b/packages/testing/playwright/services/webhook-helper.ts deleted file mode 100644 index e285d8d5e0..0000000000 --- a/packages/testing/playwright/services/webhook-helper.ts +++ /dev/null @@ -1,160 +0,0 @@ -import { readFileSync } from 'fs'; -import { nanoid } from 'nanoid'; -import { setTimeout } from 'timers/promises'; - -import type { ApiHelpers } from './api-helper'; -import { TestError } from '../Types'; -import { resolveFromRoot } from '../utils/path-helper'; - -type WorkflowDefinition = { - name?: string; - active?: boolean; - nodes: Array<{ - id?: string; - name?: string; - type: string; - typeVersion?: number; - position?: [number, number]; - webhookId?: string; - parameters: { [key: string]: unknown } & { path?: string }; - }>; - connections?: Record; -}; - -/** - * Generate and assign a unique webhook id and path to the first Webhook node in a workflow. - * - * - Uniqueness: Uses nanoid to ensure both the internal `webhookId` and external `parameters.path` - * are unique per call, avoiding collisions across parallel tests and instances. - * - Path format: `${prefix}-${nanoid}` (default prefix: `test-webhook`). - * - Mutation: Updates the passed-in `workflow` object in-place. - */ -export function applyUniqueWebhookIds( - workflow: WorkflowDefinition, - options?: { prefix?: string; idLength?: number }, -) { - const idLength = options?.idLength ?? 12; - const prefix = options?.prefix ?? 'test-webhook'; - - const generatedId = nanoid(idLength); - const generatedPath = `${prefix}-${generatedId}`; - - for (const node of workflow.nodes) { - if (node.type === 'n8n-nodes-base.webhook') { - node.webhookId = generatedId; - node.parameters.path = generatedPath; - } - } - - return { webhookId: generatedId, webhookPath: generatedPath, workflow }; -} - -/** - * Create a webhook workflow from an in-memory definition after assigning unique webhook id/path. - * - * Returns the externally callable `webhookPath` (what to pass to triggerWebhook) - * and the `workflowId` created by the API. - */ -export async function createWebhookWorkflow( - api: ApiHelpers, - workflow: WorkflowDefinition, - options?: { prefix?: string; idLength?: number }, -) { - const { webhookPath } = applyUniqueWebhookIds(workflow, options); - const createdWorkflow = await api.workflowApi.createWorkflow(workflow as object); - const workflowId = createdWorkflow.id as string; - return { webhookPath, workflowId, createdWorkflow }; -} - -/** - * Import a webhook workflow from `packages/testing/playwright/workflows/{fileName}` and create it - * with a unique webhook id/path. - */ -export async function importWebhookWorkflow( - api: ApiHelpers, - fileName: string, - options?: { prefix?: string; idLength?: number }, -) { - const workflowDefinition = JSON.parse( - readFileSync(resolveFromRoot('workflows', fileName), 'utf8'), - ) as WorkflowDefinition; - - return await createWebhookWorkflow(api, workflowDefinition, options); -} - -/** - * Convenience: import a webhook workflow from file, ensure unique webhook id/path, and activate it. - * - * Returns the `webhookPath` to call and the `workflowId` for follow-up assertions. - */ -export async function importAndActivateWebhookWorkflow( - api: ApiHelpers, - fileName: string, - options?: { prefix?: string; idLength?: number }, -) { - const { webhookPath, workflowId, createdWorkflow } = await importWebhookWorkflow( - api, - fileName, - options, - ); - await setTimeout(500); - await api.workflowApi.setActive(workflowId, true); - return { webhookPath, workflowId, createdWorkflow }; -} - -/** - * Convenience: create a webhook workflow from an in-memory definition and activate it. - */ -export async function createAndActivateWebhookWorkflow( - api: ApiHelpers, - workflow: WorkflowDefinition, - options?: { prefix?: string; idLength?: number }, -) { - const { webhookPath, workflowId, createdWorkflow } = await createWebhookWorkflow( - api, - workflow, - options, - ); - // Timing issue between workflow creation and activation - await setTimeout(500); - await api.workflowApi.setActive(workflowId, true); - return { webhookPath, workflowId, createdWorkflow }; -} - -/** - * Trigger a webhook endpoint with optional data and parameters. - * - * @param api - The API helpers instance - * @param path - The webhook path (without /webhook/ prefix) - * @param options - Configuration for the webhook request - */ -export async function triggerWebhook( - api: ApiHelpers, - path: string, - options: { method?: 'GET' | 'POST'; data?: object; params?: Record } = {}, -) { - const { method = 'POST', data, params } = options; - - let url = `/webhook/${path}`; - if (params && Object.keys(params).length > 0) { - const searchParams = new URLSearchParams(params); - url += `?${searchParams.toString()}`; - } - - const requestOptions: Record = { - headers: { 'Content-Type': 'application/json' }, - }; - - if (data && method === 'POST') { - requestOptions.data = data; - } - - const response = - method === 'GET' ? await api.request.get(url) : await api.request.post(url, requestOptions); - - if (!response.ok()) { - throw new TestError(`Webhook trigger failed: ${await response.text()}`); - } - - return response; -} diff --git a/packages/testing/playwright/services/workflow-api-helper.ts b/packages/testing/playwright/services/workflow-api-helper.ts index 730827ac14..2e95a8161a 100644 --- a/packages/testing/playwright/services/workflow-api-helper.ts +++ b/packages/testing/playwright/services/workflow-api-helper.ts @@ -1,10 +1,30 @@ +import { readFileSync } from 'fs'; +import type { IWorkflowBase, ExecutionSummary } from 'n8n-workflow'; +import { nanoid } from 'nanoid'; + +// Type for execution responses from the n8n API +// Couldn't find the exact type so I put these ones together + +interface ExecutionListResponse extends ExecutionSummary { + data: string; + workflowData: IWorkflowBase; +} + import type { ApiHelpers } from './api-helper'; import { TestError } from '../Types'; +import { resolveFromRoot } from '../utils/path-helper'; + +type WorkflowImportResult = { + workflowId: string; + createdWorkflow: IWorkflowBase; + webhookPath?: string; + webhookId?: string; +}; export class WorkflowApiHelper { constructor(private api: ApiHelpers) {} - async createWorkflow(workflow: object) { + async createWorkflow(workflow: IWorkflowBase) { const response = await this.api.request.post('/rest/workflows', { data: workflow }); if (!response.ok()) { @@ -27,7 +47,83 @@ export class WorkflowApiHelper { } } - async getExecutions(workflowId?: string, limit = 20) { + /** + * Make workflow unique by updating name, IDs, and webhook paths if present. + * This ensures no conflicts when importing workflows for testing. + */ + private makeWorkflowUnique( + workflow: IWorkflowBase, + options?: { webhookPrefix?: string; idLength?: number }, + ) { + const idLength = options?.idLength ?? 12; + const webhookPrefix = options?.webhookPrefix ?? 'test-webhook'; + const uniqueSuffix = nanoid(idLength); + + // Make workflow name unique + if (workflow.name) { + workflow.name = `${workflow.name} (Test ${uniqueSuffix})`; + } + + // Check if workflow has webhook nodes and process them + let webhookId: string | undefined; + let webhookPath: string | undefined; + + for (const node of workflow.nodes) { + if (node.type === 'n8n-nodes-base.webhook') { + webhookId = nanoid(idLength); + webhookPath = `${webhookPrefix}-${webhookId}`; + node.webhookId = webhookId; + node.parameters.path = webhookPath; + } + } + + return { webhookId, webhookPath, workflow }; + } + + /** + * Create a workflow from an in-memory definition, making it unique for testing. + * Returns detailed information about what was created. + */ + async createWorkflowFromDefinition( + workflow: IWorkflowBase, + options?: { webhookPrefix?: string; idLength?: number }, + ): Promise { + const { webhookPath, webhookId } = this.makeWorkflowUnique(workflow, options); + const createdWorkflow = await this.createWorkflow(workflow); + const workflowId: string = String(createdWorkflow.id); + + return { + workflowId, + createdWorkflow, + webhookPath, + webhookId, + }; + } + + /** + * Import a workflow from file and make it unique for testing. + * The workflow will be created with its original active state from the JSON file. + * Returns detailed information about what was imported, including webhook info if present. + */ + async importWorkflow( + fileName: string, + options?: { webhookPrefix?: string; idLength?: number }, + ): Promise { + const workflowDefinition: IWorkflowBase = JSON.parse( + readFileSync(resolveFromRoot('workflows', fileName), 'utf8'), + ); + + const result = await this.createWorkflowFromDefinition(workflowDefinition, options); + + // Ensure the workflow is in the correct active state as specified in the JSON + if (workflowDefinition.active) { + await this.setActive(result.workflowId, workflowDefinition.active); + } + + return result; + } + + async getExecutions(workflowId?: string, limit = 20): Promise { const params = new URLSearchParams(); if (workflowId) params.set('workflowId', workflowId); params.set('limit', limit.toString()); @@ -47,7 +143,7 @@ export class WorkflowApiHelper { return []; } - async getExecution(executionId: string) { + async getExecution(executionId: string): Promise { const response = await this.api.request.get(`/rest/executions/${executionId}`); if (!response.ok()) { @@ -58,7 +154,7 @@ export class WorkflowApiHelper { return result.data ?? result; } - async waitForExecution(workflowId: string, timeoutMs = 10000) { + async waitForExecution(workflowId: string, timeoutMs = 10000): Promise { const initialExecutions = await this.getExecutions(workflowId, 50); const initialCount = initialExecutions.length; const startTime = Date.now(); @@ -77,7 +173,9 @@ export class WorkflowApiHelper { for (const execution of executions) { const isCompleted = execution.status === 'success' || execution.status === 'error'; if (isCompleted && execution.mode === 'webhook') { - const executionTime = new Date(execution.startedAt ?? execution.createdAt).getTime(); + const executionTime = new Date( + execution.startedAt ?? execution.createdAt ?? Date.now(), + ).getTime(); if (executionTime >= startTime - 5000) { return execution; } diff --git a/packages/testing/playwright/tests/ui/building-blocks/01-core-ui-patterns.spec.ts b/packages/testing/playwright/tests/ui/building-blocks/01-core-ui-patterns.spec.ts new file mode 100644 index 0000000000..8624cd6727 --- /dev/null +++ b/packages/testing/playwright/tests/ui/building-blocks/01-core-ui-patterns.spec.ts @@ -0,0 +1,48 @@ +import { test, expect } from '../../../fixtures/base'; + +test.describe('Core UI Patterns - Building Blocks', () => { + test.describe('Entry Point: Home Page', () => { + test('should navigate from home', async ({ n8n }) => { + await n8n.start.fromHome(); + expect(n8n.page.url()).toContain('/home/workflows'); + }); + }); + + test.describe('Entry Point: Blank Canvas', () => { + test('should navigate from blank canvas', async ({ n8n }) => { + await n8n.start.fromBlankCanvas(); + await expect(n8n.canvas.canvasPane()).toBeVisible(); + }); + }); + + test.describe('Entry Point: Basic Workflow Creation', () => { + test('should create a new project and workflow', async ({ n8n }) => { + await n8n.start.fromNewProject(); + await expect(n8n.canvas.canvasPane()).toBeVisible(); + }); + }); + + test.describe('Entry Point: Imported Workflow', () => { + test('should import a webhook workflow', async ({ n8n }) => { + const workflowImportResult = await n8n.start.fromImportedWorkflow('simple-webhook-test.json'); + const { webhookPath } = workflowImportResult; + + const testPayload = { message: 'Hello from Playwright test' }; + + await n8n.canvas.clickExecuteWorkflowButton(); + await expect(n8n.canvas.getExecuteWorkflowButton()).toHaveText('Waiting for trigger event'); + + const webhookResponse = await n8n.page.request.post(`/webhook-test/${webhookPath}`, { + data: testPayload, + }); + + expect(webhookResponse.ok()).toBe(true); + }); + + test('should import a workflow', async ({ n8n }) => { + await n8n.start.fromImportedWorkflow('manual.json'); + await n8n.workflowComposer.executeWorkflowAndWaitForNotification('Success'); + await expect(n8n.canvas.canvasPane()).toBeVisible(); + }); + }); +}); diff --git a/packages/testing/playwright/tests/ui/webhook-external-trigger.spec.ts b/packages/testing/playwright/tests/ui/webhook-external-trigger.spec.ts index f7470b1e98..e1c39d578b 100644 --- a/packages/testing/playwright/tests/ui/webhook-external-trigger.spec.ts +++ b/packages/testing/playwright/tests/ui/webhook-external-trigger.spec.ts @@ -1,23 +1,22 @@ import { test, expect } from '../../fixtures/base'; -import { importAndActivateWebhookWorkflow, triggerWebhook } from '../../services/webhook-helper'; -test.describe('External Webhook Triggering @auth:owner', () => { +test.describe('External Webhook Triggering', () => { test('should create workflow via API, activate it, trigger webhook externally, and verify execution', async ({ api, }) => { - const { webhookPath, workflowId } = await importAndActivateWebhookWorkflow( - api, + const { webhookPath, workflowId } = await api.workflowApi.importWorkflow( 'simple-webhook-test.json', ); const testPayload = { message: 'Hello from Playwright test' }; - const webhookResponse = await triggerWebhook(api, webhookPath, { + const webhookResponse = await api.request.post(`/webhook/${webhookPath}`, { data: testPayload, }); + expect(webhookResponse.ok()).toBe(true); - const execution = await api.workflowApi.waitForExecution(workflowId, 10000); + const execution = await api.workflowApi.waitForExecution(workflowId, 5000); expect(execution.status).toBe('success'); const executionDetails = await api.workflowApi.getExecution(execution.id); diff --git a/packages/testing/playwright/workflows/manual.json b/packages/testing/playwright/workflows/manual.json new file mode 100644 index 0000000000..3090bfded8 --- /dev/null +++ b/packages/testing/playwright/workflows/manual.json @@ -0,0 +1,22 @@ +{ + "name": "Manual Trigger Workflow", + "nodes": [ + { + "parameters": {}, + "type": "n8n-nodes-base.manualTrigger", + "typeVersion": 1, + "position": [0, 0], + "id": "0567e1a2-e1cb-480f-9a17-8f37b88bbe7f", + "name": "When clicking ‘Execute workflow’" + } + ], + "pinData": {}, + "connections": {}, + "active": false, + "settings": { + "executionOrder": "v1" + }, + "versionId": "2071c8bd-6e92-4eb6-81cd-3d693f683955", + "id": "YaCQ6nNLk4xJabWT", + "tags": [] +} diff --git a/packages/testing/playwright/workflows/simple-webhook-test.json b/packages/testing/playwright/workflows/simple-webhook-test.json index 86e5ff5f88..c23b2880a0 100644 --- a/packages/testing/playwright/workflows/simple-webhook-test.json +++ b/packages/testing/playwright/workflows/simple-webhook-test.json @@ -1,6 +1,6 @@ { "name": "Simple Webhook Test", - "active": false, + "active": true, "nodes": [ { "parameters": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a371952020..c2186c7989 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3129,9 +3129,18 @@ importers: generate-schema: specifier: 2.6.0 version: 2.6.0 + n8n: + specifier: workspace:* + version: link:../../cli n8n-containers: specifier: workspace:* version: link:../containers + n8n-core: + specifier: workspace:* + version: link:../../core + n8n-workflow: + specifier: workspace:* + version: link:../../workflow nanoid: specifier: 'catalog:' version: 3.3.8 @@ -18795,7 +18804,7 @@ snapshots: '@currents/commit-info': 1.0.1-beta.0 async-retry: 1.3.3 axios: 1.11.0(debug@4.4.1) - axios-retry: 4.5.0(axios@1.11.0(debug@4.4.1)) + axios-retry: 4.5.0(axios@1.11.0) c12: 1.11.2(magicast@0.3.5) chalk: 4.1.2 commander: 12.1.0 @@ -23479,14 +23488,9 @@ snapshots: axe-core@4.7.2: {} - axios-retry@4.5.0(axios@1.11.0(debug@4.4.1)): - dependencies: - axios: 1.11.0(debug@4.4.1) - is-retry-allowed: 2.2.0 - axios-retry@4.5.0(axios@1.11.0): dependencies: - axios: 1.11.0(debug@4.3.6) + axios: 1.11.0(debug@4.4.1) is-retry-allowed: 2.2.0 axios-retry@4.5.0(axios@1.8.3): @@ -23851,7 +23855,7 @@ snapshots: bundlemon@3.1.0(typescript@5.9.2): dependencies: - axios: 1.11.0(debug@4.3.6) + axios: 1.11.0(debug@4.4.1) axios-retry: 4.5.0(axios@1.11.0) brotli-size: 4.0.0 bundlemon-utils: 2.0.1 @@ -27000,7 +27004,7 @@ snapshots: infisical-node@1.3.0: dependencies: - axios: 1.11.0(debug@4.3.6) + axios: 1.11.0(debug@4.4.1) dotenv: 16.3.1 tweetnacl: 1.0.3 tweetnacl-util: 0.15.1 @@ -28207,7 +28211,7 @@ snapshots: '@langchain/groq': 0.2.3(@langchain/core@0.3.68(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.67)))(encoding@0.1.13) '@langchain/mistralai': 0.2.1(@langchain/core@0.3.68(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.67)))(zod@3.25.67) '@langchain/ollama': 0.2.3(@langchain/core@0.3.68(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.67))) - axios: 1.11.0(debug@4.3.6) + axios: 1.11.0(debug@4.4.1) cheerio: 1.0.0 handlebars: 4.7.8 transitivePeerDependencies: @@ -30259,7 +30263,7 @@ snapshots: posthog-node@3.2.1: dependencies: - axios: 1.11.0(debug@4.3.6) + axios: 1.11.0(debug@4.4.1) rusha: 0.8.14 transitivePeerDependencies: - debug @@ -30938,7 +30942,7 @@ snapshots: retry-axios@2.6.0(axios@1.11.0): dependencies: - axios: 1.11.0(debug@4.3.6) + axios: 1.11.0(debug@4.4.1) retry-request@7.0.2(encoding@0.1.13): dependencies: @@ -31443,7 +31447,7 @@ snapshots: asn1.js: 5.4.1 asn1.js-rfc2560: 5.0.1(asn1.js@5.4.1) asn1.js-rfc5280: 3.0.0 - axios: 1.11.0(debug@4.3.6) + axios: 1.11.0(debug@4.4.1) big-integer: 1.6.52 bignumber.js: 9.1.2 binascii: 0.0.2 @@ -33587,4 +33591,4 @@ snapshots: zx@8.1.4: optionalDependencies: '@types/fs-extra': 11.0.4 - '@types/node': 20.17.57 \ No newline at end of file + '@types/node': 20.17.57