alchemy 0.45.5 → 0.46.0
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/README.md +2 -2
- package/bin/alchemy.mjs +19285 -15137
- package/bin/alchemy.ts +14 -56
- package/bin/commands/create.ts +307 -137
- package/bin/commands/deploy.ts +23 -0
- package/bin/commands/destroy.ts +19 -0
- package/bin/commands/dev.ts +21 -0
- package/bin/commands/login.ts +66 -0
- package/bin/commands/run.ts +29 -0
- package/bin/services/dependencies.ts +0 -5
- package/bin/services/execute-alchemy.ts +160 -0
- package/bin/services/git.ts +27 -0
- package/bin/services/github-workflow.ts +229 -0
- package/bin/services/package-manager.ts +51 -68
- package/bin/services/template-manager.ts +10 -21
- package/bin/trpc.ts +3 -0
- package/bin/types.ts +4 -2
- package/lib/apply.d.ts +2 -0
- package/lib/apply.d.ts.map +1 -1
- package/lib/apply.js +26 -8
- package/lib/apply.js.map +1 -1
- package/lib/build-date.d.ts +1 -1
- package/lib/build-date.js +1 -1
- package/lib/cloudflare/ai.d.ts +8 -4
- package/lib/cloudflare/ai.d.ts.map +1 -1
- package/lib/cloudflare/ai.js +6 -8
- package/lib/cloudflare/ai.js.map +1 -1
- package/lib/cloudflare/analytics-engine.d.ts +11 -7
- package/lib/cloudflare/analytics-engine.d.ts.map +1 -1
- package/lib/cloudflare/analytics-engine.js +11 -9
- package/lib/cloudflare/analytics-engine.js.map +1 -1
- package/lib/cloudflare/{types.d.ts → api-response.d.ts} +6 -1
- package/lib/cloudflare/api-response.d.ts.map +1 -0
- package/lib/cloudflare/api-response.js +38 -0
- package/lib/cloudflare/api-response.js.map +1 -0
- package/lib/cloudflare/auth-wrangler.d.ts +25 -0
- package/lib/cloudflare/auth-wrangler.d.ts.map +1 -0
- package/lib/cloudflare/auth-wrangler.js +224 -0
- package/lib/cloudflare/auth-wrangler.js.map +1 -0
- package/lib/cloudflare/auth.d.ts.map +1 -1
- package/lib/cloudflare/auth.js +7 -116
- package/lib/cloudflare/auth.js.map +1 -1
- package/lib/cloudflare/browser-rendering.d.ts +12 -3
- package/lib/cloudflare/browser-rendering.d.ts.map +1 -1
- package/lib/cloudflare/browser-rendering.js +12 -2
- package/lib/cloudflare/browser-rendering.js.map +1 -1
- package/lib/cloudflare/bundle/fs.d.ts.map +1 -1
- package/lib/cloudflare/bundle/fs.js +3 -0
- package/lib/cloudflare/bundle/fs.js.map +1 -1
- package/lib/cloudflare/bundle/internal-worker-bundle.d.ts +6 -0
- package/lib/cloudflare/bundle/internal-worker-bundle.d.ts.map +1 -0
- package/lib/cloudflare/bundle/internal-worker-bundle.js +14 -0
- package/lib/cloudflare/bundle/internal-worker-bundle.js.map +1 -0
- package/lib/cloudflare/compatibility-presets.d.ts +22 -0
- package/lib/cloudflare/compatibility-presets.d.ts.map +1 -0
- package/lib/cloudflare/compatibility-presets.js +27 -0
- package/lib/cloudflare/compatibility-presets.js.map +1 -0
- package/lib/cloudflare/container.d.ts +6 -2
- package/lib/cloudflare/container.d.ts.map +1 -1
- package/lib/cloudflare/container.js +48 -4
- package/lib/cloudflare/container.js.map +1 -1
- package/lib/cloudflare/dispatch-namespace.d.ts +5 -0
- package/lib/cloudflare/dispatch-namespace.d.ts.map +1 -1
- package/lib/cloudflare/dispatch-namespace.js +8 -0
- package/lib/cloudflare/dispatch-namespace.js.map +1 -1
- package/lib/cloudflare/durable-object-namespace.d.ts +23 -15
- package/lib/cloudflare/durable-object-namespace.d.ts.map +1 -1
- package/lib/cloudflare/durable-object-namespace.js +22 -21
- package/lib/cloudflare/durable-object-namespace.js.map +1 -1
- package/lib/cloudflare/hyperdrive.d.ts +19 -5
- package/lib/cloudflare/hyperdrive.d.ts.map +1 -1
- package/lib/cloudflare/hyperdrive.js +14 -0
- package/lib/cloudflare/hyperdrive.js.map +1 -1
- package/lib/cloudflare/images.d.ts +27 -17
- package/lib/cloudflare/images.d.ts.map +1 -1
- package/lib/cloudflare/images.js +13 -8
- package/lib/cloudflare/images.js.map +1 -1
- package/lib/cloudflare/index.d.ts +1 -3
- package/lib/cloudflare/index.d.ts.map +1 -1
- package/lib/cloudflare/index.js +1 -3
- package/lib/cloudflare/index.js.map +1 -1
- package/lib/cloudflare/miniflare/miniflare.d.ts +3 -3
- package/lib/cloudflare/miniflare/miniflare.d.ts.map +1 -1
- package/lib/cloudflare/miniflare/miniflare.js +7 -7
- package/lib/cloudflare/miniflare/miniflare.js.map +1 -1
- package/lib/cloudflare/miniflare/{mixed-mode.d.ts → remote-binding-proxy.d.ts} +5 -5
- package/lib/cloudflare/miniflare/remote-binding-proxy.d.ts.map +1 -0
- package/lib/cloudflare/miniflare/{mixed-mode.js → remote-binding-proxy.js} +16 -52
- package/lib/cloudflare/miniflare/remote-binding-proxy.js.map +1 -0
- package/lib/cloudflare/state.d.ts +26 -0
- package/lib/cloudflare/state.d.ts.map +1 -0
- package/lib/cloudflare/state.js +14 -0
- package/lib/cloudflare/state.js.map +1 -0
- package/lib/cloudflare/user.d.ts +2 -2
- package/lib/cloudflare/user.d.ts.map +1 -1
- package/lib/cloudflare/user.js +7 -21
- package/lib/cloudflare/user.js.map +1 -1
- package/lib/cloudflare/vectorize-index.d.ts.map +1 -1
- package/lib/cloudflare/vectorize-index.js +5 -2
- package/lib/cloudflare/vectorize-index.js.map +1 -1
- package/lib/cloudflare/version-metadata.d.ts +15 -3
- package/lib/cloudflare/version-metadata.d.ts.map +1 -1
- package/lib/cloudflare/version-metadata.js +11 -2
- package/lib/cloudflare/version-metadata.js.map +1 -1
- package/lib/cloudflare/vite.d.ts.map +1 -1
- package/lib/cloudflare/vite.js +2 -1
- package/lib/cloudflare/vite.js.map +1 -1
- package/lib/cloudflare/worker-metadata.d.ts +13 -2
- package/lib/cloudflare/worker-metadata.d.ts.map +1 -1
- package/lib/cloudflare/worker-metadata.js +10 -15
- package/lib/cloudflare/worker-metadata.js.map +1 -1
- package/lib/cloudflare/worker-subdomain.d.ts +7 -0
- package/lib/cloudflare/worker-subdomain.d.ts.map +1 -1
- package/lib/cloudflare/worker-subdomain.js +17 -22
- package/lib/cloudflare/worker-subdomain.js.map +1 -1
- package/lib/cloudflare/{worker/tail.d.ts → worker-tail.d.ts} +2 -2
- package/lib/cloudflare/worker-tail.d.ts.map +1 -0
- package/lib/cloudflare/{worker/tail.js → worker-tail.js} +11 -9
- package/lib/cloudflare/worker-tail.js.map +1 -0
- package/lib/cloudflare/worker.d.ts +18 -8
- package/lib/cloudflare/worker.d.ts.map +1 -1
- package/lib/cloudflare/worker.js +32 -8
- package/lib/cloudflare/worker.js.map +1 -1
- package/lib/cloudflare/workflow.d.ts +22 -11
- package/lib/cloudflare/workflow.d.ts.map +1 -1
- package/lib/cloudflare/workflow.js +23 -18
- package/lib/cloudflare/workflow.js.map +1 -1
- package/lib/context.d.ts +2 -2
- package/lib/context.d.ts.map +1 -1
- package/lib/docker/api.d.ts.map +1 -1
- package/lib/docker/api.js +30 -8
- package/lib/docker/api.js.map +1 -1
- package/lib/fs/file-system-state-store.d.ts +5 -20
- package/lib/fs/file-system-state-store.d.ts.map +1 -1
- package/lib/fs/file-system-state-store.js +5 -121
- package/lib/fs/file-system-state-store.js.map +1 -1
- package/lib/fs/index.d.ts +0 -1
- package/lib/fs/index.d.ts.map +1 -1
- package/lib/fs/index.js +0 -1
- package/lib/fs/index.js.map +1 -1
- package/lib/llms.cloudflare.txt +6 -5
- package/lib/planetscale/password.js +1 -1
- package/lib/planetscale/password.js.map +1 -1
- package/lib/scope.d.ts.map +1 -1
- package/lib/scope.js +3 -6
- package/lib/scope.js.map +1 -1
- package/lib/state/cloudflare-state-store.d.ts +34 -0
- package/lib/state/cloudflare-state-store.d.ts.map +1 -0
- package/lib/state/cloudflare-state-store.js +116 -0
- package/lib/state/cloudflare-state-store.js.map +1 -0
- package/lib/state/d1-state-store.d.ts +15 -0
- package/lib/state/d1-state-store.d.ts.map +1 -0
- package/lib/{cloudflare → state}/d1-state-store.js +31 -27
- package/lib/state/d1-state-store.js.map +1 -0
- package/lib/{cloudflare/do-state-store/types.d.ts → state/dofs-state-store/api.d.ts} +1 -1
- package/lib/state/dofs-state-store/api.d.ts.map +1 -0
- package/lib/state/dofs-state-store/api.js +1 -0
- package/lib/state/dofs-state-store/api.js.map +1 -0
- package/lib/{cloudflare/do-state-store/store.d.ts → state/dofs-state-store/index.d.ts} +10 -5
- package/lib/state/dofs-state-store/index.d.ts.map +1 -0
- package/lib/{cloudflare/do-state-store/store.js → state/dofs-state-store/index.js} +15 -11
- package/lib/state/dofs-state-store/index.js.map +1 -0
- package/lib/{cloudflare/do-state-store/internal.d.ts → state/dofs-state-store/store.d.ts} +4 -5
- package/lib/state/dofs-state-store/store.d.ts.map +1 -0
- package/lib/{cloudflare/do-state-store/internal.js → state/dofs-state-store/store.js} +7 -22
- package/lib/state/dofs-state-store/store.js.map +1 -0
- package/lib/state/file-system-state-store.d.ts +21 -0
- package/lib/state/file-system-state-store.d.ts.map +1 -0
- package/lib/state/file-system-state-store.js +122 -0
- package/lib/state/file-system-state-store.js.map +1 -0
- package/lib/state/index.d.ts +7 -0
- package/lib/state/index.d.ts.map +1 -0
- package/lib/state/index.js +7 -0
- package/lib/state/index.js.map +1 -0
- package/lib/state/migrations.d.ts +2 -0
- package/lib/state/migrations.d.ts.map +1 -0
- package/lib/state/migrations.js +3 -0
- package/lib/state/migrations.js.map +1 -0
- package/lib/state/operations.d.ts +36 -0
- package/lib/state/operations.d.ts.map +1 -0
- package/lib/state/operations.js +126 -0
- package/lib/state/operations.js.map +1 -0
- package/lib/state/proxy.d.ts +53 -0
- package/lib/state/proxy.d.ts.map +1 -0
- package/lib/state/proxy.js +65 -0
- package/lib/state/proxy.js.map +1 -0
- package/lib/{cloudflare → state}/r2-rest-state-store.d.ts +3 -1
- package/lib/state/r2-rest-state-store.d.ts.map +1 -0
- package/lib/{cloudflare → state}/r2-rest-state-store.js +6 -4
- package/lib/state/r2-rest-state-store.js.map +1 -0
- package/lib/state/schema.d.ts.map +1 -0
- package/lib/state/schema.js.map +1 -0
- package/lib/{sqlite → state}/sqlite-state-store.d.ts +5 -3
- package/lib/state/sqlite-state-store.d.ts.map +1 -0
- package/lib/{sqlite → state}/sqlite-state-store.js +15 -6
- package/lib/state/sqlite-state-store.js.map +1 -0
- package/lib/test/vitest.d.ts.map +1 -1
- package/lib/test/vitest.js +3 -6
- package/lib/test/vitest.js.map +1 -1
- package/lib/util/detect-node-runtime.d.ts +3 -0
- package/lib/util/detect-node-runtime.d.ts.map +1 -0
- package/lib/util/detect-node-runtime.js +10 -0
- package/lib/util/detect-node-runtime.js.map +1 -0
- package/lib/util/detect-package-manager.d.ts +2 -2
- package/lib/util/detect-package-manager.d.ts.map +1 -1
- package/lib/util/detect-package-manager.js +15 -5
- package/lib/util/detect-package-manager.js.map +1 -1
- package/lib/util/http-server.d.ts.map +1 -0
- package/lib/{cloudflare/miniflare → util}/http-server.js +1 -1
- package/lib/util/http-server.js.map +1 -0
- package/lib/util/memoize.d.ts +2 -0
- package/lib/util/memoize.d.ts.map +1 -1
- package/lib/util/memoize.js +14 -7
- package/lib/util/memoize.js.map +1 -1
- package/lib/util/neverthrow.d.ts +9 -0
- package/lib/util/neverthrow.d.ts.map +1 -0
- package/lib/util/neverthrow.js +29 -0
- package/lib/util/neverthrow.js.map +1 -0
- package/package.json +20 -20
- package/src/apply.ts +31 -10
- package/src/build-date.ts +1 -1
- package/src/cloudflare/ai.ts +10 -5
- package/src/cloudflare/analytics-engine.ts +20 -11
- package/src/cloudflare/{types.ts → api-response.ts} +31 -0
- package/src/cloudflare/auth-wrangler.ts +314 -0
- package/src/cloudflare/auth.ts +8 -156
- package/src/cloudflare/browser-rendering.ts +16 -2
- package/src/cloudflare/bundle/fs.ts +5 -0
- package/src/cloudflare/bundle/internal-worker-bundle.ts +21 -0
- package/src/cloudflare/compatibility-presets.ts +34 -0
- package/src/cloudflare/container.ts +77 -6
- package/src/cloudflare/dispatch-namespace.ts +28 -0
- package/src/cloudflare/durable-object-namespace.ts +38 -27
- package/src/cloudflare/hyperdrive.ts +19 -5
- package/src/cloudflare/images.ts +32 -17
- package/src/cloudflare/index.ts +1 -3
- package/src/cloudflare/miniflare/miniflare.ts +10 -7
- package/src/cloudflare/miniflare/{mixed-mode.ts → remote-binding-proxy.ts} +25 -75
- package/src/cloudflare/state.ts +35 -0
- package/src/cloudflare/user.ts +55 -70
- package/src/cloudflare/vectorize-index.ts +7 -2
- package/src/cloudflare/version-metadata.ts +19 -2
- package/src/cloudflare/vite.ts +2 -1
- package/src/cloudflare/worker-metadata.ts +18 -43
- package/src/cloudflare/worker-subdomain.ts +43 -37
- package/src/cloudflare/{worker/tail.ts → worker-tail.ts} +13 -10
- package/src/cloudflare/worker.ts +66 -20
- package/src/cloudflare/workflow.ts +38 -19
- package/src/context.ts +2 -2
- package/src/docker/api.ts +33 -8
- package/src/fs/file-system-state-store.ts +5 -148
- package/src/fs/index.ts +0 -1
- package/src/llms.cloudflare.txt +6 -5
- package/src/planetscale/password.ts +1 -1
- package/src/scope.ts +3 -6
- package/src/state/cloudflare-state-store.ts +170 -0
- package/src/state/d1-state-store.ts +102 -0
- package/src/{cloudflare/do-state-store/store.ts → state/dofs-state-store/index.ts} +20 -13
- package/src/{cloudflare/do-state-store/internal.ts → state/dofs-state-store/store.ts} +9 -27
- package/src/state/file-system-state-store.ts +149 -0
- package/src/state/index.ts +6 -0
- package/src/state/migrations.ts +9 -0
- package/src/state/operations.ts +152 -0
- package/src/state/proxy.ts +132 -0
- package/src/{cloudflare → state}/r2-rest-state-store.ts +11 -8
- package/src/{sqlite → state}/sqlite-state-store.ts +18 -10
- package/src/test/vitest.ts +8 -6
- package/src/util/detect-node-runtime.ts +12 -0
- package/src/util/detect-package-manager.ts +19 -6
- package/src/{cloudflare/miniflare → util}/http-server.ts +1 -1
- package/src/util/memoize.ts +18 -7
- package/src/util/neverthrow.ts +36 -0
- package/templates/astro/package.json +3 -3
- package/templates/nuxt/package.json +3 -3
- package/templates/react-router/package.json +3 -3
- package/templates/rwsdk/alchemy.run.ts +1 -1
- package/templates/rwsdk/package.json +3 -3
- package/templates/sveltekit/package.json +3 -3
- package/templates/tanstack-start/package.json +3 -3
- package/templates/typescript/package.json +3 -2
- package/templates/typescript/tsconfig.json +1 -0
- package/templates/vite/package.json +3 -3
- package/workers/cloudflare-state-store.js +5638 -0
- package/workers/cloudflare-state-store.ts +108 -0
- package/workers/{do-state-store.js → dofs-state-store.js} +4 -4
- package/workers/{do-state-store.ts → dofs-state-store.ts} +12 -8
- package/workers/{mixed-mode-proxy-worker.js → remote-binding-proxy.js} +3 -3
- package/workers/remote-binding-proxy.ts +45 -0
- package/lib/cloudflare/d1-state-store.d.ts +0 -10
- package/lib/cloudflare/d1-state-store.d.ts.map +0 -1
- package/lib/cloudflare/d1-state-store.js.map +0 -1
- package/lib/cloudflare/do-state-store/index.d.ts +0 -2
- package/lib/cloudflare/do-state-store/index.d.ts.map +0 -1
- package/lib/cloudflare/do-state-store/index.js +0 -2
- package/lib/cloudflare/do-state-store/index.js.map +0 -1
- package/lib/cloudflare/do-state-store/internal.d.ts.map +0 -1
- package/lib/cloudflare/do-state-store/internal.js.map +0 -1
- package/lib/cloudflare/do-state-store/store.d.ts.map +0 -1
- package/lib/cloudflare/do-state-store/store.js.map +0 -1
- package/lib/cloudflare/do-state-store/types.d.ts.map +0 -1
- package/lib/cloudflare/do-state-store/types.js +0 -1
- package/lib/cloudflare/do-state-store/types.js.map +0 -1
- package/lib/cloudflare/miniflare/http-server.d.ts.map +0 -1
- package/lib/cloudflare/miniflare/http-server.js.map +0 -1
- package/lib/cloudflare/miniflare/mixed-mode.d.ts.map +0 -1
- package/lib/cloudflare/miniflare/mixed-mode.js.map +0 -1
- package/lib/cloudflare/r2-rest-state-store.d.ts.map +0 -1
- package/lib/cloudflare/r2-rest-state-store.js.map +0 -1
- package/lib/cloudflare/types.d.ts.map +0 -1
- package/lib/cloudflare/types.js +0 -19
- package/lib/cloudflare/types.js.map +0 -1
- package/lib/cloudflare/worker/shared.d.ts +0 -4
- package/lib/cloudflare/worker/shared.d.ts.map +0 -1
- package/lib/cloudflare/worker/shared.js +0 -21
- package/lib/cloudflare/worker/shared.js.map +0 -1
- package/lib/cloudflare/worker/tail.d.ts.map +0 -1
- package/lib/cloudflare/worker/tail.js.map +0 -1
- package/lib/sqlite/base-sqlite-state-store.d.ts +0 -31
- package/lib/sqlite/base-sqlite-state-store.d.ts.map +0 -1
- package/lib/sqlite/base-sqlite-state-store.js +0 -124
- package/lib/sqlite/base-sqlite-state-store.js.map +0 -1
- package/lib/sqlite/index.d.ts +0 -2
- package/lib/sqlite/index.d.ts.map +0 -1
- package/lib/sqlite/index.js +0 -2
- package/lib/sqlite/index.js.map +0 -1
- package/lib/sqlite/schema.d.ts.map +0 -1
- package/lib/sqlite/schema.js.map +0 -1
- package/lib/sqlite/sqlite-state-store.d.ts.map +0 -1
- package/lib/sqlite/sqlite-state-store.js.map +0 -1
- package/src/cloudflare/d1-state-store.ts +0 -105
- package/src/cloudflare/do-state-store/index.ts +0 -1
- package/src/cloudflare/worker/shared.ts +0 -30
- package/src/sqlite/base-sqlite-state-store.ts +0 -199
- package/src/sqlite/index.ts +0 -1
- package/templates/typescript/src/worker.js +0 -5
- package/workers/mixed-mode-proxy-worker.ts +0 -46
- /package/drizzle/{0000_busy_mauler.sql → default/0000_busy_mauler.sql} +0 -0
- /package/drizzle/{0001_concerned_iceman.sql → default/0001_concerned_iceman.sql} +0 -0
- /package/drizzle/{meta → default/meta}/0000_snapshot.json +0 -0
- /package/drizzle/{meta → default/meta}/0001_snapshot.json +0 -0
- /package/drizzle/{meta → default/meta}/_journal.json +0 -0
- /package/lib/{sqlite → state}/schema.d.ts +0 -0
- /package/lib/{sqlite → state}/schema.js +0 -0
- /package/lib/{cloudflare/miniflare → util}/http-server.d.ts +0 -0
- /package/src/{cloudflare/do-state-store/types.ts → state/dofs-state-store/api.ts} +0 -0
- /package/src/{sqlite → state}/schema.ts +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { assertNever } from "../util/assert-never.ts";
|
|
2
2
|
import { logger } from "../util/logger.ts";
|
|
3
3
|
import { memoize } from "../util/memoize.ts";
|
|
4
|
+
import { extractCloudflareResult } from "./api-response.ts";
|
|
4
5
|
import type { CloudflareApi } from "./api.ts";
|
|
5
6
|
import {
|
|
6
7
|
Self,
|
|
@@ -200,7 +201,7 @@ export interface WorkerMetadata {
|
|
|
200
201
|
|
|
201
202
|
export async function prepareWorkerMetadata(
|
|
202
203
|
api: CloudflareApi,
|
|
203
|
-
props: WorkerProps & {
|
|
204
|
+
props: Omit<WorkerProps, "entrypoint"> & {
|
|
204
205
|
compatibilityDate: string;
|
|
205
206
|
compatibilityFlags: string[];
|
|
206
207
|
workerName: string;
|
|
@@ -210,6 +211,7 @@ export async function prepareWorkerMetadata(
|
|
|
210
211
|
keepAssets?: boolean;
|
|
211
212
|
assetConfig?: AssetsConfig;
|
|
212
213
|
};
|
|
214
|
+
tags?: string[];
|
|
213
215
|
unstable_cacheWorkerSettings?: boolean;
|
|
214
216
|
},
|
|
215
217
|
): Promise<WorkerMetadata> {
|
|
@@ -226,7 +228,7 @@ export async function prepareWorkerMetadata(
|
|
|
226
228
|
// we use Cloudflare Worker tags to store a mapping between Alchemy's stable identifier and the binding name
|
|
227
229
|
// e.g.
|
|
228
230
|
// {
|
|
229
|
-
// BINDING_NAME:
|
|
231
|
+
// BINDING_NAME: DurableObjectNamespace("stable-id")
|
|
230
232
|
// }
|
|
231
233
|
// will be stored as alchemy:do:stable-id:BINDING_NAME
|
|
232
234
|
// TODO(sam): should we base64 encode to ensure no `:` collision risk?
|
|
@@ -323,6 +325,7 @@ export async function prepareWorkerMetadata(
|
|
|
323
325
|
),
|
|
324
326
|
// encode the migraiton tag if there is one so we can avoid the failed PutWorker after adoption
|
|
325
327
|
...(newMigrationTag ? [`alchemy:migration-tag:${newMigrationTag}`] : []),
|
|
328
|
+
...(props.tags ?? []),
|
|
326
329
|
],
|
|
327
330
|
migrations: {
|
|
328
331
|
old_tag: oldMigrationTag,
|
|
@@ -640,6 +643,7 @@ interface WorkerSettings {
|
|
|
640
643
|
compatibility_date: string;
|
|
641
644
|
compatibility_flags: string[];
|
|
642
645
|
migrations: SingleStepMigration | MultiStepMigration;
|
|
646
|
+
tags: string[];
|
|
643
647
|
[key: string]: any;
|
|
644
648
|
}
|
|
645
649
|
|
|
@@ -648,51 +652,22 @@ const getWorkerSettingsWithCache = memoize(
|
|
|
648
652
|
(api, workerName) => `${api.accountId}:${workerName}`,
|
|
649
653
|
);
|
|
650
654
|
|
|
651
|
-
async function getWorkerSettings(
|
|
655
|
+
export async function getWorkerSettings(
|
|
652
656
|
api: CloudflareApi,
|
|
653
657
|
workerName: string,
|
|
654
658
|
): Promise<WorkerSettings | undefined> {
|
|
655
659
|
// Fetch the bindings for a worker by calling the Cloudflare API endpoint:
|
|
656
660
|
// GET /accounts/:account_id/workers/scripts/:script_name/bindings
|
|
657
661
|
// See: https://developers.cloudflare.com/api/resources/workers/subresources/scripts/subresources/script_and_version_settings/methods/get/
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
}
|
|
669
|
-
// The result is an object with a "result" property containing the bindings array
|
|
670
|
-
const { result, success, errors } = (await response.json()) as {
|
|
671
|
-
result: {
|
|
672
|
-
bindings: WorkerBindingSpec[];
|
|
673
|
-
compatibility_date: string;
|
|
674
|
-
compatibility_flags: string[];
|
|
675
|
-
migrations: SingleStepMigration | MultiStepMigration;
|
|
676
|
-
[key: string]: any;
|
|
677
|
-
};
|
|
678
|
-
success: boolean;
|
|
679
|
-
errors: Array<{
|
|
680
|
-
code: number;
|
|
681
|
-
message: string;
|
|
682
|
-
documentation_url: string;
|
|
683
|
-
[key: string]: any;
|
|
684
|
-
}>;
|
|
685
|
-
messages: Array<{
|
|
686
|
-
code: number;
|
|
687
|
-
message: string;
|
|
688
|
-
documentation_url: string;
|
|
689
|
-
[key: string]: any;
|
|
690
|
-
}>;
|
|
691
|
-
};
|
|
692
|
-
if (!success) {
|
|
693
|
-
throw new Error(
|
|
694
|
-
`Error getting worker bindings: ${response.status} ${response.statusText}\nErrors:\n${errors.map((e) => `- [${e.code}] ${e.message} (${e.documentation_url})`).join("\n")}`,
|
|
695
|
-
);
|
|
696
|
-
}
|
|
697
|
-
return result;
|
|
662
|
+
return await extractCloudflareResult<WorkerSettings>(
|
|
663
|
+
`get worker settings for ${workerName}`,
|
|
664
|
+
api.get(
|
|
665
|
+
`/accounts/${api.accountId}/workers/scripts/${workerName}/settings`,
|
|
666
|
+
),
|
|
667
|
+
).catch((error) => {
|
|
668
|
+
if (error.status === 404) {
|
|
669
|
+
return undefined;
|
|
670
|
+
}
|
|
671
|
+
throw error;
|
|
672
|
+
});
|
|
698
673
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { Context } from "../context.ts";
|
|
2
2
|
import { Resource } from "../resource.ts";
|
|
3
|
+
import { memoize } from "../util/memoize.ts";
|
|
4
|
+
import { extractCloudflareResult } from "./api-response.ts";
|
|
3
5
|
import {
|
|
4
6
|
createCloudflareApi,
|
|
5
7
|
type CloudflareApi,
|
|
6
8
|
type CloudflareApiOptions,
|
|
7
9
|
} from "./api.ts";
|
|
8
|
-
import type { CloudflareApiResponse } from "./types.ts";
|
|
9
|
-
import { getAccountSubdomain } from "./worker/shared.ts";
|
|
10
10
|
|
|
11
11
|
interface WorkerSubdomainProps extends CloudflareApiOptions {
|
|
12
12
|
/**
|
|
@@ -49,16 +49,7 @@ export const WorkerSubdomain = Resource(
|
|
|
49
49
|
}
|
|
50
50
|
return this.destroy();
|
|
51
51
|
}
|
|
52
|
-
await
|
|
53
|
-
`enable subdomain for "${props.scriptName}"`,
|
|
54
|
-
api.post(
|
|
55
|
-
`/accounts/${api.accountId}/workers/scripts/${props.scriptName}/subdomain`,
|
|
56
|
-
{ enabled: true, previews_enabled: true },
|
|
57
|
-
{
|
|
58
|
-
headers: { "Content-Type": "application/json" },
|
|
59
|
-
},
|
|
60
|
-
),
|
|
61
|
-
);
|
|
52
|
+
await enableWorkerSubdomain(api, props.scriptName);
|
|
62
53
|
const subdomain = await getAccountSubdomain(api);
|
|
63
54
|
const base = `${subdomain}.workers.dev`;
|
|
64
55
|
let url: string;
|
|
@@ -77,7 +68,7 @@ export async function disableWorkerSubdomain(
|
|
|
77
68
|
api: CloudflareApi,
|
|
78
69
|
scriptName: string,
|
|
79
70
|
) {
|
|
80
|
-
await
|
|
71
|
+
await extractCloudflareResult<SubdomainResponse>(
|
|
81
72
|
`disable subdomain for "${scriptName}"`,
|
|
82
73
|
api.post(
|
|
83
74
|
`/accounts/${api.accountId}/workers/scripts/${scriptName}/subdomain`,
|
|
@@ -91,33 +82,48 @@ export async function disableWorkerSubdomain(
|
|
|
91
82
|
});
|
|
92
83
|
}
|
|
93
84
|
|
|
85
|
+
export async function enableWorkerSubdomain(
|
|
86
|
+
api: CloudflareApi,
|
|
87
|
+
scriptName: string,
|
|
88
|
+
) {
|
|
89
|
+
await extractCloudflareResult<SubdomainResponse>(
|
|
90
|
+
`enable subdomain for "${scriptName}"`,
|
|
91
|
+
api.post(
|
|
92
|
+
`/accounts/${api.accountId}/workers/scripts/${scriptName}/subdomain`,
|
|
93
|
+
{ enabled: true, previews_enabled: true },
|
|
94
|
+
),
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export async function getWorkerSubdomain(
|
|
99
|
+
api: CloudflareApi,
|
|
100
|
+
scriptName: string,
|
|
101
|
+
) {
|
|
102
|
+
return await extractCloudflareResult<SubdomainResponse>(
|
|
103
|
+
`get subdomain for "${scriptName}"`,
|
|
104
|
+
api.get(
|
|
105
|
+
`/accounts/${api.accountId}/workers/scripts/${scriptName}/subdomain`,
|
|
106
|
+
),
|
|
107
|
+
).catch((error): SubdomainResponse => {
|
|
108
|
+
if (error.status === 404) {
|
|
109
|
+
return { enabled: false, previews_enabled: false };
|
|
110
|
+
}
|
|
111
|
+
throw error;
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
94
115
|
interface SubdomainResponse {
|
|
95
116
|
enabled: boolean;
|
|
96
117
|
previews_enabled: boolean;
|
|
97
118
|
}
|
|
98
119
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
throw new Error(`Failed to ${label}: Failed to fetch`);
|
|
105
|
-
});
|
|
106
|
-
const json = (await response.json().catch(() => {
|
|
107
|
-
throw new Error(
|
|
108
|
-
`Failed to ${label} (${response.status}): The API returned an invalid response`,
|
|
120
|
+
export const getAccountSubdomain = memoize(
|
|
121
|
+
async (api: CloudflareApi) => {
|
|
122
|
+
const result = await extractCloudflareResult<{ subdomain: string }>(
|
|
123
|
+
`get subdomain for account ${api.accountId}`,
|
|
124
|
+
api.get(`/accounts/${api.accountId}/workers/subdomain`),
|
|
109
125
|
);
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
const error = new Error(
|
|
115
|
-
`Failed to ${label} (${response.status}): ${json.errors.map((e) => `${e.code}: ${e.message}`).join(", ")}`,
|
|
116
|
-
);
|
|
117
|
-
Error.captureStackTrace(error, wrapFetch);
|
|
118
|
-
Object.assign(error, {
|
|
119
|
-
status: response.status,
|
|
120
|
-
});
|
|
121
|
-
throw error;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
126
|
+
return result.subdomain;
|
|
127
|
+
},
|
|
128
|
+
(api) => api.accountId,
|
|
129
|
+
);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import kleur from "kleur";
|
|
2
2
|
import { WebSocket } from "ws";
|
|
3
|
-
import { logger } from "
|
|
4
|
-
import type {
|
|
5
|
-
import type {
|
|
3
|
+
import { logger } from "../util/logger.ts";
|
|
4
|
+
import type { CloudflareApiResponse } from "./api-response.ts";
|
|
5
|
+
import type { CloudflareApi } from "./api.ts";
|
|
6
6
|
|
|
7
7
|
export const createTail = async (
|
|
8
8
|
api: CloudflareApi,
|
|
@@ -47,7 +47,12 @@ class TailClient {
|
|
|
47
47
|
}
|
|
48
48
|
const res = await this.api.post(
|
|
49
49
|
`/accounts/${this.api.accountId}/workers/scripts/${this.scriptName}/tails`,
|
|
50
|
-
{},
|
|
50
|
+
{ filters: [] },
|
|
51
|
+
{
|
|
52
|
+
headers: {
|
|
53
|
+
"Content-Type": "application/json",
|
|
54
|
+
},
|
|
55
|
+
},
|
|
51
56
|
);
|
|
52
57
|
const json = (await res.json()) as CloudflareApiResponse<Tail>;
|
|
53
58
|
if (!json.success) {
|
|
@@ -72,11 +77,7 @@ class TailClient {
|
|
|
72
77
|
throw new Error(`Failed to connect to tail for ${this.scriptName}`);
|
|
73
78
|
}
|
|
74
79
|
const tail = await this.create();
|
|
75
|
-
const ws = new WebSocket(tail.url,
|
|
76
|
-
headers: {
|
|
77
|
-
"Sec-WebSocket-Protocol": "trace-v1",
|
|
78
|
-
},
|
|
79
|
-
});
|
|
80
|
+
const ws = new WebSocket(tail.url, "trace-v1");
|
|
80
81
|
ws.on("open", () => {
|
|
81
82
|
this.ping(ws);
|
|
82
83
|
if (DEBUG) {
|
|
@@ -92,7 +93,9 @@ class TailClient {
|
|
|
92
93
|
return;
|
|
93
94
|
}
|
|
94
95
|
logger.log(`reconnecting to tail for "${this.scriptName}"`);
|
|
95
|
-
|
|
96
|
+
setTimeout(() => {
|
|
97
|
+
this.connect(attempt + 1);
|
|
98
|
+
}, 1000);
|
|
96
99
|
});
|
|
97
100
|
ws.on("error", (event) => {
|
|
98
101
|
logger.error(`error on tail for "${this.scriptName}": ${event}`);
|
package/src/cloudflare/worker.ts
CHANGED
|
@@ -48,6 +48,10 @@ import {
|
|
|
48
48
|
normalizeWorkerBundle,
|
|
49
49
|
} from "./bundle/index.ts";
|
|
50
50
|
import { wrap } from "./bundle/normalize.ts";
|
|
51
|
+
import {
|
|
52
|
+
type CompatibilityPreset,
|
|
53
|
+
unionCompatibilityFlags,
|
|
54
|
+
} from "./compatibility-presets.ts";
|
|
51
55
|
import { type Container, ContainerApplication } from "./container.ts";
|
|
52
56
|
import { CustomDomain } from "./custom-domain.ts";
|
|
53
57
|
import { isD1Database } from "./d1-database.ts";
|
|
@@ -81,7 +85,7 @@ import {
|
|
|
81
85
|
} from "./worker-metadata.ts";
|
|
82
86
|
import { WorkerStub, isWorkerStub } from "./worker-stub.ts";
|
|
83
87
|
import { WorkerSubdomain, disableWorkerSubdomain } from "./worker-subdomain.ts";
|
|
84
|
-
import { createTail } from "./worker
|
|
88
|
+
import { createTail } from "./worker-tail.ts";
|
|
85
89
|
import { Workflow, isWorkflow, upsertWorkflow } from "./workflow.ts";
|
|
86
90
|
|
|
87
91
|
/**
|
|
@@ -215,6 +219,15 @@ export interface BaseWorkerProps<
|
|
|
215
219
|
*/
|
|
216
220
|
compatibilityFlags?: string[];
|
|
217
221
|
|
|
222
|
+
/**
|
|
223
|
+
* Compatibility preset to automatically include common compatibility flags
|
|
224
|
+
*
|
|
225
|
+
* - "node": Includes nodejs_compat flag for Node.js compatibility
|
|
226
|
+
*
|
|
227
|
+
* @default undefined (no preset)
|
|
228
|
+
*/
|
|
229
|
+
compatibility?: CompatibilityPreset;
|
|
230
|
+
|
|
218
231
|
/**
|
|
219
232
|
* Configuration for static assets
|
|
220
233
|
*/
|
|
@@ -618,8 +631,8 @@ export function WorkerRef<
|
|
|
618
631
|
* @example
|
|
619
632
|
* // Create a real-time chat worker using Durable Objects
|
|
620
633
|
* // for state management:
|
|
621
|
-
* const chatRooms =
|
|
622
|
-
* const userStore =
|
|
634
|
+
* const chatRooms = DurableObjectNamespace("chat-rooms");
|
|
635
|
+
* const userStore = DurableObjectNamespace("user-store");
|
|
623
636
|
*
|
|
624
637
|
* const chat = await Worker("chat", {
|
|
625
638
|
* name: "chat-worker",
|
|
@@ -693,7 +706,7 @@ export function WorkerRef<
|
|
|
693
706
|
* entrypoint: "./src/data.ts",
|
|
694
707
|
* bindings: {
|
|
695
708
|
* // Bind to its own durable object
|
|
696
|
-
* STORAGE:
|
|
709
|
+
* STORAGE: DurableObjectNamespace("storage", {
|
|
697
710
|
* className: "DataStorage"
|
|
698
711
|
* })
|
|
699
712
|
* }
|
|
@@ -834,7 +847,13 @@ export function Worker<const B extends Bindings>(
|
|
|
834
847
|
...(props as any),
|
|
835
848
|
url: true,
|
|
836
849
|
compatibilityFlags: Array.from(
|
|
837
|
-
new Set([
|
|
850
|
+
new Set([
|
|
851
|
+
"nodejs_compat",
|
|
852
|
+
...unionCompatibilityFlags(
|
|
853
|
+
props.compatibility,
|
|
854
|
+
props.compatibilityFlags,
|
|
855
|
+
),
|
|
856
|
+
]),
|
|
838
857
|
),
|
|
839
858
|
entrypoint: meta!.filename,
|
|
840
859
|
name: workerName,
|
|
@@ -987,7 +1006,10 @@ export const _Worker = Resource(
|
|
|
987
1006
|
const workerName = props.name ?? id;
|
|
988
1007
|
const compatibilityDate =
|
|
989
1008
|
props.compatibilityDate ?? DEFAULT_COMPATIBILITY_DATE;
|
|
990
|
-
const compatibilityFlags =
|
|
1009
|
+
const compatibilityFlags = unionCompatibilityFlags(
|
|
1010
|
+
props.compatibility,
|
|
1011
|
+
props.compatibilityFlags,
|
|
1012
|
+
);
|
|
991
1013
|
const dispatchNamespace =
|
|
992
1014
|
typeof props.namespace === "string"
|
|
993
1015
|
? props.namespace
|
|
@@ -1085,6 +1107,26 @@ export const _Worker = Resource(
|
|
|
1085
1107
|
throw error;
|
|
1086
1108
|
}
|
|
1087
1109
|
|
|
1110
|
+
if (this.phase === "update") {
|
|
1111
|
+
const oldName = this.output.name ?? this.output.id;
|
|
1112
|
+
const newName = workerName;
|
|
1113
|
+
|
|
1114
|
+
if (oldName !== newName) {
|
|
1115
|
+
if (dispatchNamespace) {
|
|
1116
|
+
await this.replace(true);
|
|
1117
|
+
} else {
|
|
1118
|
+
const renameResponse = await api.patch(
|
|
1119
|
+
`/accounts/${api.accountId}/workers/services/${oldName}`,
|
|
1120
|
+
{ id: newName },
|
|
1121
|
+
);
|
|
1122
|
+
|
|
1123
|
+
if (!renameResponse.ok) {
|
|
1124
|
+
await handleApiError(renameResponse, "rename", "worker", oldName);
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1088
1130
|
let assetsBinding: Assets | undefined;
|
|
1089
1131
|
const workflowsBindings: Workflow[] = [];
|
|
1090
1132
|
const containersBindings: Container[] = [];
|
|
@@ -1219,8 +1261,13 @@ export const _Worker = Resource(
|
|
|
1219
1261
|
}),
|
|
1220
1262
|
);
|
|
1221
1263
|
putWorkerResult = await promise.value;
|
|
1222
|
-
|
|
1223
|
-
|
|
1264
|
+
await createTail(api, id, workerName)
|
|
1265
|
+
.then((tail) => {
|
|
1266
|
+
cleanups.push(() => tail.close());
|
|
1267
|
+
})
|
|
1268
|
+
.catch((error) => {
|
|
1269
|
+
logger.error(`Failed to create tail for ${workerName}`, error);
|
|
1270
|
+
});
|
|
1224
1271
|
} else {
|
|
1225
1272
|
putWorkerResult = await putWorkerWithAssets(props, await bundle.create());
|
|
1226
1273
|
}
|
|
@@ -1424,13 +1471,13 @@ const normalizeExportBindings = (
|
|
|
1424
1471
|
Object.entries(bindings).map(([bindingName, binding]) => [
|
|
1425
1472
|
bindingName,
|
|
1426
1473
|
isDurableObjectNamespace(binding) && binding.scriptName === undefined
|
|
1427
|
-
?
|
|
1474
|
+
? DurableObjectNamespace(binding.id, {
|
|
1428
1475
|
...binding,
|
|
1429
1476
|
// re-export this binding mapping to the host worker (this worker)
|
|
1430
1477
|
scriptName,
|
|
1431
1478
|
})
|
|
1432
1479
|
: isWorkflow(binding) && binding.scriptName === undefined
|
|
1433
|
-
?
|
|
1480
|
+
? Workflow(binding.id, {
|
|
1434
1481
|
...binding,
|
|
1435
1482
|
// re-export this binding mapping to the host worker (this worker)
|
|
1436
1483
|
scriptName,
|
|
@@ -1471,7 +1518,7 @@ async function provisionContainers(
|
|
|
1471
1518
|
}
|
|
1472
1519
|
return ContainerApplication(container.id, {
|
|
1473
1520
|
image: container.image,
|
|
1474
|
-
name: container.
|
|
1521
|
+
name: container.name,
|
|
1475
1522
|
instanceType: container.instanceType,
|
|
1476
1523
|
observability: container.observability,
|
|
1477
1524
|
durableObjects: {
|
|
@@ -1824,21 +1871,20 @@ function createDevCommand(props: {
|
|
|
1824
1871
|
}
|
|
1825
1872
|
}
|
|
1826
1873
|
|
|
1827
|
-
type PutWorkerOptions = WorkerProps & {
|
|
1874
|
+
type PutWorkerOptions = Omit<WorkerProps, "entrypoint"> & {
|
|
1828
1875
|
dispatchNamespace?: string;
|
|
1829
1876
|
migrationTag?: string;
|
|
1830
1877
|
workerName: string;
|
|
1831
1878
|
scriptBundle: WorkerBundle;
|
|
1832
|
-
version
|
|
1879
|
+
version?: string;
|
|
1833
1880
|
compatibilityDate: string;
|
|
1834
1881
|
compatibilityFlags: string[];
|
|
1835
|
-
assetUploadResult
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
| undefined;
|
|
1882
|
+
assetUploadResult?: {
|
|
1883
|
+
completionToken?: string;
|
|
1884
|
+
keepAssets?: boolean;
|
|
1885
|
+
assetConfig?: AssetsConfig;
|
|
1886
|
+
};
|
|
1887
|
+
tags?: string[];
|
|
1842
1888
|
unstable_cacheWorkerSettings?: boolean;
|
|
1843
1889
|
};
|
|
1844
1890
|
|
|
@@ -34,31 +34,50 @@ export interface WorkflowProps {
|
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
export
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export class Workflow<PARAMS = unknown> {
|
|
42
|
-
public readonly type = "workflow";
|
|
37
|
+
export type Workflow<PARAMS = unknown> = {
|
|
38
|
+
type: "workflow";
|
|
43
39
|
/**
|
|
44
40
|
* Phantom property to preserve workflow params at the type level.
|
|
45
|
-
*
|
|
46
41
|
* No value exists.
|
|
47
42
|
*/
|
|
48
|
-
|
|
43
|
+
_PARAMS: PARAMS;
|
|
44
|
+
id: string;
|
|
45
|
+
workflowName: string;
|
|
46
|
+
className: string;
|
|
47
|
+
scriptName?: string;
|
|
48
|
+
};
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
export function isWorkflow(binding: Binding): binding is Workflow {
|
|
51
|
+
return typeof binding === "object" && binding.type === "workflow";
|
|
52
|
+
}
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
54
|
+
/**
|
|
55
|
+
* Creates a workflow binding for orchestrating and automating tasks.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```ts
|
|
59
|
+
* // Create a basic workflow
|
|
60
|
+
* const workflow = Workflow("my-workflow", {
|
|
61
|
+
* workflowName: "my-workflow",
|
|
62
|
+
* className: "MyWorkflow"
|
|
63
|
+
* });
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export function Workflow<PARAMS = unknown>(
|
|
67
|
+
id: string,
|
|
68
|
+
props: WorkflowProps = {},
|
|
69
|
+
): Workflow<PARAMS> {
|
|
70
|
+
const workflowName = props.workflowName ?? props.className ?? id;
|
|
71
|
+
const className = props.className ?? workflowName;
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
type: "workflow",
|
|
75
|
+
_PARAMS: undefined!,
|
|
76
|
+
id,
|
|
77
|
+
workflowName,
|
|
78
|
+
className,
|
|
79
|
+
scriptName: props.scriptName,
|
|
80
|
+
};
|
|
62
81
|
}
|
|
63
82
|
|
|
64
83
|
export interface WorkflowMetadata {
|
package/src/context.ts
CHANGED
|
@@ -57,7 +57,7 @@ export interface BaseContext<Out extends Resource> {
|
|
|
57
57
|
* Indicate that this resource is being replaced.
|
|
58
58
|
* This will cause the resource to be deleted at the end of the stack's CREATE phase.
|
|
59
59
|
*/
|
|
60
|
-
replace(): never
|
|
60
|
+
replace(force?: boolean): Promise<never>;
|
|
61
61
|
/**
|
|
62
62
|
* Terminate the resource lifecycle handler and destroy the resource.
|
|
63
63
|
*
|
|
@@ -102,7 +102,7 @@ export function context<
|
|
|
102
102
|
seq: number;
|
|
103
103
|
props: Props;
|
|
104
104
|
state: State<Kind, Props, Out>;
|
|
105
|
-
replace: () => never
|
|
105
|
+
replace: (force?: boolean) => Promise<never>;
|
|
106
106
|
isReplacement?: boolean;
|
|
107
107
|
}): Context<Out> {
|
|
108
108
|
type InternalSymbols =
|
package/src/docker/api.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { execa } from "execa";
|
|
1
2
|
import { Buffer } from "node:buffer";
|
|
2
3
|
import { spawn } from "node:child_process";
|
|
3
4
|
import fs from "node:fs/promises";
|
|
4
5
|
import path from "node:path";
|
|
5
|
-
import { exec } from "../os/exec.ts";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Options for Docker API requests
|
|
@@ -66,14 +66,39 @@ export class DockerApi {
|
|
|
66
66
|
? { ...process.env, DOCKER_CONFIG: this.configDir }
|
|
67
67
|
: process.env;
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
shell: true,
|
|
73
|
-
env,
|
|
74
|
-
})) as { stdout: string; stderr: string };
|
|
69
|
+
// Buffers to capture output
|
|
70
|
+
let stdout = "";
|
|
71
|
+
let stderr = "";
|
|
75
72
|
|
|
76
|
-
|
|
73
|
+
// Create the subprocess
|
|
74
|
+
const subprocess = execa(this.dockerPath, args, {
|
|
75
|
+
env: env,
|
|
76
|
+
// Don't buffer - we'll handle streams manually
|
|
77
|
+
buffer: false,
|
|
78
|
+
encoding: "utf8",
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// Stream stdout in real-time
|
|
82
|
+
subprocess.stdout?.on("data", (chunk: string) => {
|
|
83
|
+
process.stdout.write(chunk);
|
|
84
|
+
stdout += chunk;
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// Stream stderr in real-time
|
|
88
|
+
subprocess.stderr?.on("data", (chunk: string) => {
|
|
89
|
+
process.stderr.write(chunk);
|
|
90
|
+
stderr += chunk;
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// Wait for the process to complete
|
|
94
|
+
try {
|
|
95
|
+
await subprocess;
|
|
96
|
+
} catch (error: any) {
|
|
97
|
+
// Process failed, but we still have the output
|
|
98
|
+
throw new Error(stderr || error.message || "Command failed");
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return { stdout, stderr };
|
|
77
102
|
}
|
|
78
103
|
|
|
79
104
|
/**
|