diff --git a/examples/workflow-code-runner/.gitignore b/examples/workflow-code-runner/.gitignore new file mode 100644 index 00000000..c7c16664 --- /dev/null +++ b/examples/workflow-code-runner/.gitignore @@ -0,0 +1,2 @@ +/.next +/next-env.d.ts diff --git a/examples/workflow-code-runner/next.config.ts b/examples/workflow-code-runner/next.config.ts index ef1c8078..b1e26bf2 100644 --- a/examples/workflow-code-runner/next.config.ts +++ b/examples/workflow-code-runner/next.config.ts @@ -1,8 +1,6 @@ import { withWorkflow } from "workflow/next"; import type { NextConfig } from "next"; -const nextConfig: NextConfig = { - serverExternalPackages: ["@vercel/sandbox"], -}; +const nextConfig: NextConfig = {}; export default withWorkflow(nextConfig); diff --git a/examples/workflow-code-runner/package.json b/examples/workflow-code-runner/package.json index 35d58ca7..4c872614 100644 --- a/examples/workflow-code-runner/package.json +++ b/examples/workflow-code-runner/package.json @@ -4,7 +4,7 @@ "private": true, "scripts": { "dev": "next dev --turbopack", - "build": "next build --turbopack", + "build": "next build", "start": "next start" }, "dependencies": { @@ -13,7 +13,7 @@ "next": "16.0.10", "react": "19.2.3", "react-dom": "19.2.3", - "workflow": "^4.2.0-beta.71", + "workflow": "4.2.0-beta.73", "zod": "^4.1.9" }, "devDependencies": { diff --git a/examples/workflow-code-runner/public/file.svg b/examples/workflow-code-runner/public/file.svg new file mode 100644 index 00000000..004145cd --- /dev/null +++ b/examples/workflow-code-runner/public/file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/examples/workflow-code-runner/steps/sandbox.ts b/examples/workflow-code-runner/steps/sandbox.ts index 950b56cd..b65233a0 100644 --- a/examples/workflow-code-runner/steps/sandbox.ts +++ b/examples/workflow-code-runner/steps/sandbox.ts @@ -1,26 +1,26 @@ -import { Sandbox, setSandboxCredentials } from "@vercel/sandbox"; +import { Sandbox, setSandboxCredentials } from '@vercel/sandbox'; -function initCredentials() { - setSandboxCredentials({ - token: process.env.VERCEL_TOKEN!, - teamId: process.env.VERCEL_TEAM_ID!, - projectId: process.env.VERCEL_PROJECT_ID!, - }); -} +// Set credentials at module scope so they're available in every step +// context, including nested steps from SDK methods like writeFiles(), +// runCommand(), etc. which are each executed as their own step. +setSandboxCredentials({ + token: process.env.VERCEL_TOKEN!, + teamId: process.env.VERCEL_TEAM_ID!, + projectId: process.env.VERCEL_PROJECT_ID!, +}); export async function createSandbox() { - "use step"; - initCredentials(); + 'use step'; - console.log("[Sandbox] Creating..."); + console.log('[Sandbox] Creating...'); const sandbox = await Sandbox.create({ resources: { vcpus: 1 }, timeout: 5 * 60 * 1000, - runtime: "node22", + runtime: 'node22', }); - console.log("[Sandbox] Created:", sandbox.sandboxId); + console.log('[Sandbox] Created:', sandbox.sandboxId); // Return the full Sandbox object — workflow serialization // automatically dehydrates it via WORKFLOW_SERIALIZE @@ -30,16 +30,13 @@ export async function createSandbox() { // The Sandbox object is deserialized via WORKFLOW_DESERIALIZE when // it crosses the step boundary — no need for Sandbox.get(id) export async function execute(sandbox: Sandbox, code: string) { - "use step"; - initCredentials(); + 'use step'; - console.log("[Sandbox] Executing code..."); + console.log('[Sandbox] Executing code...'); - await sandbox.writeFiles([ - { path: "script.js", content: Buffer.from(code) }, - ]); + await sandbox.writeFiles([{ path: 'script.js', content: Buffer.from(code) }]); - const finished = await sandbox.runCommand("node", ["script.js"]); + const finished = await sandbox.runCommand('node', ['script.js']); const stdout = await finished.stdout(); const stderr = await finished.stderr(); @@ -51,9 +48,8 @@ export async function execute(sandbox: Sandbox, code: string) { } export async function stopSandbox(sandbox: Sandbox) { - "use step"; - initCredentials(); + 'use step'; - console.log("[Sandbox] Stopping..."); + console.log('[Sandbox] Stopping...'); await sandbox.stop(); } diff --git a/examples/workflow-code-runner/vercel.json b/examples/workflow-code-runner/vercel.json new file mode 100644 index 00000000..58142434 --- /dev/null +++ b/examples/workflow-code-runner/vercel.json @@ -0,0 +1,3 @@ +{ + "outputDirectory": "./.next" +} diff --git a/package.json b/package.json index 88ffa572..5b43a1a9 100644 --- a/package.json +++ b/package.json @@ -35,5 +35,8 @@ "pre-commit": "lint-staged" } }, - "packageManager": "pnpm@10.30.2+sha512.36cdc707e7b7940a988c9c1ecf88d084f8514b5c3f085f53a2e244c2921d3b2545bc20dd4ebe1fc245feec463bb298aecea7a63ed1f7680b877dc6379d8d0cb4" + "packageManager": "pnpm@10.30.2+sha512.36cdc707e7b7940a988c9c1ecf88d084f8514b5c3f085f53a2e244c2921d3b2545bc20dd4ebe1fc245feec463bb298aecea7a63ed1f7680b877dc6379d8d0cb4", + "dependencies": { + "workflow": "4.2.0-beta.73" + } } diff --git a/packages/vercel-sandbox/src/command.ts b/packages/vercel-sandbox/src/command.ts index 1f61ad3e..b8d3987c 100644 --- a/packages/vercel-sandbox/src/command.ts +++ b/packages/vercel-sandbox/src/command.ts @@ -1,7 +1,7 @@ -import { APIClient, type CommandData } from "./api-client/index.js"; -import { Signal, resolveSignal } from "./utils/resolveSignal.js"; -import { getSandboxCredentials } from "./utils/sandbox-credentials.js"; -import { WORKFLOW_SERIALIZE, WORKFLOW_DESERIALIZE } from "@workflow/serde"; +import { WORKFLOW_DESERIALIZE, WORKFLOW_SERIALIZE } from '@workflow/serde'; +import { APIClient, type CommandData } from './api-client/index.js'; +import { getCredentials } from './utils/get-credentials.js'; +import { resolveSignal, type Signal } from './utils/resolveSignal.js'; /** * Cached output from a command execution. @@ -49,17 +49,17 @@ export class Command { protected _client: APIClient | null = null; /** - * Lazily get or create the API client. - * If no client was provided during construction, creates one using global credentials. + * Lazily resolve credentials and construct an API client. + * @internal */ - get client(): APIClient { - if (!this._client) { - const credentials = getSandboxCredentials(); - this._client = new APIClient({ - teamId: credentials.teamId, - token: credentials.token, - }); - } + protected async ensureClient(): Promise { + 'use step'; + if (this._client) return this._client; + const credentials = await getCredentials(); + this._client = new APIClient({ + teamId: credentials.teamId, + token: credentials.token, + }); return this._client; } @@ -190,7 +190,12 @@ export class Command { * to access output as a string. */ logs(opts?: { signal?: AbortSignal }) { - return this.client.getLogs({ + if (!this._client) { + throw new Error( + 'logs() requires an API client. Call an async method first to initialize the client.' + ); + } + return this._client.getLogs({ sandboxId: this.sandboxId, cmdId: this.cmd.id, signal: opts?.signal, @@ -217,9 +222,11 @@ export class Command { * @returns A {@link CommandFinished} instance with populated exit code. */ async wait(params?: { signal?: AbortSignal }) { + 'use step'; + const client = await this.ensureClient(); params?.signal?.throwIfAborted(); - const command = await this.client.getCommand({ + const command = await client.getCommand({ sandboxId: this.sandboxId, cmdId: this.cmd.id, wait: true, @@ -227,7 +234,7 @@ export class Command { }); return new CommandFinished({ - client: this.client, + client, sandboxId: this.sandboxId, cmd: command.json.command, exitCode: command.json.command.exitCode, @@ -246,12 +253,12 @@ export class Command { if (!this.outputCache) { this.outputCache = (async () => { try { - let stdout = ""; - let stderr = ""; - let both = ""; + let stdout = ''; + let stderr = ''; + let both = ''; for await (const log of this.logs({ signal: opts?.signal })) { both += log.data; - if (log.stream === "stdout") { + if (log.stream === 'stdout') { stdout += log.data; } else { stderr += log.data; @@ -283,9 +290,10 @@ export class Command { * @returns The output of the specified stream(s) as a string. */ async output( - stream: "stdout" | "stderr" | "both" = "both", + stream: 'stdout' | 'stderr' | 'both' = 'both', opts?: { signal?: AbortSignal } ) { + 'use step'; const cached = await this.getCachedOutput(opts); return cached[stream]; } @@ -301,7 +309,8 @@ export class Command { * @returns The standard output of the command. */ async stdout(opts?: { signal?: AbortSignal }) { - return this.output("stdout", opts); + 'use step'; + return this.output('stdout', opts); } /** @@ -315,7 +324,8 @@ export class Command { * @returns The standard error output of the command. */ async stderr(opts?: { signal?: AbortSignal }) { - return this.output("stderr", opts); + 'use step'; + return this.output('stderr', opts); } /** @@ -327,10 +337,12 @@ export class Command { * @returns Promise. */ async kill(signal?: Signal, opts?: { abortSignal?: AbortSignal }) { - await this.client.killCommand({ + 'use step'; + const client = await this.ensureClient(); + await client.killCommand({ sandboxId: this.sandboxId, commandId: this.cmd.id, - signal: resolveSignal(signal ?? "SIGTERM"), + signal: resolveSignal(signal ?? 'SIGTERM'), abortSignal: opts?.abortSignal, }); } diff --git a/packages/vercel-sandbox/src/sandbox.serialize.test.ts b/packages/vercel-sandbox/src/sandbox.serialize.test.ts index aa00ac93..0a7823cc 100644 --- a/packages/vercel-sandbox/src/sandbox.serialize.test.ts +++ b/packages/vercel-sandbox/src/sandbox.serialize.test.ts @@ -1,44 +1,44 @@ -import { describe, it, expect, vi, afterEach } from "vitest"; -import { WORKFLOW_SERIALIZE, WORKFLOW_DESERIALIZE } from "@workflow/serde"; -import { registerSerializationClass } from "@workflow/core/class-serialization"; +import { registerSerializationClass } from '@workflow/core/class-serialization'; import { dehydrateStepReturnValue, hydrateStepReturnValue, -} from "@workflow/core/serialization"; -import { Sandbox, type SerializedSandbox } from "./sandbox"; -import type { SandboxMetaData, SandboxRouteData } from "./api-client"; -import { APIClient } from "./api-client"; -import { toSandboxSnapshot } from "./utils/sandbox-snapshot"; - -describe("Sandbox serialization", () => { +} from '@workflow/core/serialization'; +import { WORKFLOW_DESERIALIZE, WORKFLOW_SERIALIZE } from '@workflow/serde'; +import { afterEach, describe, expect, it, vi } from 'vitest'; +import type { SandboxMetaData, SandboxRouteData } from './api-client'; +import { APIClient } from './api-client'; +import { Sandbox, type SerializedSandbox } from './sandbox'; +import { toSandboxSnapshot } from './utils/sandbox-snapshot'; + +describe('Sandbox serialization', () => { const mockMetadata: SandboxMetaData = { - id: "sbx_test123", + id: 'sbx_test123', memory: 2048, vcpus: 1, - region: "us-east-1", - runtime: "node24", + region: 'us-east-1', + runtime: 'node24', timeout: 300000, - status: "running", + status: 'running', requestedAt: 1700000000000, startedAt: 1700000001000, createdAt: 1700000000000, - cwd: "/vercel/sandbox", + cwd: '/vercel/sandbox', updatedAt: 1700000002000, - networkPolicy: { mode: "allow-all" }, + networkPolicy: { mode: 'allow-all' }, }; const mockRoutes: SandboxRouteData[] = [ - { url: "https://test-3000.vercel.run", subdomain: "test-3000", port: 3000 }, - { url: "https://test-4000.vercel.run", subdomain: "test-4000", port: 4000 }, + { url: 'https://test-3000.vercel.run', subdomain: 'test-3000', port: 3000 }, + { url: 'https://test-4000.vercel.run', subdomain: 'test-4000', port: 4000 }, ]; const createMockSandbox = ( metadata: SandboxMetaData = mockMetadata, - routes: SandboxRouteData[] = mockRoutes, + routes: SandboxRouteData[] = mockRoutes ): Sandbox => { const client = new APIClient({ - teamId: "team_test", - token: "test_token", + teamId: 'team_test', + token: 'test_token', }); return new Sandbox({ @@ -60,38 +60,38 @@ describe("Sandbox serialization", () => { vi.restoreAllMocks(); }); - describe("WORKFLOW_SERIALIZE", () => { - it("serializes sandbox snapshot data", () => { + describe('WORKFLOW_SERIALIZE', () => { + it('serializes sandbox snapshot data', () => { const sandbox = createMockSandbox(); const serialized = serializeSandbox(sandbox); - expect(serialized.metadata.id).toBe("sbx_test123"); + expect(serialized.metadata.id).toBe('sbx_test123'); expect(serialized.routes).toEqual(mockRoutes); - expect(serialized.metadata.networkPolicy).toBe("allow-all"); + expect(serialized.metadata.networkPolicy).toBe('allow-all'); }); - it("returns plain JSON-serializable data", () => { + it('returns plain JSON-serializable data', () => { const sandbox = createMockSandbox(); const serialized = serializeSandbox(sandbox); const jsonString = JSON.stringify(serialized); const parsed = JSON.parse(jsonString); - expect(parsed.metadata.id).toBe("sbx_test123"); + expect(parsed.metadata.id).toBe('sbx_test123'); expect(parsed.routes).toEqual(mockRoutes); }); - it("does not include the API client or credentials", () => { + it('does not include the API client or credentials', () => { const sandbox = createMockSandbox(); const serialized = serializeSandbox(sandbox); - expect(serialized).not.toHaveProperty("client"); - expect(JSON.stringify(serialized)).not.toContain("token"); + expect(serialized).not.toHaveProperty('client'); + expect(JSON.stringify(serialized)).not.toContain('token'); }); }); - describe("WORKFLOW_DESERIALIZE", () => { - it("returns synchronously", () => { + describe('WORKFLOW_DESERIALIZE', () => { + it('returns synchronously', () => { const sandbox = createMockSandbox(); const serialized = serializeSandbox(sandbox); @@ -101,124 +101,124 @@ describe("Sandbox serialization", () => { expect(result).not.toBeInstanceOf(Promise); }); - it("reconstructs a fully usable snapshot-backed instance", () => { + it('reconstructs a fully usable snapshot-backed instance', () => { const sandbox = createMockSandbox(); const serialized = serializeSandbox(sandbox); const result = deserializeSandbox(serialized); - expect(result.sandboxId).toBe("sbx_test123"); - expect(result.status).toBe("running"); + expect(result.sandboxId).toBe('sbx_test123'); + expect(result.status).toBe('running'); expect(result.routes).toEqual(mockRoutes); - expect(result.networkPolicy).toBe("allow-all"); - expect(result.domain(3000)).toBe("https://test-3000.vercel.run"); + expect(result.networkPolicy).toBe('allow-all'); + expect(result.domain(3000)).toBe('https://test-3000.vercel.run'); }); - it("does not require global credentials just to deserialize and read metadata", async () => { + it('does not require global credentials just to deserialize and read metadata', async () => { vi.resetModules(); - const { Sandbox: FreshSandbox } = await import("./sandbox"); + const { Sandbox: FreshSandbox } = await import('./sandbox'); const serializedData: SerializedSandbox = { metadata: { - id: "sbx_test123", + id: 'sbx_test123', memory: 2048, vcpus: 1, - region: "us-east-1", - runtime: "node24", + region: 'us-east-1', + runtime: 'node24', timeout: 300000, - status: "running", + status: 'running', requestedAt: 1700000000000, startedAt: 1700000001000, createdAt: 1700000000000, - cwd: "/vercel/sandbox", + cwd: '/vercel/sandbox', updatedAt: 1700000002000, - networkPolicy: "allow-all", + networkPolicy: 'allow-all', }, routes: mockRoutes, }; const deserialized = FreshSandbox[WORKFLOW_DESERIALIZE]( - serializedData, + serializedData ) as Sandbox; - expect(deserialized.sandboxId).toBe("sbx_test123"); - expect(deserialized.status).toBe("running"); + expect(deserialized.sandboxId).toBe('sbx_test123'); + expect(deserialized.status).toBe('running'); expect(deserialized.routes).toEqual(mockRoutes); }); - it("still requires global credentials when API client is actually accessed", async () => { + it('deserialized instance has no client until ensureClient() is called', async () => { vi.resetModules(); - const { Sandbox: FreshSandbox } = await import("./sandbox"); + const { Sandbox: FreshSandbox } = await import('./sandbox'); const serializedData: SerializedSandbox = { metadata: { - id: "sbx_test123", + id: 'sbx_test123', memory: 2048, vcpus: 1, - region: "us-east-1", - runtime: "node24", + region: 'us-east-1', + runtime: 'node24', timeout: 300000, - status: "running", + status: 'running', requestedAt: 1700000000000, startedAt: 1700000001000, createdAt: 1700000000000, - cwd: "/vercel/sandbox", + cwd: '/vercel/sandbox', updatedAt: 1700000002000, - networkPolicy: "allow-all", + networkPolicy: 'allow-all', }, routes: mockRoutes, }; const deserialized = FreshSandbox[WORKFLOW_DESERIALIZE]( - serializedData, + serializedData ) as Sandbox; - expect(() => deserialized.client).toThrowError( - /Global credentials have not been set/, - ); + // The deserialized instance has no client until an API method is called + // (which triggers ensureClient()). Verify the internal state is null. + expect((deserialized as any)._client).toBeNull(); }); }); - describe("workflow runtime integration", () => { - it("survives a step boundary roundtrip", async () => { - registerSerializationClass("Sandbox", Sandbox); + describe('workflow runtime integration', () => { + it('survives a step boundary roundtrip', async () => { + registerSerializationClass('Sandbox', Sandbox); const sandbox = createMockSandbox(); const dehydrated = await dehydrateStepReturnValue( sandbox, - "run_123", - undefined, + 'run_123', + undefined ); const rehydrated = await hydrateStepReturnValue( dehydrated, - "run_123", - undefined, + 'run_123', + undefined ); expect(rehydrated).toBeInstanceOf(Sandbox); - expect(rehydrated.sandboxId).toBe("sbx_test123"); + expect(rehydrated.sandboxId).toBe('sbx_test123'); expect(rehydrated.routes).toEqual(mockRoutes); }); - it("preserves converted metadata through runtime pipeline", async () => { - registerSerializationClass("Sandbox", Sandbox); + it('preserves converted metadata through runtime pipeline', async () => { + registerSerializationClass('Sandbox', Sandbox); const sandbox = createMockSandbox(); const dehydrated = await dehydrateStepReturnValue( sandbox, - "run_456", - undefined, + 'run_456', + undefined ); const rehydrated = await hydrateStepReturnValue( dehydrated, - "run_456", - undefined, + 'run_456', + undefined ); - expect(rehydrated.status).toBe("running"); - expect(rehydrated.networkPolicy).toBe("allow-all"); + expect(rehydrated.status).toBe('running'); + expect(rehydrated.networkPolicy).toBe('allow-all'); }); }); }); diff --git a/packages/vercel-sandbox/src/sandbox.ts b/packages/vercel-sandbox/src/sandbox.ts index cd46420c..8cf86a2e 100644 --- a/packages/vercel-sandbox/src/sandbox.ts +++ b/packages/vercel-sandbox/src/sandbox.ts @@ -1,31 +1,31 @@ -import type { SandboxMetaData, SandboxRouteData } from "./api-client/index.js"; -import { type Writable } from "stream"; -import { pipeline } from "stream/promises"; -import { createWriteStream } from "fs"; -import { mkdir } from "fs/promises"; -import { dirname, resolve } from "path"; -import { APIClient } from "./api-client/index.js"; -import { Command, CommandFinished } from "./command.js"; -import { type Credentials, getCredentials } from "./utils/get-credentials.js"; -import { getPrivateParams, WithPrivate } from "./utils/types.js"; -import { WithFetchOptions } from "./api-client/api-client.js"; -import { RUNTIMES } from "./constants.js"; -import { Snapshot } from "./snapshot.js"; -import { consumeReadable } from "./utils/consume-readable.js"; +import { WORKFLOW_DESERIALIZE, WORKFLOW_SERIALIZE } from '@workflow/serde'; +import { createWriteStream } from 'fs'; +import { mkdir } from 'fs/promises'; +import { dirname, resolve } from 'path'; +import type { Writable } from 'stream'; +import { pipeline } from 'stream/promises'; +import type { WithFetchOptions } from './api-client/api-client.js'; +import type { SandboxMetaData, SandboxRouteData } from './api-client/index.js'; +import { APIClient } from './api-client/index.js'; +import { Command, CommandFinished } from './command.js'; +import type { RUNTIMES } from './constants.js'; +import type { + NetworkPolicy, + NetworkPolicyRule, + NetworkTransformer, +} from './network-policy.js'; +import { Snapshot } from './snapshot.js'; +import { consumeReadable } from './utils/consume-readable.js'; +import { type Credentials, getCredentials } from './utils/get-credentials.js'; import { - setSandboxCredentials, getSandboxCredentials, -} from "./utils/sandbox-credentials.js"; -import { - type NetworkPolicy, - type NetworkPolicyRule, - type NetworkTransformer, -} from "./network-policy.js"; + setSandboxCredentials, +} from './utils/sandbox-credentials.js'; import { - toSandboxSnapshot, type SandboxSnapshot, -} from "./utils/sandbox-snapshot.js"; -import { WORKFLOW_SERIALIZE, WORKFLOW_DESERIALIZE } from "@workflow/serde"; + toSandboxSnapshot, +} from './utils/sandbox-snapshot.js'; +import { getPrivateParams, type WithPrivate } from './utils/types.js'; export type { NetworkPolicy, NetworkPolicyRule, NetworkTransformer }; @@ -42,20 +42,20 @@ export interface BaseCreateSandboxParams { */ source?: | { - type: "git"; + type: 'git'; url: string; depth?: number; revision?: string; } | { - type: "git"; + type: 'git'; url: string; username: string; password: string; depth?: number; revision?: string; } - | { type: "tarball"; url: string }; + | { type: 'tarball'; url: string }; /** * Array of port numbers to expose from the sandbox. Sandboxes can * expose up to 4 ports. @@ -107,8 +107,8 @@ export interface BaseCreateSandboxParams { export type CreateSandboxParams = | BaseCreateSandboxParams - | (Omit & { - source: { type: "snapshot"; snapshotId: string }; + | (Omit & { + source: { type: 'snapshot'; snapshotId: string }; }); /** @inline */ @@ -172,7 +172,7 @@ interface RunCommandParams { } // Re-export for public API -export { setSandboxCredentials } from "./utils/sandbox-credentials.js"; +export { setSandboxCredentials } from './utils/sandbox-credentials.js'; // ============================================================================ // Sandbox class @@ -188,17 +188,21 @@ export class Sandbox { private _client: APIClient | null = null; /** - * Lazily get or create the API client. - * If no client was provided during construction, creates one using global credentials. + * Lazily resolve credentials and construct an API client. + * This is used in step contexts where the Sandbox was deserialized + * without a client (e.g. when crossing workflow/step boundaries). + * Uses getCredentials() which resolves from OIDC, env vars, or + * setSandboxCredentials() — works across isolated step contexts. + * @internal */ - get client(): APIClient { - if (!this._client) { - const credentials = getSandboxCredentials(); - this._client = new APIClient({ - teamId: credentials.teamId, - token: credentials.token, - }); - } + private async ensureClient(): Promise { + 'use step'; + if (this._client) return this._client; + const credentials = await getCredentials(); + this._client = new APIClient({ + teamId: credentials.teamId, + token: credentials.token, + }); return this._client; } @@ -222,7 +226,7 @@ export class Sandbox { /** * The status of the sandbox. */ - public get status(): SandboxMetaData["status"] { + public get status(): SandboxMetaData['status'] { return this.sandbox.status; } @@ -305,10 +309,11 @@ export class Sandbox { * the next page of results. */ static async list( - params?: Partial[0]> & + params?: Partial[0]> & Partial & - WithFetchOptions, + WithFetchOptions ) { + 'use step'; const credentials = await getCredentials(params); const client = new APIClient({ teamId: credentials.teamId, @@ -366,8 +371,9 @@ export class Sandbox { params?: WithPrivate< CreateSandboxParams | (CreateSandboxParams & Credentials) > & - WithFetchOptions, + WithFetchOptions ): Promise { + 'use step'; const credentials = await getCredentials(params); const client = new APIClient({ teamId: credentials.teamId, @@ -382,7 +388,7 @@ export class Sandbox { ports: params?.ports ?? [], timeout: params?.timeout, resources: params?.resources, - runtime: params && "runtime" in params ? params?.runtime : undefined, + runtime: params && 'runtime' in params ? params?.runtime : undefined, networkPolicy: params?.networkPolicy, env: params?.env, signal: params?.signal, @@ -404,8 +410,9 @@ export class Sandbox { */ static async get( params: WithPrivate & - WithFetchOptions, + WithFetchOptions ): Promise { + 'use step'; const credentials = await getCredentials(params); const client = new APIClient({ teamId: credentials.teamId, @@ -458,16 +465,18 @@ export class Sandbox { */ async getCommand( cmdId: string, - opts?: { signal?: AbortSignal }, + opts?: { signal?: AbortSignal } ): Promise { - const command = await this.client.getCommand({ + 'use step'; + const client = await this.ensureClient(); + const command = await client.getCommand({ sandboxId: this.sandbox.id, cmdId, signal: opts?.signal, }); return new Command({ - client: this.client, + client, sandboxId: this.sandbox.id, cmd: command.json.command, }); @@ -485,7 +494,7 @@ export class Sandbox { async runCommand( command: string, args?: string[], - opts?: { signal?: AbortSignal }, + opts?: { signal?: AbortSignal } ): Promise; /** @@ -495,7 +504,7 @@ export class Sandbox { * @returns A {@link Command} instance for the running command. */ async runCommand( - params: RunCommandParams & { detached: true }, + params: RunCommandParams & { detached: true } ): Promise; /** @@ -509,10 +518,12 @@ export class Sandbox { async runCommand( commandOrParams: string | RunCommandParams, args?: string[], - opts?: { signal?: AbortSignal }, + opts?: { signal?: AbortSignal } ): Promise { + 'use step'; + const client = await this.ensureClient(); const params: RunCommandParams = - typeof commandOrParams === "string" + typeof commandOrParams === 'string' ? { cmd: commandOrParams, args, signal: opts?.signal } : commandOrParams; @@ -524,9 +535,9 @@ export class Sandbox { try { for await (const log of command.logs({ signal: params.signal })) { - if (log.stream === "stdout") { + if (log.stream === 'stdout') { params.stdout?.write(log.data); - } else if (log.stream === "stderr") { + } else if (log.stream === 'stderr') { params.stderr?.write(log.data); } } @@ -539,7 +550,7 @@ export class Sandbox { }; if (wait) { - const commandStream = await this.client.runCommand({ + const commandStream = await client.runCommand({ sandboxId: this.sandbox.id, command: params.cmd, args: params.args ?? [], @@ -551,7 +562,7 @@ export class Sandbox { }); const command = new Command({ - client: this.client, + client, sandboxId: this.sandbox.id, cmd: commandStream.command, }); @@ -561,14 +572,14 @@ export class Sandbox { pipeLogs(command), ]); return new CommandFinished({ - client: this.client, + client, sandboxId: this.sandbox.id, cmd: finished, exitCode: finished.exitCode ?? 0, }); } - const commandResponse = await this.client.runCommand({ + const commandResponse = await client.runCommand({ sandboxId: this.sandbox.id, command: params.cmd, args: params.args ?? [], @@ -579,7 +590,7 @@ export class Sandbox { }); const command = new Command({ - client: this.client, + client, sandboxId: this.sandbox.id, cmd: commandResponse.json.command, }); @@ -588,7 +599,7 @@ export class Sandbox { if (params.signal?.aborted) { return; } - (params.stderr ?? params.stdout)?.emit('error', err) + (params.stderr ?? params.stdout)?.emit('error', err); }); return command; @@ -602,7 +613,9 @@ export class Sandbox { * @param opts.signal - An AbortSignal to cancel the operation. */ async mkDir(path: string, opts?: { signal?: AbortSignal }): Promise { - await this.client.mkDir({ + 'use step'; + const client = await this.ensureClient(); + await client.mkDir({ sandboxId: this.sandbox.id, path: path, signal: opts?.signal, @@ -619,9 +632,11 @@ export class Sandbox { */ async readFile( file: { path: string; cwd?: string }, - opts?: { signal?: AbortSignal }, + opts?: { signal?: AbortSignal } ): Promise { - return this.client.readFile({ + 'use step'; + const client = await this.ensureClient(); + return client.readFile({ sandboxId: this.sandbox.id, path: file.path, cwd: file.cwd, @@ -639,9 +654,11 @@ export class Sandbox { */ async readFileToBuffer( file: { path: string; cwd?: string }, - opts?: { signal?: AbortSignal }, + opts?: { signal?: AbortSignal } ): Promise { - const stream = await this.client.readFile({ + 'use step'; + const client = await this.ensureClient(); + const stream = await client.readFile({ sandboxId: this.sandbox.id, path: file.path, cwd: file.cwd, @@ -668,17 +685,19 @@ export class Sandbox { async downloadFile( src: { path: string; cwd?: string }, dst: { path: string; cwd?: string }, - opts?: { mkdirRecursive?: boolean; signal?: AbortSignal }, + opts?: { mkdirRecursive?: boolean; signal?: AbortSignal } ): Promise { + 'use step'; + const client = await this.ensureClient(); if (!src?.path) { - throw new Error("downloadFile: source path is required"); + throw new Error('downloadFile: source path is required'); } if (!dst?.path) { - throw new Error("downloadFile: destination path is required"); + throw new Error('downloadFile: destination path is required'); } - const stream = await this.client.readFile({ + const stream = await client.readFile({ sandboxId: this.sandbox.id, path: src.path, cwd: src.cwd, @@ -690,7 +709,7 @@ export class Sandbox { } try { - const dstPath = resolve(dst.cwd ?? "", dst.path); + const dstPath = resolve(dst.cwd ?? '', dst.path); if (opts?.mkdirRecursive) { await mkdir(dirname(dstPath), { recursive: true }); } @@ -721,12 +740,14 @@ export class Sandbox { */ async writeFiles( files: { path: string; content: Buffer; mode?: number }[], - opts?: { signal?: AbortSignal }, + opts?: { signal?: AbortSignal } ) { - return this.client.writeFiles({ + 'use step'; + const client = await this.ensureClient(); + return client.writeFiles({ sandboxId: this.sandbox.id, cwd: this.sandbox.cwd, - extractDir: "/", + extractDir: '/', files: files, signal: opts?.signal, }); @@ -760,7 +781,9 @@ export class Sandbox { signal?: AbortSignal; blocking?: boolean; }): Promise { - const response = await this.client.stopSandbox({ + 'use step'; + const client = await this.ensureClient(); + const response = await client.stopSandbox({ sandboxId: this.sandbox.id, signal: opts?.signal, blocking: opts?.blocking, @@ -802,9 +825,11 @@ export class Sandbox { */ async updateNetworkPolicy( networkPolicy: NetworkPolicy, - opts?: { signal?: AbortSignal }, + opts?: { signal?: AbortSignal } ): Promise { - const response = await this.client.updateNetworkPolicy({ + 'use step'; + const client = await this.ensureClient(); + const response = await client.updateNetworkPolicy({ sandboxId: this.sandbox.id, networkPolicy: networkPolicy, signal: opts?.signal, @@ -833,9 +858,11 @@ export class Sandbox { */ async extendTimeout( duration: number, - opts?: { signal?: AbortSignal }, + opts?: { signal?: AbortSignal } ): Promise { - const response = await this.client.extendTimeout({ + 'use step'; + const client = await this.ensureClient(); + const response = await client.extendTimeout({ sandboxId: this.sandbox.id, duration, signal: opts?.signal, @@ -860,7 +887,9 @@ export class Sandbox { expiration?: number; signal?: AbortSignal; }): Promise { - const response = await this.client.createSnapshot({ + 'use step'; + const client = await this.ensureClient(); + const response = await client.createSnapshot({ sandboxId: this.sandbox.id, expiration: opts?.expiration, signal: opts?.signal, @@ -869,7 +898,7 @@ export class Sandbox { this.sandbox = toSandboxSnapshot(response.json.sandbox); return new Snapshot({ - client: this.client, + client, snapshot: response.json.snapshot, }); } diff --git a/packages/vercel-sandbox/src/snapshot.ts b/packages/vercel-sandbox/src/snapshot.ts index d3561c85..b3c97632 100644 --- a/packages/vercel-sandbox/src/snapshot.ts +++ b/packages/vercel-sandbox/src/snapshot.ts @@ -1,7 +1,7 @@ -import type { SnapshotMetadata } from "./api-client/index.js"; -import { APIClient } from "./api-client/index.js"; -import { WithFetchOptions } from "./api-client/api-client.js"; -import { Credentials, getCredentials } from "./utils/get-credentials.js"; +import type { WithFetchOptions } from './api-client/api-client.js'; +import type { SnapshotMetadata } from './api-client/index.js'; +import { APIClient } from './api-client/index.js'; +import { type Credentials, getCredentials } from './utils/get-credentials.js'; /** @inline */ interface GetSnapshotParams { @@ -41,7 +41,7 @@ export class Snapshot { /** * The status of the snapshot. */ - public get status(): SnapshotMetadata["status"] { + public get status(): SnapshotMetadata['status'] { return this.snapshot.status; } @@ -98,10 +98,11 @@ export class Snapshot { * the next page of results. */ static async list( - params?: Partial[0]> & + params?: Partial[0]> & Partial & - WithFetchOptions, + WithFetchOptions ) { + 'use step'; const credentials = await getCredentials(params); const client = new APIClient({ teamId: credentials.teamId, @@ -121,8 +122,9 @@ export class Snapshot { * @returns A promise resolving to the {@link Sandbox}. */ static async get( - params: GetSnapshotParams | (GetSnapshotParams & Credentials), + params: GetSnapshotParams | (GetSnapshotParams & Credentials) ): Promise { + 'use step'; const credentials = await getCredentials(params); const client = new APIClient({ teamId: credentials.teamId, @@ -148,7 +150,8 @@ export class Snapshot { * @returns A promise that resolves once the snapshot has been deleted. */ async delete(opts?: { signal?: AbortSignal }): Promise { - const response = await this.client.deleteSnapshot({ + 'use step'; + const response = await this.client!.deleteSnapshot({ snapshotId: this.snapshot.id, signal: opts?.signal, }); diff --git a/packages/vercel-sandbox/tsdown.config.ts b/packages/vercel-sandbox/tsdown.config.ts index d4df2a97..9cd6ddfe 100644 --- a/packages/vercel-sandbox/tsdown.config.ts +++ b/packages/vercel-sandbox/tsdown.config.ts @@ -1,13 +1,18 @@ -import { defineConfig } from "tsdown"; +import { defineConfig } from 'tsdown'; export default defineConfig({ - entry: ["src/index.ts", "src/auth/index.ts"], - outDir: "dist", - format: ["esm", "cjs"], + entry: ['src/index.ts', 'src/auth/index.ts'], + outDir: 'dist', + format: ['esm', 'cjs'], outExtensions: ({ format }) => ({ - js: format === "cjs" ? ".cjs" : ".js", + js: format === 'cjs' ? '.cjs' : '.js', }), sourcemap: true, dts: true, - target: "es2020", + target: 'es2020', + // Do not bundle internal modules into a single file. This keeps Node.js + // imports local to the files that use them, so the Workflow DevKit SWC + // compiler can strip "use step" method bodies and their associated imports + // independently — preventing false build errors in the workflow VM context. + bundle: false, }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b0013cab..badc812f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -16,6 +16,10 @@ catalogs: importers: .: + dependencies: + workflow: + specifier: 4.2.0-beta.73 + version: 4.2.0-beta.73(@nestjs/common@11.1.17(reflect-metadata@0.2.2)(rxjs@6.6.7))(@nestjs/core@11.1.17(@nestjs/common@11.1.17(reflect-metadata@0.2.2)(rxjs@6.6.7))(reflect-metadata@0.2.2)(rxjs@6.6.7))(@opentelemetry/api@1.9.0)(@swc/cli@0.8.0(@swc/core@1.15.3)(chokidar@5.0.0))(@swc/core@1.15.3)(next@16.0.10(@opentelemetry/api@1.9.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.8.3) devDependencies: '@changesets/cli': specifier: 2.29.4 @@ -250,8 +254,8 @@ importers: specifier: 19.2.3 version: 19.2.3(react@19.2.3) workflow: - specifier: ^4.2.0-beta.71 - version: 4.2.0-beta.71(@nestjs/common@11.1.17(reflect-metadata@0.2.2)(rxjs@6.6.7))(@nestjs/core@11.1.17(@nestjs/common@11.1.17(reflect-metadata@0.2.2)(rxjs@6.6.7))(reflect-metadata@0.2.2)(rxjs@6.6.7))(@opentelemetry/api@1.9.0)(@swc/cli@0.8.0(@swc/core@1.15.3)(chokidar@5.0.0))(@swc/core@1.15.3)(next@16.0.10(@opentelemetry/api@1.9.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.8.3) + specifier: 4.2.0-beta.73 + version: 4.2.0-beta.73(@nestjs/common@11.1.17(reflect-metadata@0.2.2)(rxjs@6.6.7))(@nestjs/core@11.1.17(@nestjs/common@11.1.17(reflect-metadata@0.2.2)(rxjs@6.6.7))(reflect-metadata@0.2.2)(rxjs@6.6.7))(@opentelemetry/api@1.9.0)(@swc/cli@0.8.0(@swc/core@1.15.3)(chokidar@5.0.0))(@swc/core@1.15.3)(next@16.0.10(@opentelemetry/api@1.9.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.8.3) zod: specifier: ^4.1.9 version: 4.3.6 @@ -1375,9 +1379,6 @@ packages: '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - '@jridgewell/trace-mapping@0.3.30': - resolution: {integrity: sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==} - '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} @@ -1663,8 +1664,8 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@nuxt/kit@4.3.1': - resolution: {integrity: sha512-UjBFt72dnpc+83BV3OIbCT0YHLevJtgJCHpxMX0YRKWLDhhbcDdUse87GtsQBrjvOzK7WUNUYLDS/hQLYev5rA==} + '@nuxt/kit@4.4.2': + resolution: {integrity: sha512-5+IPRNX2CjkBhuWUwz0hBuLqiaJPRoKzQ+SvcdrQDbAyE+VDeFt74VpSFr5/R0ujrK4b+XnSHUJWdS72w6hsog==} engines: {node: '>=18.12.0'} '@nuxt/opencollective@0.4.1': @@ -2590,14 +2591,14 @@ packages: '@vitest/utils@3.2.1': resolution: {integrity: sha512-KkHlGhePEKZSub5ViknBcN5KEF+u7dSUr9NW8QsVICusUojrgrOnnY3DEWWO877ax2Pyopuk2qHmt+gkNKnBVw==} - '@workflow/astro@4.0.0-beta.45': - resolution: {integrity: sha512-QRSXwhpjpu3JucO+iT2Bdkxm+3y1rmDWCYQ1RrgB7WXiZUlWobGo9dWxkew2pRw/MsBcO7jlGZjazVvCv3JhUQ==} + '@workflow/astro@4.0.0-beta.47': + resolution: {integrity: sha512-t/9R18hMKrwLVO1Gc61MUTsnRj+ZdQXvur5IkZWlMfo6xgH9RN5xUR8O0b2fN+GRBlMnzdR5hTG+DYH4PrWQ8w==} - '@workflow/builders@4.0.1-beta.62': - resolution: {integrity: sha512-54oBr928ZU7CqkCukO3+AxsqqdYtIWqP4W2dkCsd2eLafcLcNdmughfFHsbLlAS32Wgnd6VVa47WHYraIfb6Rw==} + '@workflow/builders@4.0.1-beta.64': + resolution: {integrity: sha512-RChF5D2XMyW63+1OiRovrQLlsGTpoA+A21SwvuoJ/XpoIIVQhz99z6sEwGABlk0Qj+z4ZJfyuSQdUs+zg7P+Ng==} - '@workflow/cli@4.2.0-beta.71': - resolution: {integrity: sha512-3o9RmaHKRwyniGwbAdzwT3gMxrfHHvJ0DFkcKnAyletO0MGl9rI0dXMbrRT90+5LyCfi7fHrYj6ywO/rPiyh/A==} + '@workflow/cli@4.2.0-beta.73': + resolution: {integrity: sha512-2jW1QX8/Y0C+uBOzvk4KZy8BoOwRgPHCI7Hx7hOrHxEmUrKVSj5jJTEWpwmagJl+gxCcbo1tB8YBD5yYRMzfwA==} hasBin: true '@workflow/core@4.1.0-beta.62': @@ -2608,8 +2609,8 @@ packages: '@opentelemetry/api': optional: true - '@workflow/core@4.2.0-beta.71': - resolution: {integrity: sha512-1w1D88ON1ll54u9GV+pmgefu1Ro5xhCLquOXHN/+1KaG7+YbpvhpcMAvlK9mscEFJl4OSGoWaJD+zP3BtWUC4Q==} + '@workflow/core@4.2.0-beta.73': + resolution: {integrity: sha512-F0DQrw11KO1tG5gIOk493Y+O3OwmI2K31z3/HehCD/HSh7LIgj7gQVwNR78dbkt5+4q3BL8RurRDN35hRqk1tg==} peerDependencies: '@opentelemetry/api': '1' peerDependenciesMeta: @@ -2619,11 +2620,11 @@ packages: '@workflow/errors@4.1.0-beta.17': resolution: {integrity: sha512-ctDx9PrTCAkfsGqs6PgYAMGSaOmHESTMJEdj+d+RU0qEDfXWBZmM586hkf9hXw3jwXnw0VMp9X01jLsnWPyZcA==} - '@workflow/errors@4.1.0-beta.18': - resolution: {integrity: sha512-Ana+xAHp+rKyXe3yues+TOzK+DALLqHTFe7yBEcLjXQZRXof30Wx3BjBaADm2/syIcRpgR3Q2tuASqzrnWmjBg==} + '@workflow/errors@4.1.0-beta.19': + resolution: {integrity: sha512-AEZefVGpant/4eUJixnjGlK3LfyNPWp/C6YpmAsJbPPaFHPggKE7WT185BCMtXJMbpVKF/d/rNa7fxZ3J/yYhw==} - '@workflow/nest@0.0.0-beta.20': - resolution: {integrity: sha512-tBZ/S8lkR1y/0jtmHxrQ4DVi/7BEO+L7I/atkWJFXRrNDitP+i+F9IGmw1Zu5e06zaJA7kJoW9oupaVfESBpQw==} + '@workflow/nest@0.0.0-beta.22': + resolution: {integrity: sha512-8pCwKGSPWscoKfqjca+K/AiI/sUF690iGChmSvMe9PWQKnMVYtcbawaujCf/i0ru+tMmfFO80Vm+iNpMj/YbZQ==} hasBin: true peerDependencies: '@nestjs/common': '>=10.0.0' @@ -2631,31 +2632,31 @@ packages: '@swc/cli': '>=0.4.0' '@swc/core': '>=1.5.0' - '@workflow/next@4.0.1-beta.67': - resolution: {integrity: sha512-2u3aJ4SMgZHi73EBhaR/Hcu4b3T0T+NQkFiq/Ei+lyqgj4vn+HU08rmSUeC7ADgc4RBOisHlFKUvittgMyIPwQ==} + '@workflow/next@4.0.1-beta.69': + resolution: {integrity: sha512-+3As/uSlYhTtHE7r2qFess2HyJI0zVqXu3K7YvKgzNM+td6dl/SF0cbXcUgTy58WeFfPQoGCCumO6LNgC9c1oA==} peerDependencies: next: '>13' peerDependenciesMeta: next: optional: true - '@workflow/nitro@4.0.1-beta.66': - resolution: {integrity: sha512-65tnwGlpUpVPXD/z7aVuN7KJrjdtzkgl54hBycz0vaRZFi1vlTcFWFGG4JOpYfbVJru+EDRuVI3zOURMJU0F4Q==} + '@workflow/nitro@4.0.1-beta.68': + resolution: {integrity: sha512-g5yEEZpncc99fqdXZcQWSC2dvASbhzqLHKB4lOP2da+Sy8i2Fb86hKIwtSTgi/POpr/9WCI3u4F1i8sn3DBhig==} - '@workflow/nuxt@4.0.1-beta.55': - resolution: {integrity: sha512-0QVpF9T5wXiFSOB/0UZCUWlg0ejWEBiNyz/s2mQxDXf7ABog7v8l4IpQ9oNniVMBYWz/KPaLVWc7n8waYRX+xg==} + '@workflow/nuxt@4.0.1-beta.57': + resolution: {integrity: sha512-pTWDevRsscNoklP2R43a/ENUlBU/dBcQWxlvmrP7eTkK6LmRjvl1+S57fKiMcRzlYvhUB8yOAD9CDaZZ2jMecg==} - '@workflow/rollup@4.0.0-beta.28': - resolution: {integrity: sha512-AYKGEX+SJ2YLPFil8qRelniGeFxQUynH0YVUiizZlscIL3j3IgdG1SKCXY6/s5i4ZsAp/bKov4jgwR/HVWlyNA==} + '@workflow/rollup@4.0.0-beta.30': + resolution: {integrity: sha512-ZbJPwo01UyiyzBr6GIv20jYnfXfGm/PZ9yA4ARrkwwZt1X/G1S/J08T33iWYUkXV0RH+6DJUvJioHtn8QbL0DA==} '@workflow/serde@4.1.0-beta.2': resolution: {integrity: sha512-8kkeoQKLDaKXefjV5dbhBj2aErfKp1Mc4pb6tj8144cF+Em5SPbyMbyLCHp+BVrFfFVCBluCtMx+jjvaFVZGww==} - '@workflow/sveltekit@4.0.0-beta.60': - resolution: {integrity: sha512-uxInMVCqPo7bbLdhim8jg15j3oRqncMFLBsr+nm8EpBDJt0/kk3qKdu6uAs+26dzfjOgHGbzljR9TnwI4YBa7A==} + '@workflow/sveltekit@4.0.0-beta.62': + resolution: {integrity: sha512-HetSMA+rh/ZbQTNH55wfSLFEoUhsQpKK7vX6aY35CUwVATiq1Ib8/hgVBM01ZI0HxD+T5HzbZg7wx9dJOJicXw==} - '@workflow/swc-plugin@4.1.0-beta.20': - resolution: {integrity: sha512-sauQ/5Mj1NAbT6f/EiWuvKWgPmq/pGlVAtQ4x3bkaHotHlgVU+HURKXZXHu564YCkIQimHFvcCrLvn9fmhWUCA==} + '@workflow/swc-plugin@4.1.0-beta.21': + resolution: {integrity: sha512-CcZG8T3oxMNils93OTomXT54pMwqH2IPheiZjg4bEz2aQtIQXGyU3ul0NRCDyLFgQa9tb3mgW18yOsOqajr0Tg==} peerDependencies: '@swc/core': 1.15.3 @@ -2667,11 +2668,11 @@ packages: '@workflow/utils@4.1.0-beta.13': resolution: {integrity: sha512-3vVuXZVfLVeJ78MM6D0gNXg6hMZdDYAzmF92p+HxItI0B2Yk1EuDIIUfBXKWwTOKCCuKF4iroZt2u9BFqrs2AQ==} - '@workflow/vite@4.0.0-beta.21': - resolution: {integrity: sha512-BlfM8+voF+5VzkD0fh6JjMlN0if4GI/00yoEGJnI8x65ub99Z53Ou4cV235ABw1ehFYzwj4qalQfvTACSQp7Kw==} + '@workflow/vite@4.0.0-beta.23': + resolution: {integrity: sha512-EM5rDgrkwWN5vAY2YteuL8/bELEv6g2dckTHiEl4SuYNYZK/NLvQV7b57ypMNafWAc2hZ/euplE1fBqsuQEC3Q==} - '@workflow/web@4.1.0-beta.43': - resolution: {integrity: sha512-vWB1ZoWHFDsYZOHW+VFtYTOeHVziZaHTjjSfFxtHHogxQ32+/p5+eR2MtGIR3Fl/QoA4QdrIB0usGV8FXioLxQ==} + '@workflow/web@4.1.0-beta.45': + resolution: {integrity: sha512-ITqHjQMS5QPj0lx4vGdyhASz/IrqKQcgnv97OBiKvnwcWCH+nszmP59LJ/BL9DTb0AR2ugFWh2FlGe1GJxTTZg==} '@workflow/world-local@4.1.0-beta.36': resolution: {integrity: sha512-eOavTINKlpepB4MJyQr0RoUVRnFZM3nP4T+AUMrRjm9qhZvZB5g5TgHBfkrOzdqqOHtuj7dfOccNc76hywZ5Fw==} @@ -2681,8 +2682,8 @@ packages: '@opentelemetry/api': optional: true - '@workflow/world-local@4.1.0-beta.44': - resolution: {integrity: sha512-nDTOiTszaWJijr2TjKIcQu7HMMY9N/GIXVVSkSW1YxevOcMSYvnKpczmcBuc0+zAZMxX2DTqOX/BBgVluO38cQ==} + '@workflow/world-local@4.1.0-beta.46': + resolution: {integrity: sha512-jCDcJdQTDwq4+5BTf3OajUtRuDaXM6yYdrGsA0P4PAnY7grgOW+R1Thd4cW4EHJZYhOQ5bfgrCCCMF8nhAwukw==} peerDependencies: '@opentelemetry/api': '1' peerDependenciesMeta: @@ -2697,16 +2698,16 @@ packages: '@opentelemetry/api': optional: true - '@workflow/world-vercel@4.1.0-beta.44': - resolution: {integrity: sha512-VX+2eK4Jx9Qmo8/u8N1SSKq6AXdbeDnu5TGZkwRVXMITX+V3rksAncxaiypbrZzLs2WzrjtkLgOth9RbHJAM/w==} + '@workflow/world-vercel@4.1.0-beta.45': + resolution: {integrity: sha512-+2u8BtWnOWgdry22zJj9QSgh4s1WrTy9EvAJKx+sFnG24mrVBAW83IvqxpDIXAAd72PTFnEXyGHP4LUIO2KJag==} peerDependencies: '@opentelemetry/api': '1' peerDependenciesMeta: '@opentelemetry/api': optional: true - '@workflow/world@4.1.0-beta.13': - resolution: {integrity: sha512-W5Qub/OUfFtQXSJ3LUGobr2PBPEMd1HFO0J2QfYClvA3Pada4oeSLCzRER5MXkS5DImf7OX2bpaqm4Eqiiu1bg==} + '@workflow/world@4.1.0-beta.14': + resolution: {integrity: sha512-23BC9d7m7DDuGuaLncMHZ/6XFJePsY7Dr2zVecRWpM6NvOmAKV+oiOav/HEBxUCdaccSshSsLRqwdHX9Q9HCZA==} peerDependencies: zod: 4.3.6 @@ -5909,8 +5910,8 @@ packages: wordwrap@1.0.0: resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} - workflow@4.2.0-beta.71: - resolution: {integrity: sha512-8DU1zGgE0tCvrfgMoV67OtBP17/uKOhMHnNSeD3JTXNdM6RhP9XatH2Qpy/ED7eiAhxbWuAh/2k+68pAdB0qmw==} + workflow@4.2.0-beta.73: + resolution: {integrity: sha512-qojoyPIommGOVCj/LHOZEBRJqlSbijLOKDr5yzBokhc7qO2wJAXixVshPH6mOxHJc22KuYKFMlJu+ocqhDKT0A==} hasBin: true peerDependencies: '@opentelemetry/api': '1' @@ -6854,22 +6855,17 @@ snapshots: '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.30 + '@jridgewell/trace-mapping': 0.3.31 '@jridgewell/remapping@2.3.5': dependencies: '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.30 + '@jridgewell/trace-mapping': 0.3.31 '@jridgewell/resolve-uri@3.1.2': {} '@jridgewell/sourcemap-codec@1.5.5': {} - '@jridgewell/trace-mapping@0.3.30': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping@0.3.31': dependencies: '@jridgewell/resolve-uri': 3.1.2 @@ -7065,7 +7061,7 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 - '@nuxt/kit@4.3.1': + '@nuxt/kit@4.4.2': dependencies: c12: 3.3.3 consola: 3.4.2 @@ -7107,7 +7103,7 @@ snapshots: is-wsl: 2.2.0 lilconfig: 3.1.3 minimatch: 10.2.4 - semver: 7.7.3 + semver: 7.7.4 string-width: 4.2.3 supports-color: 8.1.1 tinyglobby: 0.2.15 @@ -7647,7 +7643,7 @@ snapshots: commander: 8.3.0 minimatch: 9.0.5 piscina: 4.9.2 - semver: 7.7.3 + semver: 7.7.4 slash: 3.0.0 source-map: 0.7.6 tinyglobby: 0.2.15 @@ -7997,13 +7993,13 @@ snapshots: loupe: 3.2.1 tinyrainbow: 2.0.0 - '@workflow/astro@4.0.0-beta.45(@opentelemetry/api@1.9.0)': + '@workflow/astro@4.0.0-beta.47(@opentelemetry/api@1.9.0)': dependencies: '@swc/core': 1.15.3 - '@workflow/builders': 4.0.1-beta.62(@opentelemetry/api@1.9.0) - '@workflow/rollup': 4.0.0-beta.28(@opentelemetry/api@1.9.0) - '@workflow/swc-plugin': 4.1.0-beta.20(@swc/core@1.15.3) - '@workflow/vite': 4.0.0-beta.21(@opentelemetry/api@1.9.0) + '@workflow/builders': 4.0.1-beta.64(@opentelemetry/api@1.9.0) + '@workflow/rollup': 4.0.0-beta.30(@opentelemetry/api@1.9.0) + '@workflow/swc-plugin': 4.1.0-beta.21(@swc/core@1.15.3) + '@workflow/vite': 4.0.0-beta.23(@opentelemetry/api@1.9.0) exsolve: 1.0.8 pathe: 2.0.3 transitivePeerDependencies: @@ -8012,12 +8008,12 @@ snapshots: - aws-crt - supports-color - '@workflow/builders@4.0.1-beta.62(@opentelemetry/api@1.9.0)': + '@workflow/builders@4.0.1-beta.64(@opentelemetry/api@1.9.0)': dependencies: '@swc/core': 1.15.3 - '@workflow/core': 4.2.0-beta.71(@opentelemetry/api@1.9.0) - '@workflow/errors': 4.1.0-beta.18 - '@workflow/swc-plugin': 4.1.0-beta.20(@swc/core@1.15.3) + '@workflow/core': 4.2.0-beta.73(@opentelemetry/api@1.9.0) + '@workflow/errors': 4.1.0-beta.19 + '@workflow/swc-plugin': 4.1.0-beta.21(@swc/core@1.15.3) '@workflow/utils': 4.1.0-beta.13 builtin-modules: 5.0.0 chalk: 5.6.2 @@ -8032,21 +8028,21 @@ snapshots: - aws-crt - supports-color - '@workflow/cli@4.2.0-beta.71(@opentelemetry/api@1.9.0)': + '@workflow/cli@4.2.0-beta.73(@opentelemetry/api@1.9.0)': dependencies: '@oclif/core': 4.8.1 '@oclif/plugin-help': 6.2.37 '@swc/core': 1.15.3 '@vercel/cli-auth': 0.0.1 - '@workflow/builders': 4.0.1-beta.62(@opentelemetry/api@1.9.0) - '@workflow/core': 4.2.0-beta.71(@opentelemetry/api@1.9.0) - '@workflow/errors': 4.1.0-beta.18 - '@workflow/swc-plugin': 4.1.0-beta.20(@swc/core@1.15.3) + '@workflow/builders': 4.0.1-beta.64(@opentelemetry/api@1.9.0) + '@workflow/core': 4.2.0-beta.73(@opentelemetry/api@1.9.0) + '@workflow/errors': 4.1.0-beta.19 + '@workflow/swc-plugin': 4.1.0-beta.21(@swc/core@1.15.3) '@workflow/utils': 4.1.0-beta.13 - '@workflow/web': 4.1.0-beta.43 - '@workflow/world': 4.1.0-beta.13(zod@4.3.6) - '@workflow/world-local': 4.1.0-beta.44(@opentelemetry/api@1.9.0) - '@workflow/world-vercel': 4.1.0-beta.44(@opentelemetry/api@1.9.0) + '@workflow/web': 4.1.0-beta.45 + '@workflow/world': 4.1.0-beta.14(zod@4.3.6) + '@workflow/world-local': 4.1.0-beta.46(@opentelemetry/api@1.9.0) + '@workflow/world-vercel': 4.1.0-beta.45(@opentelemetry/api@1.9.0) boxen: 8.0.1 builtin-modules: 5.0.0 chalk: 5.6.2 @@ -8096,19 +8092,19 @@ snapshots: - aws-crt - supports-color - '@workflow/core@4.2.0-beta.71(@opentelemetry/api@1.9.0)': + '@workflow/core@4.2.0-beta.73(@opentelemetry/api@1.9.0)': dependencies: '@aws-sdk/credential-provider-web-identity': 3.972.13 '@jridgewell/trace-mapping': 0.3.31 '@standard-schema/spec': 1.0.0 '@types/ms': 2.1.0 '@vercel/functions': 3.4.3(@aws-sdk/credential-provider-web-identity@3.972.13) - '@workflow/errors': 4.1.0-beta.18 + '@workflow/errors': 4.1.0-beta.19 '@workflow/serde': 4.1.0-beta.2 '@workflow/utils': 4.1.0-beta.13 - '@workflow/world': 4.1.0-beta.13(zod@4.3.6) - '@workflow/world-local': 4.1.0-beta.44(@opentelemetry/api@1.9.0) - '@workflow/world-vercel': 4.1.0-beta.44(@opentelemetry/api@1.9.0) + '@workflow/world': 4.1.0-beta.14(zod@4.3.6) + '@workflow/world-local': 4.1.0-beta.46(@opentelemetry/api@1.9.0) + '@workflow/world-vercel': 4.1.0-beta.45(@opentelemetry/api@1.9.0) debug: 4.4.3(supports-color@8.1.1) devalue: 5.6.3 ms: 2.1.3 @@ -8127,19 +8123,19 @@ snapshots: '@workflow/utils': 4.1.0-beta.13 ms: 2.1.3 - '@workflow/errors@4.1.0-beta.18': + '@workflow/errors@4.1.0-beta.19': dependencies: '@workflow/utils': 4.1.0-beta.13 ms: 2.1.3 - '@workflow/nest@0.0.0-beta.20(@nestjs/common@11.1.17(reflect-metadata@0.2.2)(rxjs@6.6.7))(@nestjs/core@11.1.17(@nestjs/common@11.1.17(reflect-metadata@0.2.2)(rxjs@6.6.7))(reflect-metadata@0.2.2)(rxjs@6.6.7))(@opentelemetry/api@1.9.0)(@swc/cli@0.8.0(@swc/core@1.15.3)(chokidar@5.0.0))(@swc/core@1.15.3)': + '@workflow/nest@0.0.0-beta.22(@nestjs/common@11.1.17(reflect-metadata@0.2.2)(rxjs@6.6.7))(@nestjs/core@11.1.17(@nestjs/common@11.1.17(reflect-metadata@0.2.2)(rxjs@6.6.7))(reflect-metadata@0.2.2)(rxjs@6.6.7))(@opentelemetry/api@1.9.0)(@swc/cli@0.8.0(@swc/core@1.15.3)(chokidar@5.0.0))(@swc/core@1.15.3)': dependencies: '@nestjs/common': 11.1.17(reflect-metadata@0.2.2)(rxjs@6.6.7) '@nestjs/core': 11.1.17(@nestjs/common@11.1.17(reflect-metadata@0.2.2)(rxjs@6.6.7))(reflect-metadata@0.2.2)(rxjs@6.6.7) '@swc/cli': 0.8.0(@swc/core@1.15.3)(chokidar@5.0.0) '@swc/core': 1.15.3 - '@workflow/builders': 4.0.1-beta.62(@opentelemetry/api@1.9.0) - '@workflow/swc-plugin': 4.1.0-beta.20(@swc/core@1.15.3) + '@workflow/builders': 4.0.1-beta.64(@opentelemetry/api@1.9.0) + '@workflow/swc-plugin': 4.1.0-beta.21(@swc/core@1.15.3) pathe: 2.0.3 transitivePeerDependencies: - '@opentelemetry/api' @@ -8147,12 +8143,12 @@ snapshots: - aws-crt - supports-color - '@workflow/next@4.0.1-beta.67(@opentelemetry/api@1.9.0)(next@16.0.10(@opentelemetry/api@1.9.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': + '@workflow/next@4.0.1-beta.69(@opentelemetry/api@1.9.0)(next@16.0.10(@opentelemetry/api@1.9.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': dependencies: '@swc/core': 1.15.3 - '@workflow/builders': 4.0.1-beta.62(@opentelemetry/api@1.9.0) - '@workflow/core': 4.2.0-beta.71(@opentelemetry/api@1.9.0) - '@workflow/swc-plugin': 4.1.0-beta.20(@swc/core@1.15.3) + '@workflow/builders': 4.0.1-beta.64(@opentelemetry/api@1.9.0) + '@workflow/core': 4.2.0-beta.73(@opentelemetry/api@1.9.0) + '@workflow/swc-plugin': 4.1.0-beta.21(@swc/core@1.15.3) semver: 7.7.4 watchpack: 2.5.1 optionalDependencies: @@ -8163,14 +8159,14 @@ snapshots: - aws-crt - supports-color - '@workflow/nitro@4.0.1-beta.66(@opentelemetry/api@1.9.0)': + '@workflow/nitro@4.0.1-beta.68(@opentelemetry/api@1.9.0)': dependencies: '@swc/core': 1.15.3 - '@workflow/builders': 4.0.1-beta.62(@opentelemetry/api@1.9.0) - '@workflow/core': 4.2.0-beta.71(@opentelemetry/api@1.9.0) - '@workflow/rollup': 4.0.0-beta.28(@opentelemetry/api@1.9.0) - '@workflow/swc-plugin': 4.1.0-beta.20(@swc/core@1.15.3) - '@workflow/vite': 4.0.0-beta.21(@opentelemetry/api@1.9.0) + '@workflow/builders': 4.0.1-beta.64(@opentelemetry/api@1.9.0) + '@workflow/core': 4.2.0-beta.73(@opentelemetry/api@1.9.0) + '@workflow/rollup': 4.0.0-beta.30(@opentelemetry/api@1.9.0) + '@workflow/swc-plugin': 4.1.0-beta.21(@swc/core@1.15.3) + '@workflow/vite': 4.0.0-beta.23(@opentelemetry/api@1.9.0) exsolve: 1.0.8 pathe: 2.0.3 transitivePeerDependencies: @@ -8179,10 +8175,10 @@ snapshots: - aws-crt - supports-color - '@workflow/nuxt@4.0.1-beta.55(@opentelemetry/api@1.9.0)': + '@workflow/nuxt@4.0.1-beta.57(@opentelemetry/api@1.9.0)': dependencies: - '@nuxt/kit': 4.3.1 - '@workflow/nitro': 4.0.1-beta.66(@opentelemetry/api@1.9.0) + '@nuxt/kit': 4.4.2 + '@workflow/nitro': 4.0.1-beta.68(@opentelemetry/api@1.9.0) transitivePeerDependencies: - '@opentelemetry/api' - '@swc/helpers' @@ -8190,11 +8186,11 @@ snapshots: - magicast - supports-color - '@workflow/rollup@4.0.0-beta.28(@opentelemetry/api@1.9.0)': + '@workflow/rollup@4.0.0-beta.30(@opentelemetry/api@1.9.0)': dependencies: '@swc/core': 1.15.3 - '@workflow/builders': 4.0.1-beta.62(@opentelemetry/api@1.9.0) - '@workflow/swc-plugin': 4.1.0-beta.20(@swc/core@1.15.3) + '@workflow/builders': 4.0.1-beta.64(@opentelemetry/api@1.9.0) + '@workflow/swc-plugin': 4.1.0-beta.21(@swc/core@1.15.3) exsolve: 1.0.7 transitivePeerDependencies: - '@opentelemetry/api' @@ -8204,13 +8200,13 @@ snapshots: '@workflow/serde@4.1.0-beta.2': {} - '@workflow/sveltekit@4.0.0-beta.60(@opentelemetry/api@1.9.0)': + '@workflow/sveltekit@4.0.0-beta.62(@opentelemetry/api@1.9.0)': dependencies: '@swc/core': 1.15.3 - '@workflow/builders': 4.0.1-beta.62(@opentelemetry/api@1.9.0) - '@workflow/rollup': 4.0.0-beta.28(@opentelemetry/api@1.9.0) - '@workflow/swc-plugin': 4.1.0-beta.20(@swc/core@1.15.3) - '@workflow/vite': 4.0.0-beta.21(@opentelemetry/api@1.9.0) + '@workflow/builders': 4.0.1-beta.64(@opentelemetry/api@1.9.0) + '@workflow/rollup': 4.0.0-beta.30(@opentelemetry/api@1.9.0) + '@workflow/swc-plugin': 4.1.0-beta.21(@swc/core@1.15.3) + '@workflow/vite': 4.0.0-beta.23(@opentelemetry/api@1.9.0) exsolve: 1.0.8 fs-extra: 11.3.4 pathe: 2.0.3 @@ -8220,7 +8216,7 @@ snapshots: - aws-crt - supports-color - '@workflow/swc-plugin@4.1.0-beta.20(@swc/core@1.15.3)': + '@workflow/swc-plugin@4.1.0-beta.21(@swc/core@1.15.3)': dependencies: '@swc/core': 1.15.3 @@ -8232,16 +8228,16 @@ snapshots: dependencies: ms: 2.1.3 - '@workflow/vite@4.0.0-beta.21(@opentelemetry/api@1.9.0)': + '@workflow/vite@4.0.0-beta.23(@opentelemetry/api@1.9.0)': dependencies: - '@workflow/builders': 4.0.1-beta.62(@opentelemetry/api@1.9.0) + '@workflow/builders': 4.0.1-beta.64(@opentelemetry/api@1.9.0) transitivePeerDependencies: - '@opentelemetry/api' - '@swc/helpers' - aws-crt - supports-color - '@workflow/web@4.1.0-beta.43': + '@workflow/web@4.1.0-beta.45': dependencies: express: 4.22.1 transitivePeerDependencies: @@ -8260,12 +8256,12 @@ snapshots: optionalDependencies: '@opentelemetry/api': 1.9.0 - '@workflow/world-local@4.1.0-beta.44(@opentelemetry/api@1.9.0)': + '@workflow/world-local@4.1.0-beta.46(@opentelemetry/api@1.9.0)': dependencies: '@vercel/queue': 0.1.4 - '@workflow/errors': 4.1.0-beta.18 + '@workflow/errors': 4.1.0-beta.19 '@workflow/utils': 4.1.0-beta.13 - '@workflow/world': 4.1.0-beta.13(zod@4.3.6) + '@workflow/world': 4.1.0-beta.14(zod@4.3.6) async-sema: 3.1.1 ulid: 3.0.1 undici: 7.22.0 @@ -8285,19 +8281,19 @@ snapshots: optionalDependencies: '@opentelemetry/api': 1.9.0 - '@workflow/world-vercel@4.1.0-beta.44(@opentelemetry/api@1.9.0)': + '@workflow/world-vercel@4.1.0-beta.45(@opentelemetry/api@1.9.0)': dependencies: '@vercel/oidc': 3.2.0 '@vercel/queue': 0.1.4 - '@workflow/errors': 4.1.0-beta.18 - '@workflow/world': 4.1.0-beta.13(zod@4.3.6) + '@workflow/errors': 4.1.0-beta.19 + '@workflow/world': 4.1.0-beta.14(zod@4.3.6) cbor-x: 1.6.0 undici: 7.22.0 zod: 4.3.6 optionalDependencies: '@opentelemetry/api': 1.9.0 - '@workflow/world@4.1.0-beta.13(zod@4.3.6)': + '@workflow/world@4.1.0-beta.14(zod@4.3.6)': dependencies: ulid: 3.0.1 zod: 4.3.6 @@ -8528,7 +8524,7 @@ snapshots: bin-version-check@5.1.0: dependencies: bin-version: 6.0.0 - semver: 7.7.3 + semver: 7.7.4 semver-truncate: 3.0.0 bin-version@6.0.0: @@ -11050,7 +11046,7 @@ snapshots: semver-truncate@3.0.0: dependencies: - semver: 7.7.3 + semver: 7.7.4 semver@5.7.2: {} @@ -11093,7 +11089,7 @@ snapshots: dependencies: color: 4.2.3 detect-libc: 2.0.4 - semver: 7.7.3 + semver: 7.7.4 optionalDependencies: '@img/sharp-darwin-arm64': 0.34.3 '@img/sharp-darwin-x64': 0.34.3 @@ -11610,7 +11606,7 @@ snapshots: unctx@2.5.0: dependencies: - acorn: 8.15.0 + acorn: 8.16.0 estree-walker: 3.0.3 magic-string: 0.30.21 unplugin: 2.3.11 @@ -11667,7 +11663,7 @@ snapshots: unplugin@2.3.11: dependencies: '@jridgewell/remapping': 2.3.5 - acorn: 8.15.0 + acorn: 8.16.0 picomatch: 4.0.3 webpack-virtual-modules: 0.6.2 @@ -11916,19 +11912,20 @@ snapshots: wordwrap@1.0.0: {} - workflow@4.2.0-beta.71(@nestjs/common@11.1.17(reflect-metadata@0.2.2)(rxjs@6.6.7))(@nestjs/core@11.1.17(@nestjs/common@11.1.17(reflect-metadata@0.2.2)(rxjs@6.6.7))(reflect-metadata@0.2.2)(rxjs@6.6.7))(@opentelemetry/api@1.9.0)(@swc/cli@0.8.0(@swc/core@1.15.3)(chokidar@5.0.0))(@swc/core@1.15.3)(next@16.0.10(@opentelemetry/api@1.9.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.8.3): - dependencies: - '@workflow/astro': 4.0.0-beta.45(@opentelemetry/api@1.9.0) - '@workflow/cli': 4.2.0-beta.71(@opentelemetry/api@1.9.0) - '@workflow/core': 4.2.0-beta.71(@opentelemetry/api@1.9.0) - '@workflow/errors': 4.1.0-beta.18 - '@workflow/nest': 0.0.0-beta.20(@nestjs/common@11.1.17(reflect-metadata@0.2.2)(rxjs@6.6.7))(@nestjs/core@11.1.17(@nestjs/common@11.1.17(reflect-metadata@0.2.2)(rxjs@6.6.7))(reflect-metadata@0.2.2)(rxjs@6.6.7))(@opentelemetry/api@1.9.0)(@swc/cli@0.8.0(@swc/core@1.15.3)(chokidar@5.0.0))(@swc/core@1.15.3) - '@workflow/next': 4.0.1-beta.67(@opentelemetry/api@1.9.0)(next@16.0.10(@opentelemetry/api@1.9.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) - '@workflow/nitro': 4.0.1-beta.66(@opentelemetry/api@1.9.0) - '@workflow/nuxt': 4.0.1-beta.55(@opentelemetry/api@1.9.0) - '@workflow/rollup': 4.0.0-beta.28(@opentelemetry/api@1.9.0) - '@workflow/sveltekit': 4.0.0-beta.60(@opentelemetry/api@1.9.0) + workflow@4.2.0-beta.73(@nestjs/common@11.1.17(reflect-metadata@0.2.2)(rxjs@6.6.7))(@nestjs/core@11.1.17(@nestjs/common@11.1.17(reflect-metadata@0.2.2)(rxjs@6.6.7))(reflect-metadata@0.2.2)(rxjs@6.6.7))(@opentelemetry/api@1.9.0)(@swc/cli@0.8.0(@swc/core@1.15.3)(chokidar@5.0.0))(@swc/core@1.15.3)(next@16.0.10(@opentelemetry/api@1.9.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.8.3): + dependencies: + '@workflow/astro': 4.0.0-beta.47(@opentelemetry/api@1.9.0) + '@workflow/cli': 4.2.0-beta.73(@opentelemetry/api@1.9.0) + '@workflow/core': 4.2.0-beta.73(@opentelemetry/api@1.9.0) + '@workflow/errors': 4.1.0-beta.19 + '@workflow/nest': 0.0.0-beta.22(@nestjs/common@11.1.17(reflect-metadata@0.2.2)(rxjs@6.6.7))(@nestjs/core@11.1.17(@nestjs/common@11.1.17(reflect-metadata@0.2.2)(rxjs@6.6.7))(reflect-metadata@0.2.2)(rxjs@6.6.7))(@opentelemetry/api@1.9.0)(@swc/cli@0.8.0(@swc/core@1.15.3)(chokidar@5.0.0))(@swc/core@1.15.3) + '@workflow/next': 4.0.1-beta.69(@opentelemetry/api@1.9.0)(next@16.0.10(@opentelemetry/api@1.9.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) + '@workflow/nitro': 4.0.1-beta.68(@opentelemetry/api@1.9.0) + '@workflow/nuxt': 4.0.1-beta.57(@opentelemetry/api@1.9.0) + '@workflow/rollup': 4.0.0-beta.30(@opentelemetry/api@1.9.0) + '@workflow/sveltekit': 4.0.0-beta.62(@opentelemetry/api@1.9.0) '@workflow/typescript-plugin': 4.0.1-beta.5(typescript@5.8.3) + '@workflow/utils': 4.1.0-beta.13 ms: 2.1.3 optionalDependencies: '@opentelemetry/api': 1.9.0