@skaile/provider-vercel-sandbox 0.1.0-beta.0 → 0.1.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/dist/index.js +17 -20
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @skaile/provider-vercel-sandbox
|
|
2
2
|
|
|
3
|
+
## 0.1.0-beta.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`ce3f33f`](https://github.com/skaile-ai/workspaces/commit/ce3f33f5b85f81d1c80689a99a8e63cf0c2afc07) Thanks [@mortegro](https://github.com/mortegro)! - Fix deploy-handle readiness timeout + dedupe deploy-target helpers.
|
|
8
|
+
|
|
9
|
+
- **Fix:** `DeployHandle.waitReady(timeoutMs)` silently ignored its `timeoutMs`
|
|
10
|
+
argument in the fly / k8s / vercel-sandbox targets, always using a hard-coded
|
|
11
|
+
internal deadline. The caller's timeout is now honored.
|
|
12
|
+
- **Fix (`@skaile/provider-fly`):** `deleteMachine` swallowed _all_ errors while
|
|
13
|
+
only intending to ignore a 404, so `stop()` could falsely report success on a
|
|
14
|
+
still-running (still-billing) machine. Non-404 errors now propagate.
|
|
15
|
+
- **Added (`@skaile/workspaces/plugin-registry`):** shared deploy helpers —
|
|
16
|
+
`buildStrategySchema` / `BuildStrategy`, abort-aware `sleep`, generic
|
|
17
|
+
`pollUntil`, and the `makeDeployHandle` factory — replacing the per-provider
|
|
18
|
+
copies of the sleep loop, handle wrapper, and build-strategy enum.
|
|
19
|
+
|
|
3
20
|
## 0.1.0-beta.0
|
|
4
21
|
|
|
5
22
|
### Minor Changes
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
// src/target.ts
|
|
2
|
+
import {
|
|
3
|
+
buildStrategySchema,
|
|
4
|
+
makeDeployHandle
|
|
5
|
+
} from "@skaile/workspaces/plugin-registry";
|
|
2
6
|
import * as z from "zod";
|
|
3
7
|
|
|
4
8
|
// src/sdk-types.ts
|
|
@@ -20,38 +24,31 @@ var vercelConfigSchema = z.object({
|
|
|
20
24
|
runtime: z.string().default("node22"),
|
|
21
25
|
port: z.number().int().positive().default(8080),
|
|
22
26
|
timeout: z.number().int().positive().default(3e5),
|
|
23
|
-
buildStrategy:
|
|
27
|
+
buildStrategy: buildStrategySchema.default("remote")
|
|
24
28
|
}).strict();
|
|
25
29
|
var vercelPayloadSchema = z.object({
|
|
26
30
|
sandboxId: z.string()
|
|
27
31
|
});
|
|
28
32
|
function buildHandle(sandbox, config, ctx, initialState) {
|
|
29
|
-
let state = initialState;
|
|
30
33
|
let stopped = false;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
wsUrl,
|
|
34
|
-
|
|
35
|
-
get state() {
|
|
36
|
-
return state;
|
|
37
|
-
},
|
|
34
|
+
return makeDeployHandle({
|
|
35
|
+
// Vercel exposes the sandbox over an https domain; swap to wss for the WS URL.
|
|
36
|
+
wsUrl: sandbox.domain(config.port).replace(/^http/, "ws"),
|
|
37
|
+
ctx,
|
|
38
38
|
payload: { sandboxId: sandbox.sandboxId },
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
initialState,
|
|
40
|
+
defaultReadyTimeoutMs: config.timeout,
|
|
41
|
+
// `Sandbox.create` resolves once the sandbox is up, so readiness is immediate.
|
|
42
|
+
ready: async () => {
|
|
42
43
|
},
|
|
43
|
-
async
|
|
44
|
-
|
|
45
|
-
},
|
|
46
|
-
async stop() {
|
|
47
|
-
state = "stopping";
|
|
44
|
+
health: async () => stopped ? { healthy: false, detail: `sandbox ${sandbox.sandboxId} stopped` } : { healthy: true },
|
|
45
|
+
stop: async () => {
|
|
48
46
|
if (!stopped) {
|
|
49
47
|
await sandbox.stop();
|
|
50
48
|
stopped = true;
|
|
51
49
|
}
|
|
52
|
-
state = "stopped";
|
|
53
50
|
}
|
|
54
|
-
};
|
|
51
|
+
});
|
|
55
52
|
}
|
|
56
53
|
function makeVercelSandboxDeployTarget(opts = {}) {
|
|
57
54
|
const loadSdk = opts.loadSdk ?? defaultSdkLoader;
|
|
@@ -82,7 +79,7 @@ function makeVercelSandboxDeployTarget(opts = {}) {
|
|
|
82
79
|
token: ctx.env.VERCEL_TOKEN
|
|
83
80
|
});
|
|
84
81
|
ctx.log.info("re-attached to vercel sandbox", { sandboxId: payload.sandboxId });
|
|
85
|
-
return buildHandle(sandbox, { port: 8080 }, ctx, "ready");
|
|
82
|
+
return buildHandle(sandbox, { port: 8080, timeout: 3e5 }, ctx, "ready");
|
|
86
83
|
}
|
|
87
84
|
};
|
|
88
85
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/target.ts","../src/sdk-types.ts","../src/index.ts"],"sourcesContent":["/**\n * `vercelSandboxDeployTarget` — deploy a workspace into a Vercel Sandbox and\n * reach it over the sandbox's public TLS domain. `tlsTermination: \"edge\"`.\n *\n * `@vercel/sandbox` is an *optional* peer dependency, lazy-loaded inside\n * `create()`/`restore()` via an injectable loader (`opts.loadSdk`, default\n * `defaultSdkLoader`). This keeps the package building standalone offline; the\n * test injects a fake loader so it never imports the real SDK.\n */\n\nimport type
|
|
1
|
+
{"version":3,"sources":["../src/target.ts","../src/sdk-types.ts","../src/index.ts"],"sourcesContent":["/**\n * `vercelSandboxDeployTarget` — deploy a workspace into a Vercel Sandbox and\n * reach it over the sandbox's public TLS domain. `tlsTermination: \"edge\"`.\n *\n * `@vercel/sandbox` is an *optional* peer dependency, lazy-loaded inside\n * `create()`/`restore()` via an injectable loader (`opts.loadSdk`, default\n * `defaultSdkLoader`). This keeps the package building standalone offline; the\n * test injects a fake loader so it never imports the real SDK.\n */\n\nimport {\n buildStrategySchema,\n type DeployContext,\n type DeployHandle,\n type DeployTarget,\n makeDeployHandle,\n} from \"@skaile/workspaces/plugin-registry\";\nimport * as z from \"zod\";\nimport { defaultSdkLoader, type SdkLoader, type VercelSandbox } from \"./sdk-types.js\";\n\nconst vercelConfigSchema = z\n .object({\n token: z.string().optional(),\n teamId: z.string().optional(),\n projectId: z.string().optional(),\n runtime: z.string().default(\"node22\"),\n port: z.number().int().positive().default(8080),\n timeout: z.number().int().positive().default(300_000),\n buildStrategy: buildStrategySchema.default(\"remote\"),\n })\n .strict();\n\ntype VercelConfig = z.infer<typeof vercelConfigSchema>;\n\nconst vercelPayloadSchema = z.object({\n sandboxId: z.string(),\n});\n\ntype VercelPayload = z.infer<typeof vercelPayloadSchema>;\n\n/** Injectable seams so tests never load the real `@vercel/sandbox`. */\nexport interface VercelSandboxTargetOptions {\n loadSdk?: SdkLoader;\n}\n\nfunction buildHandle(\n sandbox: VercelSandbox,\n config: Pick<VercelConfig, \"port\" | \"timeout\">,\n ctx: DeployContext,\n initialState: DeployHandle[\"state\"],\n): DeployHandle<VercelPayload> {\n let stopped = false;\n return makeDeployHandle<VercelPayload>({\n // Vercel exposes the sandbox over an https domain; swap to wss for the WS URL.\n wsUrl: sandbox.domain(config.port).replace(/^http/, \"ws\"),\n ctx,\n payload: { sandboxId: sandbox.sandboxId },\n initialState,\n defaultReadyTimeoutMs: config.timeout,\n // `Sandbox.create` resolves once the sandbox is up, so readiness is immediate.\n ready: async () => {},\n health: async () =>\n stopped ? { healthy: false, detail: `sandbox ${sandbox.sandboxId} stopped` } : { healthy: true },\n stop: async () => {\n if (!stopped) {\n await sandbox.stop();\n stopped = true;\n }\n },\n });\n}\n\n/** Build the Vercel Sandbox deploy target with an optional injected SDK loader. */\nexport function makeVercelSandboxDeployTarget(\n opts: VercelSandboxTargetOptions = {},\n): DeployTarget<VercelConfig, VercelPayload> {\n const loadSdk = opts.loadSdk ?? defaultSdkLoader;\n\n return {\n id: \"vercel-sandbox\",\n displayName: \"Vercel Sandbox\",\n apiVersion: 1,\n tlsTermination: \"edge\",\n configSchema: vercelConfigSchema as unknown as z.ZodType<VercelConfig>,\n payloadSchema: vercelPayloadSchema,\n\n async create(config, ctx) {\n const { Sandbox } = await loadSdk();\n const sandbox = await Sandbox.create({\n token: config.token,\n teamId: config.teamId,\n projectId: config.projectId,\n runtime: config.runtime,\n timeout: config.timeout,\n ports: [config.port],\n });\n ctx.log.info(\"vercel sandbox created\", { sandboxId: sandbox.sandboxId });\n return buildHandle(sandbox, config, ctx, \"starting\");\n },\n\n async restore(payload, ctx) {\n const { Sandbox } = await loadSdk();\n const sandbox = await Sandbox.get({\n sandboxId: payload.sandboxId,\n token: ctx.env.VERCEL_TOKEN,\n });\n ctx.log.info(\"re-attached to vercel sandbox\", { sandboxId: payload.sandboxId });\n return buildHandle(sandbox, { port: 8080, timeout: 300_000 }, ctx, \"ready\");\n },\n };\n}\n\n/** Default Vercel Sandbox deploy target registered by `register()`. */\nexport const vercelSandboxDeployTarget = makeVercelSandboxDeployTarget();\n","/**\n * Minimal local interface for the `@vercel/sandbox` SDK — only the members this\n * provider actually calls.\n *\n * We deliberately do NOT import the real package's types at compile time: the\n * SDK is an *optional* peer dependency, lazy-loaded via a string-literal dynamic\n * `import()` at runtime. Typing against this minimal surface keeps the package\n * building + typechecking standalone (offline-safe), while the user's project\n * supplies the real SDK at runtime.\n */\n\n/** A live Vercel Sandbox instance (subset). */\nexport interface VercelSandbox {\n readonly sandboxId: string;\n /** Public URL for a given exposed port. */\n domain(port: number): string;\n stop(): Promise<void>;\n}\n\n/** The `@vercel/sandbox` module surface we depend on. */\nexport interface VercelSandboxModule {\n Sandbox: {\n create(opts: {\n token?: string;\n teamId?: string;\n projectId?: string;\n runtime?: string;\n timeout?: number;\n ports?: number[];\n }): Promise<VercelSandbox>;\n get(opts: { sandboxId: string; token?: string }): Promise<VercelSandbox>;\n };\n}\n\n/** Loader seam: returns the SDK module. Default does a real dynamic import. */\nexport type SdkLoader = () => Promise<VercelSandboxModule>;\n\n/**\n * Default loader: lazy `import(\"@vercel/sandbox\")`. The string literal keeps\n * bundlers from eagerly resolving the optional peer; it is only evaluated when\n * `create()`/`restore()` actually run.\n */\nexport const defaultSdkLoader: SdkLoader = async () => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const mod = (await import(\"@vercel/sandbox\" as string)) as unknown as VercelSandboxModule;\n if (!mod?.Sandbox) {\n throw new Error(\n \"@vercel/sandbox is not installed. Run `skaile plugin install @skaile/provider-vercel-sandbox` and add @vercel/sandbox to your project.\",\n );\n }\n return mod;\n};\n","/**\n * `@skaile/provider-vercel-sandbox` — Vercel Sandbox deploy target for\n * `@skaile/workspaces`.\n *\n * Requires the optional peer `@vercel/sandbox` to be installed in the host\n * project (lazy-loaded at runtime). Install via\n * `skaile plugin install @skaile/provider-vercel-sandbox`.\n */\n\nimport type { PluginRegistry } from \"@skaile/workspaces/plugin-registry\";\nimport { vercelSandboxDeployTarget } from \"./target.js\";\n\nexport {\n makeVercelSandboxDeployTarget,\n vercelSandboxDeployTarget,\n} from \"./target.js\";\nexport type { VercelSandboxTargetOptions } from \"./target.js\";\nexport type { SdkLoader, VercelSandbox, VercelSandboxModule } from \"./sdk-types.js\";\n\n/** Register this plugin's deploy target with a registry. */\nexport function register(registry: PluginRegistry): void {\n registry.register(\"deployTarget\", vercelSandboxDeployTarget);\n}\n"],"mappings":";AAUA;AAAA,EACE;AAAA,EAIA;AAAA,OACK;AACP,YAAY,OAAO;;;ACyBZ,IAAM,mBAA8B,YAAY;AAErD,QAAM,MAAO,MAAM,OAAO,iBAA2B;AACrD,MAAI,CAAC,KAAK,SAAS;AACjB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;;;AD/BA,IAAM,qBACH,SAAO;AAAA,EACN,OAAS,SAAO,EAAE,SAAS;AAAA,EAC3B,QAAU,SAAO,EAAE,SAAS;AAAA,EAC5B,WAAa,SAAO,EAAE,SAAS;AAAA,EAC/B,SAAW,SAAO,EAAE,QAAQ,QAAQ;AAAA,EACpC,MAAQ,SAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,IAAI;AAAA,EAC9C,SAAW,SAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,GAAO;AAAA,EACpD,eAAe,oBAAoB,QAAQ,QAAQ;AACrD,CAAC,EACA,OAAO;AAIV,IAAM,sBAAwB,SAAO;AAAA,EACnC,WAAa,SAAO;AACtB,CAAC;AASD,SAAS,YACP,SACA,QACA,KACA,cAC6B;AAC7B,MAAI,UAAU;AACd,SAAO,iBAAgC;AAAA;AAAA,IAErC,OAAO,QAAQ,OAAO,OAAO,IAAI,EAAE,QAAQ,SAAS,IAAI;AAAA,IACxD;AAAA,IACA,SAAS,EAAE,WAAW,QAAQ,UAAU;AAAA,IACxC;AAAA,IACA,uBAAuB,OAAO;AAAA;AAAA,IAE9B,OAAO,YAAY;AAAA,IAAC;AAAA,IACpB,QAAQ,YACN,UAAU,EAAE,SAAS,OAAO,QAAQ,WAAW,QAAQ,SAAS,WAAW,IAAI,EAAE,SAAS,KAAK;AAAA,IACjG,MAAM,YAAY;AAChB,UAAI,CAAC,SAAS;AACZ,cAAM,QAAQ,KAAK;AACnB,kBAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAGO,SAAS,8BACd,OAAmC,CAAC,GACO;AAC3C,QAAM,UAAU,KAAK,WAAW;AAEhC,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,eAAe;AAAA,IAEf,MAAM,OAAO,QAAQ,KAAK;AACxB,YAAM,EAAE,QAAQ,IAAI,MAAM,QAAQ;AAClC,YAAM,UAAU,MAAM,QAAQ,OAAO;AAAA,QACnC,OAAO,OAAO;AAAA,QACd,QAAQ,OAAO;AAAA,QACf,WAAW,OAAO;AAAA,QAClB,SAAS,OAAO;AAAA,QAChB,SAAS,OAAO;AAAA,QAChB,OAAO,CAAC,OAAO,IAAI;AAAA,MACrB,CAAC;AACD,UAAI,IAAI,KAAK,0BAA0B,EAAE,WAAW,QAAQ,UAAU,CAAC;AACvE,aAAO,YAAY,SAAS,QAAQ,KAAK,UAAU;AAAA,IACrD;AAAA,IAEA,MAAM,QAAQ,SAAS,KAAK;AAC1B,YAAM,EAAE,QAAQ,IAAI,MAAM,QAAQ;AAClC,YAAM,UAAU,MAAM,QAAQ,IAAI;AAAA,QAChC,WAAW,QAAQ;AAAA,QACnB,OAAO,IAAI,IAAI;AAAA,MACjB,CAAC;AACD,UAAI,IAAI,KAAK,iCAAiC,EAAE,WAAW,QAAQ,UAAU,CAAC;AAC9E,aAAO,YAAY,SAAS,EAAE,MAAM,MAAM,SAAS,IAAQ,GAAG,KAAK,OAAO;AAAA,IAC5E;AAAA,EACF;AACF;AAGO,IAAM,4BAA4B,8BAA8B;;;AE7FhE,SAAS,SAAS,UAAgC;AACvD,WAAS,SAAS,gBAAgB,yBAAyB;AAC7D;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skaile/provider-vercel-sandbox",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.1",
|
|
4
4
|
"description": "Vercel Sandbox deploy target for @skaile/workspaces",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
}
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@skaile/workspaces": "^0.22.0-beta.
|
|
34
|
+
"@skaile/workspaces": "^0.22.0-beta.1"
|
|
35
35
|
},
|
|
36
36
|
"scripts": {
|
|
37
37
|
"build": "tsup",
|