alchemy 0.55.3 → 0.57.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/bin/alchemy.js +14245 -14406
- package/bin/commands/create.ts +7 -7
- package/bin/commands/deploy.ts +2 -2
- package/bin/commands/destroy.ts +2 -2
- package/bin/commands/dev.ts +2 -2
- package/bin/commands/init.ts +6 -6
- package/bin/commands/login.ts +3 -3
- package/bin/commands/run.ts +2 -2
- package/bin/services/execute-alchemy.ts +3 -3
- package/bin/trpc.ts +49 -0
- package/lib/alchemy.d.ts.map +1 -1
- package/lib/alchemy.js +7 -0
- package/lib/alchemy.js.map +1 -1
- package/lib/apply.d.ts.map +1 -1
- package/lib/apply.js +3 -4
- package/lib/apply.js.map +1 -1
- package/lib/cloudflare/{astro.d.ts → astro/astro.d.ts} +6 -5
- package/lib/cloudflare/astro/astro.d.ts.map +1 -0
- package/lib/cloudflare/astro/astro.js +91 -0
- package/lib/cloudflare/astro/astro.js.map +1 -0
- package/lib/cloudflare/astro/plugin.d.ts +4 -0
- package/lib/cloudflare/astro/plugin.d.ts.map +1 -0
- package/lib/cloudflare/astro/plugin.js +10 -0
- package/lib/cloudflare/astro/plugin.js.map +1 -0
- package/lib/cloudflare/bundle/plugin-hot-reload.d.ts +1 -3
- package/lib/cloudflare/bundle/plugin-hot-reload.d.ts.map +1 -1
- package/lib/cloudflare/bundle/plugin-hot-reload.js +4 -1
- package/lib/cloudflare/bundle/plugin-hot-reload.js.map +1 -1
- package/lib/cloudflare/cloudflare-env-proxy.d.ts +4 -0
- package/lib/cloudflare/cloudflare-env-proxy.d.ts.map +1 -0
- package/lib/cloudflare/cloudflare-env-proxy.js +34 -0
- package/lib/cloudflare/cloudflare-env-proxy.js.map +1 -0
- package/lib/cloudflare/compatibility-date.gen.d.ts +1 -1
- package/lib/cloudflare/compatibility-date.gen.js +1 -1
- package/lib/cloudflare/compatibility-presets.d.ts +1 -1
- package/lib/cloudflare/compatibility-presets.js +1 -1
- package/lib/cloudflare/compatibility-presets.js.map +1 -1
- package/lib/cloudflare/d1-local-migrations.js +1 -1
- package/lib/cloudflare/d1-local-migrations.js.map +1 -1
- package/lib/cloudflare/index.d.ts +8 -8
- package/lib/cloudflare/index.d.ts.map +1 -1
- package/lib/cloudflare/index.js +8 -8
- package/lib/cloudflare/index.js.map +1 -1
- package/lib/cloudflare/miniflare/build-worker-options.d.ts +22 -0
- package/lib/cloudflare/miniflare/build-worker-options.d.ts.map +1 -0
- package/lib/cloudflare/miniflare/build-worker-options.js +394 -0
- package/lib/cloudflare/miniflare/build-worker-options.js.map +1 -0
- package/lib/cloudflare/miniflare/miniflare-controller.d.ts +23 -0
- package/lib/cloudflare/miniflare/miniflare-controller.d.ts.map +1 -0
- package/lib/cloudflare/miniflare/miniflare-controller.js +111 -0
- package/lib/cloudflare/miniflare/miniflare-controller.js.map +1 -0
- package/lib/cloudflare/miniflare/miniflare-worker-proxy.d.ts.map +1 -1
- package/lib/cloudflare/miniflare/miniflare-worker-proxy.js +5 -15
- package/lib/cloudflare/miniflare/miniflare-worker-proxy.js.map +1 -1
- package/lib/cloudflare/miniflare/paths.d.ts +5 -0
- package/lib/cloudflare/miniflare/paths.d.ts.map +1 -0
- package/lib/cloudflare/miniflare/paths.js +35 -0
- package/lib/cloudflare/miniflare/paths.js.map +1 -0
- package/lib/cloudflare/miniflare/remote-binding-proxy.d.ts +1 -5
- package/lib/cloudflare/miniflare/remote-binding-proxy.d.ts.map +1 -1
- package/lib/cloudflare/miniflare/remote-binding-proxy.js +17 -22
- package/lib/cloudflare/miniflare/remote-binding-proxy.js.map +1 -1
- package/lib/cloudflare/{nuxt.d.ts → nuxt/nuxt.d.ts} +4 -4
- package/lib/cloudflare/nuxt/nuxt.d.ts.map +1 -0
- package/lib/cloudflare/{nuxt.js → nuxt/nuxt.js} +8 -13
- package/lib/cloudflare/nuxt/nuxt.js.map +1 -0
- package/lib/cloudflare/nuxt/plugin.d.ts +4 -0
- package/lib/cloudflare/nuxt/plugin.d.ts.map +1 -0
- package/lib/cloudflare/nuxt/plugin.js +14 -0
- package/lib/cloudflare/nuxt/plugin.js.map +1 -0
- package/lib/cloudflare/oauth.js +2 -2
- package/lib/cloudflare/oauth.js.map +1 -1
- package/lib/cloudflare/orange.d.ts +3 -3
- package/lib/cloudflare/orange.d.ts.map +1 -1
- package/lib/cloudflare/orange.js +11 -21
- package/lib/cloudflare/orange.js.map +1 -1
- package/lib/cloudflare/react-router/plugin.d.ts +4 -0
- package/lib/cloudflare/react-router/plugin.d.ts.map +1 -0
- package/lib/cloudflare/react-router/plugin.js +11 -0
- package/lib/cloudflare/react-router/plugin.js.map +1 -0
- package/lib/cloudflare/react-router/react-router.d.ts +17 -0
- package/lib/cloudflare/react-router/react-router.d.ts.map +1 -0
- package/lib/cloudflare/react-router/react-router.js +21 -0
- package/lib/cloudflare/react-router/react-router.js.map +1 -0
- package/lib/cloudflare/redwood/plugin.d.ts +4 -0
- package/lib/cloudflare/redwood/plugin.d.ts.map +1 -0
- package/lib/cloudflare/redwood/plugin.js +19 -0
- package/lib/cloudflare/redwood/plugin.js.map +1 -0
- package/lib/cloudflare/{redwood.d.ts → redwood/redwood.d.ts} +5 -5
- package/lib/cloudflare/redwood/redwood.d.ts.map +1 -0
- package/lib/cloudflare/{redwood.js → redwood/redwood.js} +12 -13
- package/lib/cloudflare/redwood/redwood.js.map +1 -0
- package/lib/cloudflare/sveltekit/plugin.d.ts +4 -0
- package/lib/cloudflare/sveltekit/plugin.d.ts.map +1 -0
- package/lib/cloudflare/sveltekit/plugin.js +11 -0
- package/lib/cloudflare/sveltekit/plugin.js.map +1 -0
- package/lib/cloudflare/{sveltekit.d.ts → sveltekit/sveltekit.d.ts} +5 -5
- package/lib/cloudflare/sveltekit/sveltekit.d.ts.map +1 -0
- package/lib/cloudflare/{sveltekit.js → sveltekit/sveltekit.js} +4 -4
- package/lib/cloudflare/sveltekit/sveltekit.js.map +1 -0
- package/lib/cloudflare/tanstack-start/plugin.d.ts +16 -0
- package/lib/cloudflare/tanstack-start/plugin.d.ts.map +1 -0
- package/lib/cloudflare/tanstack-start/plugin.js +28 -0
- package/lib/cloudflare/tanstack-start/plugin.js.map +1 -0
- package/lib/cloudflare/{tanstack-start.d.ts → tanstack-start/tanstack-start.d.ts} +5 -5
- package/lib/cloudflare/tanstack-start/tanstack-start.d.ts.map +1 -0
- package/lib/cloudflare/tanstack-start/tanstack-start.js +11 -0
- package/lib/cloudflare/tanstack-start/tanstack-start.js.map +1 -0
- package/lib/cloudflare/vite/plugin.d.ts +4 -0
- package/lib/cloudflare/vite/plugin.d.ts.map +1 -0
- package/lib/cloudflare/vite/plugin.js +23 -0
- package/lib/cloudflare/vite/plugin.js.map +1 -0
- package/lib/cloudflare/{vite.d.ts → vite/vite.d.ts} +4 -4
- package/lib/cloudflare/vite/vite.d.ts.map +1 -0
- package/lib/cloudflare/vite/vite.js +19 -0
- package/lib/cloudflare/vite/vite.js.map +1 -0
- package/lib/cloudflare/website.d.ts +92 -70
- package/lib/cloudflare/website.d.ts.map +1 -1
- package/lib/cloudflare/website.js +225 -94
- package/lib/cloudflare/website.js.map +1 -1
- package/lib/cloudflare/worker-bundle.d.ts +3 -1
- package/lib/cloudflare/worker-bundle.d.ts.map +1 -1
- package/lib/cloudflare/worker-bundle.js +42 -16
- package/lib/cloudflare/worker-bundle.js.map +1 -1
- package/lib/cloudflare/worker-stub.d.ts.map +1 -1
- package/lib/cloudflare/worker-stub.js +3 -6
- package/lib/cloudflare/worker-stub.js.map +1 -1
- package/lib/cloudflare/worker.d.ts +2 -7
- package/lib/cloudflare/worker.d.ts.map +1 -1
- package/lib/cloudflare/worker.js +17 -157
- package/lib/cloudflare/worker.js.map +1 -1
- package/lib/cloudflare/wrangler.json.d.ts +6 -0
- package/lib/cloudflare/wrangler.json.d.ts.map +1 -1
- package/lib/cloudflare/wrangler.json.js +23 -6
- package/lib/cloudflare/wrangler.json.js.map +1 -1
- package/lib/context.d.ts +11 -0
- package/lib/context.d.ts.map +1 -1
- package/lib/context.js +8 -0
- package/lib/context.js.map +1 -1
- package/lib/env.d.ts +2 -2
- package/lib/env.d.ts.map +1 -1
- package/lib/env.js +5 -6
- package/lib/env.js.map +1 -1
- package/lib/random/index.d.ts +2 -0
- package/lib/random/index.d.ts.map +1 -0
- package/lib/random/index.js +2 -0
- package/lib/random/index.js.map +1 -0
- package/lib/random/random-string.d.ts +87 -0
- package/lib/random/random-string.d.ts.map +1 -0
- package/lib/random/random-string.js +72 -0
- package/lib/random/random-string.js.map +1 -0
- package/lib/runtime/bind.d.ts +1 -1
- package/lib/runtime/bind.d.ts.map +1 -1
- package/lib/runtime/bind.js.map +1 -1
- package/lib/scope.d.ts +11 -0
- package/lib/scope.d.ts.map +1 -1
- package/lib/scope.js +24 -0
- package/lib/scope.js.map +1 -1
- package/lib/secret.d.ts +2 -2
- package/lib/secret.d.ts.map +1 -1
- package/lib/secret.js +2 -2
- package/lib/secret.js.map +1 -1
- package/lib/state/cloudflare-state-store.js +1 -1
- package/lib/state/cloudflare-state-store.js.map +1 -1
- package/lib/state/dofs-state-store/index.js +1 -1
- package/lib/state/dofs-state-store/index.js.map +1 -1
- package/lib/util/detect-package-manager.d.ts +1 -0
- package/lib/util/detect-package-manager.d.ts.map +1 -1
- package/lib/util/detect-package-manager.js +10 -0
- package/lib/util/detect-package-manager.js.map +1 -1
- package/lib/util/telemetry/client.d.ts +1 -1
- package/lib/util/telemetry/client.d.ts.map +1 -1
- package/lib/util/telemetry/client.js +22 -1
- package/lib/util/telemetry/client.js.map +1 -1
- package/lib/util/telemetry/constants.d.ts.map +1 -1
- package/lib/util/telemetry/constants.js +2 -3
- package/lib/util/telemetry/constants.js.map +1 -1
- package/lib/util/telemetry/context.d.ts +1 -1
- package/lib/util/telemetry/context.d.ts.map +1 -1
- package/lib/util/telemetry/types.d.ts +7 -3
- package/lib/util/telemetry/types.d.ts.map +1 -1
- package/lib/vercel/api.d.ts.map +1 -1
- package/lib/vercel/api.js +1 -1
- package/lib/vercel/api.js.map +1 -1
- package/package.json +43 -4
- package/src/alchemy.ts +7 -0
- package/src/apply.ts +3 -7
- package/src/cloudflare/{astro.ts → astro/astro.ts} +46 -29
- package/src/cloudflare/astro/plugin.ts +11 -0
- package/src/cloudflare/bundle/plugin-hot-reload.ts +4 -3
- package/src/cloudflare/cloudflare-env-proxy.ts +50 -0
- package/src/cloudflare/compatibility-date.gen.ts +1 -1
- package/src/cloudflare/compatibility-presets.ts +1 -1
- package/src/cloudflare/d1-local-migrations.ts +1 -1
- package/src/cloudflare/index.ts +8 -8
- package/src/cloudflare/miniflare/build-worker-options.ts +454 -0
- package/src/cloudflare/miniflare/miniflare-controller.ts +129 -0
- package/src/cloudflare/miniflare/miniflare-worker-proxy.ts +6 -15
- package/src/cloudflare/miniflare/paths.ts +52 -0
- package/src/cloudflare/miniflare/remote-binding-proxy.ts +18 -23
- package/src/cloudflare/{nuxt.ts → nuxt/nuxt.ts} +11 -16
- package/src/cloudflare/nuxt/plugin.ts +18 -0
- package/src/cloudflare/oauth.ts +2 -2
- package/src/cloudflare/orange.ts +13 -23
- package/src/cloudflare/react-router/plugin.ts +13 -0
- package/src/cloudflare/react-router/react-router.ts +41 -0
- package/src/cloudflare/redwood/plugin.ts +20 -0
- package/src/cloudflare/{redwood.ts → redwood/redwood.ts} +16 -19
- package/src/cloudflare/sveltekit/plugin.ts +12 -0
- package/src/cloudflare/{sveltekit.ts → sveltekit/sveltekit.ts} +9 -8
- package/src/cloudflare/tanstack-start/plugin.ts +30 -0
- package/src/cloudflare/tanstack-start/tanstack-start.ts +24 -0
- package/src/cloudflare/vite/plugin.ts +30 -0
- package/src/cloudflare/vite/vite.ts +34 -0
- package/src/cloudflare/website.ts +379 -204
- package/src/cloudflare/worker-bundle.ts +55 -16
- package/src/cloudflare/worker-stub.ts +11 -14
- package/src/cloudflare/worker.ts +23 -205
- package/src/cloudflare/wrangler.json.ts +32 -4
- package/src/context.ts +19 -0
- package/src/env.ts +8 -9
- package/src/random/index.ts +1 -0
- package/src/random/random-string.ts +126 -0
- package/src/runtime/bind.ts +2 -2
- package/src/scope.ts +25 -0
- package/src/secret.ts +4 -8
- package/src/state/cloudflare-state-store.ts +2 -2
- package/src/state/dofs-state-store/index.ts +1 -1
- package/src/util/detect-package-manager.ts +11 -0
- package/src/util/telemetry/client.ts +25 -2
- package/src/util/telemetry/constants.ts +2 -4
- package/src/util/telemetry/context.ts +1 -1
- package/src/util/telemetry/types.ts +8 -2
- package/src/vercel/api.ts +2 -4
- package/templates/astro/alchemy.run.ts +1 -3
- package/templates/astro/astro.config.mjs +2 -2
- package/templates/nuxt/alchemy.run.ts +1 -3
- package/templates/nuxt/nuxt.config.ts +4 -5
- package/templates/nuxt/package.json +0 -1
- package/templates/react-router/alchemy.run.ts +1 -4
- package/templates/react-router/vite.config.ts +2 -2
- package/templates/rwsdk/alchemy.run.ts +0 -1
- package/templates/rwsdk/package.json +0 -2
- package/templates/rwsdk/vite.config.mts +2 -2
- package/templates/sveltekit/alchemy.run.ts +1 -3
- package/templates/sveltekit/svelte.config.js +2 -2
- package/templates/tanstack-start/vite.config.ts +2 -2
- package/templates/vite/alchemy.run.ts +1 -1
- package/templates/vite/vite.config.ts +4 -5
- package/workers/cloudflare-state-store.js +12 -14
- package/lib/cloudflare/astro.d.ts.map +0 -1
- package/lib/cloudflare/astro.js +0 -69
- package/lib/cloudflare/astro.js.map +0 -1
- package/lib/cloudflare/local-dev-cloudflare-shim.d.ts +0 -13
- package/lib/cloudflare/local-dev-cloudflare-shim.d.ts.map +0 -1
- package/lib/cloudflare/local-dev-cloudflare-shim.js +0 -26
- package/lib/cloudflare/local-dev-cloudflare-shim.js.map +0 -1
- package/lib/cloudflare/miniflare/miniflare-worker-options.d.ts +0 -14
- package/lib/cloudflare/miniflare/miniflare-worker-options.d.ts.map +0 -1
- package/lib/cloudflare/miniflare/miniflare-worker-options.js +0 -468
- package/lib/cloudflare/miniflare/miniflare-worker-options.js.map +0 -1
- package/lib/cloudflare/miniflare/miniflare.d.ts +0 -40
- package/lib/cloudflare/miniflare/miniflare.d.ts.map +0 -1
- package/lib/cloudflare/miniflare/miniflare.js +0 -142
- package/lib/cloudflare/miniflare/miniflare.js.map +0 -1
- package/lib/cloudflare/nuxt.d.ts.map +0 -1
- package/lib/cloudflare/nuxt.js.map +0 -1
- package/lib/cloudflare/react-router.d.ts +0 -17
- package/lib/cloudflare/react-router.d.ts.map +0 -1
- package/lib/cloudflare/react-router.js +0 -35
- package/lib/cloudflare/react-router.js.map +0 -1
- package/lib/cloudflare/redwood.d.ts.map +0 -1
- package/lib/cloudflare/redwood.js.map +0 -1
- package/lib/cloudflare/sveltekit.d.ts.map +0 -1
- package/lib/cloudflare/sveltekit.js.map +0 -1
- package/lib/cloudflare/tanstack-start.d.ts.map +0 -1
- package/lib/cloudflare/tanstack-start.js +0 -21
- package/lib/cloudflare/tanstack-start.js.map +0 -1
- package/lib/cloudflare/vite.d.ts.map +0 -1
- package/lib/cloudflare/vite.js +0 -20
- package/lib/cloudflare/vite.js.map +0 -1
- package/src/cloudflare/local-dev-cloudflare-shim.ts +0 -25
- package/src/cloudflare/miniflare/miniflare-worker-options.ts +0 -599
- package/src/cloudflare/miniflare/miniflare.ts +0 -183
- package/src/cloudflare/react-router.ts +0 -56
- package/src/cloudflare/tanstack-start.ts +0 -35
- package/src/cloudflare/vite.ts +0 -35
- package/templates/react-router/wrangler.jsonc +0 -6
- package/templates/rwsdk/wrangler.jsonc +0 -31
- package/templates/sveltekit/wrangler.jsonc +0 -7
- package/templates/tanstack-start/wrangler.jsonc +0 -7
- package/templates/typescript/index.ts +0 -1
- package/templates/vite/wrangler.jsonc +0 -6
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import esbuild from "esbuild";
|
|
2
2
|
import { err, ok, type Result } from "neverthrow";
|
|
3
3
|
import fs from "node:fs/promises";
|
|
4
|
-
import path from "
|
|
4
|
+
import path from "pathe";
|
|
5
|
+
import { logger } from "../util/logger.ts";
|
|
5
6
|
import { external, external_als } from "./bundle/externals.ts";
|
|
6
7
|
import { esbuildPluginAlias } from "./bundle/plugin-alias.ts";
|
|
7
8
|
import { esbuildPluginCompatWarning } from "./bundle/plugin-compat-warning.ts";
|
|
@@ -17,6 +18,7 @@ export interface WorkerBundle {
|
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
export function normalizeWorkerBundle(props: {
|
|
21
|
+
id: string;
|
|
20
22
|
script: string | undefined;
|
|
21
23
|
entrypoint: string | undefined;
|
|
22
24
|
noBundle: boolean | undefined;
|
|
@@ -66,12 +68,13 @@ export function normalizeWorkerBundle(props: {
|
|
|
66
68
|
sourcemaps: props.sourceMap !== false,
|
|
67
69
|
})
|
|
68
70
|
: new WorkerBundleSource.ESBuild({
|
|
71
|
+
id: props.id,
|
|
69
72
|
entrypoint: props.entrypoint,
|
|
70
73
|
format: props.format ?? "esm",
|
|
71
74
|
nodeCompat,
|
|
72
75
|
cwd: props.cwd,
|
|
73
76
|
outdir: props.outdir,
|
|
74
|
-
sourcemap: props.sourceMap !== false ?
|
|
77
|
+
sourcemap: props.sourceMap !== false ? true : undefined,
|
|
75
78
|
...props.bundle,
|
|
76
79
|
}),
|
|
77
80
|
);
|
|
@@ -125,7 +128,8 @@ export namespace WorkerBundle {
|
|
|
125
128
|
(await fs.readFile(path.join(bundle.root!, module.path)));
|
|
126
129
|
form.append(
|
|
127
130
|
module.path,
|
|
128
|
-
|
|
131
|
+
// TODO(sam): tsc -b geting a weird error about SharedArrayBuffer
|
|
132
|
+
new Blob([content as any as BlobPart], {
|
|
129
133
|
type: types[module.type],
|
|
130
134
|
}),
|
|
131
135
|
module.path,
|
|
@@ -238,6 +242,7 @@ export namespace WorkerBundleSource {
|
|
|
238
242
|
esbuild.BuildOptions,
|
|
239
243
|
"entryPoints" | "format" | "absWorkingDir" | "outdir"
|
|
240
244
|
> {
|
|
245
|
+
id: string;
|
|
241
246
|
entrypoint: string;
|
|
242
247
|
cwd: string;
|
|
243
248
|
outdir: string;
|
|
@@ -262,7 +267,7 @@ export namespace WorkerBundleSource {
|
|
|
262
267
|
const wasmPlugin = createWasmPlugin();
|
|
263
268
|
const options = this.buildOptions([wasmPlugin.plugin]);
|
|
264
269
|
const result = await esbuild.build(options);
|
|
265
|
-
const { entrypoint, root, modules } = this.
|
|
270
|
+
const { entrypoint, root, modules } = await this.formatBuildOutput(
|
|
266
271
|
result.metafile,
|
|
267
272
|
);
|
|
268
273
|
return {
|
|
@@ -274,7 +279,20 @@ export namespace WorkerBundleSource {
|
|
|
274
279
|
|
|
275
280
|
async *watch(signal: AbortSignal): AsyncIterable<WorkerBundle> {
|
|
276
281
|
const wasm = createWasmPlugin();
|
|
277
|
-
|
|
282
|
+
let count = 0;
|
|
283
|
+
const hotReload = createHotReloadPlugin({
|
|
284
|
+
onBuildStart: () => {
|
|
285
|
+
if (count > 0) {
|
|
286
|
+
logger.task(this.props.id, {
|
|
287
|
+
message: "Rebuilding",
|
|
288
|
+
status: "pending",
|
|
289
|
+
resource: this.props.id,
|
|
290
|
+
prefix: "dev",
|
|
291
|
+
prefixColor: "cyanBright",
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
},
|
|
295
|
+
});
|
|
278
296
|
const options = this.buildOptions([wasm.plugin, hotReload.plugin]);
|
|
279
297
|
|
|
280
298
|
const context = await esbuild.context(options);
|
|
@@ -282,7 +300,8 @@ export namespace WorkerBundleSource {
|
|
|
282
300
|
await context.watch();
|
|
283
301
|
|
|
284
302
|
for await (const result of hotReload.iterator) {
|
|
285
|
-
|
|
303
|
+
count++;
|
|
304
|
+
const { entrypoint, root, modules } = await this.formatBuildOutput(
|
|
286
305
|
result.metafile!,
|
|
287
306
|
);
|
|
288
307
|
yield {
|
|
@@ -301,24 +320,38 @@ export namespace WorkerBundleSource {
|
|
|
301
320
|
}
|
|
302
321
|
|
|
303
322
|
private buildOptions(additionalPlugins: esbuild.Plugin[]) {
|
|
304
|
-
const {
|
|
323
|
+
const {
|
|
324
|
+
id: _,
|
|
325
|
+
entrypoint,
|
|
326
|
+
nodeCompat,
|
|
327
|
+
cwd,
|
|
328
|
+
format,
|
|
329
|
+
...props
|
|
330
|
+
} = this.props;
|
|
305
331
|
return {
|
|
306
332
|
entryPoints: [entrypoint],
|
|
307
333
|
absWorkingDir: cwd,
|
|
334
|
+
target: "es2022",
|
|
335
|
+
loader: {
|
|
336
|
+
".js": "jsx",
|
|
337
|
+
".mjs": "jsx",
|
|
338
|
+
".cjs": "jsx",
|
|
339
|
+
},
|
|
308
340
|
format,
|
|
309
|
-
|
|
341
|
+
sourceRoot: this.props.outdir,
|
|
342
|
+
jsxFactory: "React.createElement",
|
|
343
|
+
jsxFragment: "React.Fragment",
|
|
344
|
+
keepNames: true,
|
|
310
345
|
...props,
|
|
311
346
|
metafile: true,
|
|
312
347
|
write: true,
|
|
313
348
|
bundle: true,
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
".json": "json",
|
|
319
|
-
".wasm": "binary",
|
|
320
|
-
...props.loader,
|
|
349
|
+
define: {
|
|
350
|
+
"navigator.userAgent": '"Cloudflare-Workers"',
|
|
351
|
+
"process.env.NODE_ENV": '"undefined"',
|
|
352
|
+
...props.define,
|
|
321
353
|
},
|
|
354
|
+
conditions: props.conditions ?? ["workerd", "worker", "browser"],
|
|
322
355
|
plugins: [
|
|
323
356
|
esbuildPluginAlias(props.alias ?? {}, this.props.cwd),
|
|
324
357
|
nodeCompat === "v2"
|
|
@@ -334,8 +367,14 @@ export namespace WorkerBundleSource {
|
|
|
334
367
|
} satisfies esbuild.BuildOptions;
|
|
335
368
|
}
|
|
336
369
|
|
|
337
|
-
private
|
|
370
|
+
private async formatBuildOutput(
|
|
371
|
+
metafile: esbuild.Metafile,
|
|
372
|
+
): Promise<WorkerBundle> {
|
|
338
373
|
const outdir = path.resolve(this.props.cwd, this.props.outdir);
|
|
374
|
+
await fs.writeFile(
|
|
375
|
+
path.join(outdir, "metafile.json"),
|
|
376
|
+
JSON.stringify(metafile, null, 2),
|
|
377
|
+
);
|
|
339
378
|
const paths: string[] = [];
|
|
340
379
|
let entrypoint: string | undefined;
|
|
341
380
|
for (const [key, value] of Object.entries(metafile.outputs)) {
|
|
@@ -2,6 +2,7 @@ import type { Context } from "../context.ts";
|
|
|
2
2
|
import { Resource, ResourceKind } from "../resource.ts";
|
|
3
3
|
import type { type } from "../type.ts";
|
|
4
4
|
import { handleApiError } from "./api-error.ts";
|
|
5
|
+
import { extractCloudflareResult } from "./api-response.ts";
|
|
5
6
|
import {
|
|
6
7
|
createCloudflareApi,
|
|
7
8
|
type CloudflareApi,
|
|
@@ -185,20 +186,16 @@ async function createEmptyWorker(
|
|
|
185
186
|
);
|
|
186
187
|
|
|
187
188
|
// Upload worker script
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
189
|
+
await extractCloudflareResult(
|
|
190
|
+
`create empty worker "${workerName}"`,
|
|
191
|
+
api.put(
|
|
192
|
+
`/accounts/${api.accountId}/workers/scripts/${workerName}`,
|
|
193
|
+
formData,
|
|
194
|
+
{
|
|
195
|
+
headers: {
|
|
196
|
+
"Content-Type": "multipart/form-data",
|
|
197
|
+
},
|
|
194
198
|
},
|
|
195
|
-
|
|
199
|
+
),
|
|
196
200
|
);
|
|
197
|
-
|
|
198
|
-
// Check if the upload was successful
|
|
199
|
-
if (!uploadResponse.ok) {
|
|
200
|
-
throw new Error(
|
|
201
|
-
`Failed to create empty worker: ${uploadResponse.status} ${uploadResponse.statusText}`,
|
|
202
|
-
);
|
|
203
|
-
}
|
|
204
201
|
}
|
package/src/cloudflare/worker.ts
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
import kleur from "kleur";
|
|
2
|
-
import { spawn } from "node:child_process";
|
|
3
|
-
import fs from "node:fs/promises";
|
|
4
1
|
import { isDeepStrictEqual } from "node:util";
|
|
5
2
|
import path from "pathe";
|
|
6
3
|
import type { Context } from "../context.ts";
|
|
7
4
|
import type { BundleProps } from "../esbuild/bundle.ts";
|
|
8
5
|
import { Resource, ResourceKind } from "../resource.ts";
|
|
9
|
-
import { isSecret } from "../secret.ts";
|
|
10
6
|
import type { type } from "../type.ts";
|
|
11
7
|
import { DeferredPromise } from "../util/deferred-promise.ts";
|
|
12
8
|
import { logger } from "../util/logger.ts";
|
|
@@ -38,8 +34,6 @@ import {
|
|
|
38
34
|
isDurableObjectNamespace,
|
|
39
35
|
} from "./durable-object-namespace.ts";
|
|
40
36
|
import { type EventSource, isQueueEventSource } from "./event-source.ts";
|
|
41
|
-
import type { MiniflareWorkerOptions } from "./miniflare/miniflare-worker-options.ts";
|
|
42
|
-
import { miniflareServer } from "./miniflare/miniflare.ts";
|
|
43
37
|
import {
|
|
44
38
|
QueueConsumer,
|
|
45
39
|
deleteQueueConsumer,
|
|
@@ -48,11 +42,7 @@ import {
|
|
|
48
42
|
import { isQueue } from "./queue.ts";
|
|
49
43
|
import { Route } from "./route.ts";
|
|
50
44
|
import { uploadAssets } from "./worker-assets.ts";
|
|
51
|
-
import {
|
|
52
|
-
WorkerBundle,
|
|
53
|
-
type WorkerBundleSource,
|
|
54
|
-
normalizeWorkerBundle,
|
|
55
|
-
} from "./worker-bundle.ts";
|
|
45
|
+
import { WorkerBundle, normalizeWorkerBundle } from "./worker-bundle.ts";
|
|
56
46
|
import {
|
|
57
47
|
type WorkerScriptMetadata,
|
|
58
48
|
bumpMigrationTagVersion,
|
|
@@ -65,7 +55,6 @@ import { Workflow, isWorkflow, upsertWorkflow } from "./workflow.ts";
|
|
|
65
55
|
// Previous versions of `Worker` used the `Bundle` resource.
|
|
66
56
|
// This import is here to avoid errors when destroying the `Bundle` resource.
|
|
67
57
|
import "../esbuild/bundle.ts";
|
|
68
|
-
import { exists } from "../util/exists.ts";
|
|
69
58
|
|
|
70
59
|
/**
|
|
71
60
|
* Configuration options for static assets
|
|
@@ -338,15 +327,10 @@ export interface BaseWorkerProps<
|
|
|
338
327
|
* @default false
|
|
339
328
|
*/
|
|
340
329
|
remote?: boolean;
|
|
341
|
-
|
|
342
|
-
command?: undefined;
|
|
330
|
+
url?: undefined;
|
|
343
331
|
}
|
|
344
332
|
| {
|
|
345
|
-
|
|
346
|
-
cwd?: string;
|
|
347
|
-
/** @internal */
|
|
348
|
-
port?: undefined;
|
|
349
|
-
/** @internal */
|
|
333
|
+
url: string;
|
|
350
334
|
remote?: undefined;
|
|
351
335
|
};
|
|
352
336
|
|
|
@@ -736,6 +720,7 @@ const _Worker = Resource(
|
|
|
736
720
|
: props.namespace?.namespaceName;
|
|
737
721
|
|
|
738
722
|
const bundleSourceResult = normalizeWorkerBundle({
|
|
723
|
+
id,
|
|
739
724
|
entrypoint: props.entrypoint,
|
|
740
725
|
script: props.script,
|
|
741
726
|
format: props.format,
|
|
@@ -746,8 +731,7 @@ const _Worker = Resource(
|
|
|
746
731
|
compatibilityDate,
|
|
747
732
|
compatibilityFlags,
|
|
748
733
|
outdir:
|
|
749
|
-
props.bundle?.outdir ??
|
|
750
|
-
path.join(cwd, ".alchemy", ...this.scope.chain, id),
|
|
734
|
+
props.bundle?.outdir ?? path.join(cwd, ".alchemy", "out", workerName),
|
|
751
735
|
sourceMap: "sourceMap" in props ? props.sourceMap : undefined,
|
|
752
736
|
});
|
|
753
737
|
|
|
@@ -761,37 +745,25 @@ const _Worker = Resource(
|
|
|
761
745
|
throw bundleSourceResult.error;
|
|
762
746
|
}
|
|
763
747
|
|
|
764
|
-
if (props.dev
|
|
765
|
-
|
|
766
|
-
id,
|
|
767
|
-
command: props.dev.command,
|
|
768
|
-
cwd: props.dev.cwd || props.cwd || process.cwd(),
|
|
769
|
-
env: {
|
|
770
|
-
...(process.env ?? {}),
|
|
771
|
-
...props.env,
|
|
772
|
-
...Object.fromEntries(
|
|
773
|
-
Object.entries(props.bindings ?? {}).flatMap(([key, value]) =>
|
|
774
|
-
typeof value === "string"
|
|
775
|
-
? [[key, value]]
|
|
776
|
-
: isSecret(value)
|
|
777
|
-
? [[key, value.unencrypted]]
|
|
778
|
-
: [],
|
|
779
|
-
),
|
|
780
|
-
),
|
|
781
|
-
},
|
|
782
|
-
});
|
|
783
|
-
url = commandUrl;
|
|
748
|
+
if (props.dev && "url" in props.dev) {
|
|
749
|
+
url = props.dev.url;
|
|
784
750
|
} else {
|
|
785
|
-
|
|
751
|
+
const { MiniflareController } = await import(
|
|
752
|
+
"./miniflare/miniflare-controller.js"
|
|
753
|
+
);
|
|
754
|
+
const controller = MiniflareController.singleton;
|
|
755
|
+
url = await controller.add({
|
|
786
756
|
id,
|
|
787
|
-
workerName,
|
|
757
|
+
name: workerName,
|
|
788
758
|
compatibilityDate,
|
|
789
759
|
compatibilityFlags,
|
|
790
760
|
bindings: props.bindings,
|
|
791
|
-
|
|
792
|
-
port: props.dev?.port,
|
|
761
|
+
eventSources: props.eventSources,
|
|
793
762
|
assets: props.assets,
|
|
763
|
+
bundle: bundleSourceResult.value,
|
|
764
|
+
port: props.dev?.port ?? undefined,
|
|
794
765
|
});
|
|
766
|
+
this.onCleanup(() => controller.dispose());
|
|
795
767
|
}
|
|
796
768
|
|
|
797
769
|
return this({
|
|
@@ -848,7 +820,7 @@ const _Worker = Resource(
|
|
|
848
820
|
const oldName = this.output.name ?? this.output.id;
|
|
849
821
|
const newName = workerName;
|
|
850
822
|
|
|
851
|
-
if (oldName !== newName) {
|
|
823
|
+
if (oldName && oldName !== newName) {
|
|
852
824
|
if (dispatchNamespace) {
|
|
853
825
|
this.replace(true);
|
|
854
826
|
} else {
|
|
@@ -926,7 +898,6 @@ const _Worker = Resource(
|
|
|
926
898
|
let putWorkerResult: PutWorkerResult;
|
|
927
899
|
if (watch) {
|
|
928
900
|
const controller = new AbortController();
|
|
929
|
-
cleanups.push(() => controller.abort());
|
|
930
901
|
const promise = new DeferredPromise<PutWorkerResult>();
|
|
931
902
|
const runWatch = async () => {
|
|
932
903
|
for await (const bundle of bundleSource.watch(controller.signal)) {
|
|
@@ -973,14 +944,12 @@ const _Worker = Resource(
|
|
|
973
944
|
}
|
|
974
945
|
};
|
|
975
946
|
void runWatch(); // this is not awaited because it's an ongoing process
|
|
947
|
+
this.onCleanup(() => controller.abort());
|
|
976
948
|
putWorkerResult = await promise.value;
|
|
977
|
-
await createTail(api, id, workerName)
|
|
978
|
-
.
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
.catch((error) => {
|
|
982
|
-
logger.error(`Failed to create tail for ${workerName}`, error);
|
|
983
|
-
});
|
|
949
|
+
const tail = await createTail(api, id, workerName).catch((error) => {
|
|
950
|
+
logger.error(`Failed to create tail for ${workerName}`, error);
|
|
951
|
+
});
|
|
952
|
+
this.onCleanup(() => tail?.close());
|
|
984
953
|
} else {
|
|
985
954
|
const scriptBundle = await bundleSource.create();
|
|
986
955
|
putWorkerResult = await putWorkerWithAssets(props, scriptBundle);
|
|
@@ -1102,22 +1071,6 @@ const _Worker = Resource(
|
|
|
1102
1071
|
},
|
|
1103
1072
|
);
|
|
1104
1073
|
|
|
1105
|
-
const cleanups: (() => any)[] = [];
|
|
1106
|
-
let exiting = false;
|
|
1107
|
-
|
|
1108
|
-
process.on("SIGINT", async () => {
|
|
1109
|
-
if (cleanups.length > 0) {
|
|
1110
|
-
if (!exiting) {
|
|
1111
|
-
exiting = true;
|
|
1112
|
-
logger.log(`\n${kleur.gray("Exiting...")}`);
|
|
1113
|
-
}
|
|
1114
|
-
// TODO: for some reason this runs twice...
|
|
1115
|
-
// and this whole thing feels hacky anyway
|
|
1116
|
-
await Promise.allSettled(cleanups.map((cleanup) => cleanup()));
|
|
1117
|
-
}
|
|
1118
|
-
process.exit(0);
|
|
1119
|
-
});
|
|
1120
|
-
|
|
1121
1074
|
const assertUnique = <T, Key extends keyof T>(
|
|
1122
1075
|
inputs: T[],
|
|
1123
1076
|
key: Key,
|
|
@@ -1337,141 +1290,6 @@ async function provisionSubdomain(
|
|
|
1337
1290
|
}
|
|
1338
1291
|
}
|
|
1339
1292
|
|
|
1340
|
-
async function createMiniflare(props: {
|
|
1341
|
-
id: string;
|
|
1342
|
-
workerName: string;
|
|
1343
|
-
compatibilityDate: string;
|
|
1344
|
-
compatibilityFlags: string[];
|
|
1345
|
-
bindings: Bindings | undefined;
|
|
1346
|
-
port: number | undefined;
|
|
1347
|
-
bundle: WorkerBundleSource;
|
|
1348
|
-
assets: AssetsConfig | undefined;
|
|
1349
|
-
}) {
|
|
1350
|
-
const sharedOptions: Omit<MiniflareWorkerOptions, "bundle"> = {
|
|
1351
|
-
name: props.workerName,
|
|
1352
|
-
compatibilityDate: props.compatibilityDate,
|
|
1353
|
-
compatibilityFlags: props.compatibilityFlags,
|
|
1354
|
-
bindings: props.bindings,
|
|
1355
|
-
port: props.port,
|
|
1356
|
-
assets: props.assets,
|
|
1357
|
-
};
|
|
1358
|
-
|
|
1359
|
-
const startPromise = new DeferredPromise<string>();
|
|
1360
|
-
const controller = new AbortController();
|
|
1361
|
-
cleanups.push(() => controller.abort());
|
|
1362
|
-
const run = async () => {
|
|
1363
|
-
for await (const bundle of props.bundle.watch(controller.signal)) {
|
|
1364
|
-
const server = await miniflareServer.push({
|
|
1365
|
-
...sharedOptions,
|
|
1366
|
-
bundle,
|
|
1367
|
-
});
|
|
1368
|
-
if (startPromise.status === "pending") {
|
|
1369
|
-
startPromise.resolve(server.url);
|
|
1370
|
-
}
|
|
1371
|
-
logger.task("", {
|
|
1372
|
-
message: `ready at ${server.url}`,
|
|
1373
|
-
status: "success",
|
|
1374
|
-
resource: props.id,
|
|
1375
|
-
prefix: "miniflare",
|
|
1376
|
-
prefixColor: "greenBright",
|
|
1377
|
-
});
|
|
1378
|
-
}
|
|
1379
|
-
};
|
|
1380
|
-
void run();
|
|
1381
|
-
return await startPromise.value;
|
|
1382
|
-
}
|
|
1383
|
-
|
|
1384
|
-
async function createDevCommand(props: {
|
|
1385
|
-
id: string;
|
|
1386
|
-
command: string;
|
|
1387
|
-
cwd: string;
|
|
1388
|
-
env: Record<string, string | undefined>;
|
|
1389
|
-
}): Promise<{ url: string }> {
|
|
1390
|
-
const persistFile = path.join(process.cwd(), ".alchemy", `${props.id}.pid`);
|
|
1391
|
-
if (await exists(persistFile)) {
|
|
1392
|
-
const pid = Number.parseInt(await fs.readFile(persistFile, "utf8"));
|
|
1393
|
-
try {
|
|
1394
|
-
// Actually kill the process if it's alive
|
|
1395
|
-
process.kill(pid, "SIGTERM");
|
|
1396
|
-
} catch {
|
|
1397
|
-
// ignore
|
|
1398
|
-
}
|
|
1399
|
-
try {
|
|
1400
|
-
await fs.unlink(persistFile);
|
|
1401
|
-
} catch {
|
|
1402
|
-
// ignore
|
|
1403
|
-
}
|
|
1404
|
-
}
|
|
1405
|
-
const command = props.command.split(" ");
|
|
1406
|
-
const [cmd, ...args] = command;
|
|
1407
|
-
const proc = spawn(cmd, args, {
|
|
1408
|
-
cwd: props.cwd,
|
|
1409
|
-
shell: true,
|
|
1410
|
-
env: {
|
|
1411
|
-
...process.env,
|
|
1412
|
-
...props.env,
|
|
1413
|
-
ALCHEMY_CLOUDFLARE_PERSIST_PATH: path.join(
|
|
1414
|
-
process.cwd(),
|
|
1415
|
-
".alchemy",
|
|
1416
|
-
"miniflare",
|
|
1417
|
-
),
|
|
1418
|
-
// Force colors in the child process since we're piping output
|
|
1419
|
-
// FORCE_COLOR: "1",
|
|
1420
|
-
},
|
|
1421
|
-
stdio: ["inherit", "pipe", "pipe"],
|
|
1422
|
-
});
|
|
1423
|
-
const { url } = await new Promise<{ url: string }>((resolve, reject) => {
|
|
1424
|
-
let urlFound = false;
|
|
1425
|
-
let stdout = "";
|
|
1426
|
-
let stderr = "";
|
|
1427
|
-
const urlRegex =
|
|
1428
|
-
/http:\/\/(?:(?:localhost|0\.0\.0\.0|127\.0\.0\.1)|(?:\d{1,3}\.){3}\d{1,3}):\d+(?:\/)?/;
|
|
1429
|
-
|
|
1430
|
-
const parseOutput = (data: string) => {
|
|
1431
|
-
if (!urlFound) {
|
|
1432
|
-
const match = data.match(urlRegex);
|
|
1433
|
-
if (match) {
|
|
1434
|
-
urlFound = true;
|
|
1435
|
-
resolve({ url: match[0] });
|
|
1436
|
-
}
|
|
1437
|
-
}
|
|
1438
|
-
};
|
|
1439
|
-
|
|
1440
|
-
// Handle stdout - parse for URL and write through with colors preserved
|
|
1441
|
-
proc.stdout?.on("data", (data) => {
|
|
1442
|
-
parseOutput(
|
|
1443
|
-
(stdout += data.toString().replace(/\x1B\[[0-9;]*[a-zA-Z]/g, "")),
|
|
1444
|
-
);
|
|
1445
|
-
process.stdout.write(data);
|
|
1446
|
-
});
|
|
1447
|
-
|
|
1448
|
-
proc.stderr?.on("data", (data) => {
|
|
1449
|
-
parseOutput(
|
|
1450
|
-
(stderr += data.toString().replace(/\x1B\[[0-9;]*[a-zA-Z]/g, "")),
|
|
1451
|
-
);
|
|
1452
|
-
process.stderr.write(data);
|
|
1453
|
-
});
|
|
1454
|
-
|
|
1455
|
-
proc.on("error", (error) => {
|
|
1456
|
-
reject(error);
|
|
1457
|
-
});
|
|
1458
|
-
|
|
1459
|
-
cleanups.push(async () => {
|
|
1460
|
-
try {
|
|
1461
|
-
await fs.unlink(persistFile);
|
|
1462
|
-
} catch {
|
|
1463
|
-
// ignore
|
|
1464
|
-
}
|
|
1465
|
-
proc.kill();
|
|
1466
|
-
});
|
|
1467
|
-
});
|
|
1468
|
-
if (proc.pid) {
|
|
1469
|
-
await fs.mkdir(path.dirname(persistFile), { recursive: true });
|
|
1470
|
-
await fs.writeFile(persistFile, proc.pid.toString());
|
|
1471
|
-
}
|
|
1472
|
-
return { url };
|
|
1473
|
-
}
|
|
1474
|
-
|
|
1475
1293
|
type PutWorkerOptions = Omit<WorkerProps, "entrypoint"> & {
|
|
1476
1294
|
dispatchNamespace?: string;
|
|
1477
1295
|
migrationTag?: string;
|
|
@@ -3,6 +3,7 @@ import path from "node:path";
|
|
|
3
3
|
import type { Context } from "../context.ts";
|
|
4
4
|
import { formatJson } from "../fs/static-json-file.ts";
|
|
5
5
|
import { Resource } from "../resource.ts";
|
|
6
|
+
import { isSecret } from "../secret.ts";
|
|
6
7
|
import { assertNever } from "../util/assert-never.ts";
|
|
7
8
|
import {
|
|
8
9
|
Self,
|
|
@@ -56,6 +57,13 @@ export interface WranglerJsonProps {
|
|
|
56
57
|
directory: string;
|
|
57
58
|
};
|
|
58
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Whether to include secrets in the wrangler.json file
|
|
62
|
+
*
|
|
63
|
+
* @default true
|
|
64
|
+
*/
|
|
65
|
+
secrets?: boolean;
|
|
66
|
+
|
|
59
67
|
/**
|
|
60
68
|
* Transform hooks to modify generated configuration files
|
|
61
69
|
*/
|
|
@@ -169,6 +177,7 @@ export const WranglerJson = Resource(
|
|
|
169
177
|
worker.eventSources,
|
|
170
178
|
worker.name,
|
|
171
179
|
cwd,
|
|
180
|
+
props.secrets ?? false,
|
|
172
181
|
);
|
|
173
182
|
}
|
|
174
183
|
|
|
@@ -191,7 +200,24 @@ export const WranglerJson = Resource(
|
|
|
191
200
|
: spec;
|
|
192
201
|
|
|
193
202
|
await fs.mkdir(dirname, { recursive: true });
|
|
194
|
-
|
|
203
|
+
if (props.secrets) {
|
|
204
|
+
// If secrets are enabled, decrypt them in the wrangler.json file,
|
|
205
|
+
// but do not modify `finalSpec` so that way secrets aren't written to state unencrypted.
|
|
206
|
+
const withSecretsUnwrapped = {
|
|
207
|
+
...finalSpec,
|
|
208
|
+
vars: {
|
|
209
|
+
...finalSpec.vars,
|
|
210
|
+
...Object.fromEntries(
|
|
211
|
+
Object.entries(finalSpec.vars ?? {}).map(([key, value]) =>
|
|
212
|
+
isSecret(value) ? [key, value.unencrypted] : [key, value],
|
|
213
|
+
),
|
|
214
|
+
),
|
|
215
|
+
},
|
|
216
|
+
};
|
|
217
|
+
await fs.writeFile(filePath, await formatJson(withSecretsUnwrapped));
|
|
218
|
+
} else {
|
|
219
|
+
await fs.writeFile(filePath, await formatJson(finalSpec));
|
|
220
|
+
}
|
|
195
221
|
|
|
196
222
|
// Return the resource
|
|
197
223
|
return this({
|
|
@@ -473,6 +499,7 @@ function processBindings(
|
|
|
473
499
|
eventSources: EventSource[] | undefined,
|
|
474
500
|
workerName: string,
|
|
475
501
|
workerCwd: string,
|
|
502
|
+
writeSecrets: boolean,
|
|
476
503
|
): void {
|
|
477
504
|
// Arrays to collect different binding types
|
|
478
505
|
const kvNamespaces: {
|
|
@@ -578,10 +605,11 @@ function processBindings(
|
|
|
578
605
|
}
|
|
579
606
|
if (typeof binding === "string") {
|
|
580
607
|
// Plain text binding - add to vars
|
|
581
|
-
|
|
582
|
-
spec.vars = {};
|
|
583
|
-
}
|
|
608
|
+
spec.vars ??= {};
|
|
584
609
|
spec.vars[bindingName] = binding;
|
|
610
|
+
} else if (writeSecrets && isSecret(binding)) {
|
|
611
|
+
spec.vars ??= {};
|
|
612
|
+
spec.vars[bindingName] = binding as any;
|
|
585
613
|
} else if (binding === Self) {
|
|
586
614
|
// Self(service) binding
|
|
587
615
|
services.push({
|
package/src/context.ts
CHANGED
|
@@ -67,6 +67,17 @@ export interface BaseContext<Out extends Resource> {
|
|
|
67
67
|
* "return undefined" so that `await MyResource()` always returns a value.
|
|
68
68
|
*/
|
|
69
69
|
destroy(): never;
|
|
70
|
+
/**
|
|
71
|
+
* Register a cleanup function that will be called when the process exits.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* const proc = spawn('my-command', ['arg1', 'arg2']);
|
|
75
|
+
* this.onCleanup(async () => {
|
|
76
|
+
* proc.kill();
|
|
77
|
+
* await waitForExit(proc);
|
|
78
|
+
* });
|
|
79
|
+
*/
|
|
80
|
+
onCleanup(fn: () => void | Promise<void>): void;
|
|
70
81
|
/**
|
|
71
82
|
* Create the Resource envelope (with Alchemy + User properties)
|
|
72
83
|
*/
|
|
@@ -153,6 +164,14 @@ export function context<
|
|
|
153
164
|
destroy: () => {
|
|
154
165
|
throw new DestroyedSignal();
|
|
155
166
|
},
|
|
167
|
+
onCleanup: (fn: () => void | Promise<void>) => {
|
|
168
|
+
// make the function idempotent so repeated calls don't cause the process to hang
|
|
169
|
+
let promise: Promise<void> | undefined;
|
|
170
|
+
scope.root.onCleanup(async () => {
|
|
171
|
+
promise ??= Promise.resolve(fn());
|
|
172
|
+
await promise;
|
|
173
|
+
});
|
|
174
|
+
},
|
|
156
175
|
create,
|
|
157
176
|
}) as unknown as Context<Out>;
|
|
158
177
|
}
|
package/src/env.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export interface Env {
|
|
2
|
-
[key: string]:
|
|
3
|
-
<T = string>(name: string, value?: T | undefined, error?: string):
|
|
2
|
+
[key: string]: string;
|
|
3
|
+
<T = string>(name: string, value?: T | undefined, error?: string): T;
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
export const env = new Proxy(_env, {
|
|
@@ -8,22 +8,21 @@ export const env = new Proxy(_env, {
|
|
|
8
8
|
apply: (_, __, args: [string, any?, string?]) => _env(...args),
|
|
9
9
|
}) as Env;
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
function _env<T = string>(
|
|
12
12
|
name: string,
|
|
13
13
|
value?: T | undefined,
|
|
14
14
|
error?: string,
|
|
15
|
-
):
|
|
15
|
+
): T {
|
|
16
16
|
if (value !== undefined) {
|
|
17
17
|
return value;
|
|
18
18
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
return env[name] as T;
|
|
19
|
+
if (name in environment) {
|
|
20
|
+
return environment[name] as T;
|
|
22
21
|
}
|
|
23
22
|
throw new Error(error ?? `Environment variable ${name} is not set`);
|
|
24
23
|
}
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
const environment = await (async (): Promise<Record<string, any>> => {
|
|
27
26
|
if (typeof process !== "undefined") {
|
|
28
27
|
return process.env;
|
|
29
28
|
}
|
|
@@ -35,4 +34,4 @@ async function resolveEnv(): Promise<Record<string, any>> {
|
|
|
35
34
|
return import.meta.env;
|
|
36
35
|
}
|
|
37
36
|
throw new Error("No environment found");
|
|
38
|
-
}
|
|
37
|
+
})();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./random-string.ts";
|