alchemy 0.63.1 → 0.64.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 +96 -86
- package/lib/alchemy.d.ts +4 -0
- package/lib/alchemy.d.ts.map +1 -1
- package/lib/alchemy.js +10 -4
- package/lib/alchemy.js.map +1 -1
- package/lib/apply.d.ts +3 -0
- package/lib/apply.d.ts.map +1 -1
- package/lib/apply.js +11 -1
- package/lib/apply.js.map +1 -1
- package/lib/cloudflare/bindings.d.ts +3 -1
- package/lib/cloudflare/bindings.d.ts.map +1 -1
- package/lib/cloudflare/bucket.d.ts +2 -1
- package/lib/cloudflare/bucket.d.ts.map +1 -1
- package/lib/cloudflare/bucket.js.map +1 -1
- package/lib/cloudflare/bundle/cloudflare-internal.d.ts +6 -0
- package/lib/cloudflare/bundle/cloudflare-internal.d.ts.map +1 -0
- package/lib/cloudflare/bundle/cloudflare-internal.js +39 -0
- package/lib/cloudflare/bundle/cloudflare-internal.js.map +1 -0
- package/lib/cloudflare/bundle/nodejs-builtin-modules.d.ts +2 -0
- package/lib/cloudflare/bundle/nodejs-builtin-modules.d.ts.map +1 -0
- package/lib/cloudflare/bundle/nodejs-builtin-modules.js +9 -0
- package/lib/cloudflare/bundle/nodejs-builtin-modules.js.map +1 -0
- package/lib/cloudflare/bundle/plugin-als-external.d.ts +6 -0
- package/lib/cloudflare/bundle/plugin-als-external.d.ts.map +1 -0
- package/lib/cloudflare/bundle/plugin-als-external.js +12 -0
- package/lib/cloudflare/bundle/plugin-als-external.js.map +1 -0
- package/lib/cloudflare/bundle/plugin-hybrid-node-compat.d.ts +4 -1
- package/lib/cloudflare/bundle/plugin-hybrid-node-compat.d.ts.map +1 -1
- package/lib/cloudflare/bundle/plugin-hybrid-node-compat.js +23 -23
- package/lib/cloudflare/bundle/plugin-hybrid-node-compat.js.map +1 -1
- package/lib/cloudflare/bundle/plugin-node-compat.d.ts +11 -0
- package/lib/cloudflare/bundle/plugin-node-compat.d.ts.map +1 -0
- package/lib/cloudflare/bundle/plugin-node-compat.js +93 -0
- package/lib/cloudflare/bundle/plugin-node-compat.js.map +1 -0
- package/lib/cloudflare/d1-local-migrations.js.map +1 -1
- package/lib/cloudflare/durable-object-namespace.d.ts +1 -0
- package/lib/cloudflare/durable-object-namespace.d.ts.map +1 -1
- package/lib/cloudflare/durable-object-namespace.js.map +1 -1
- package/lib/cloudflare/website.d.ts.map +1 -1
- package/lib/cloudflare/website.js +80 -82
- package/lib/cloudflare/website.js.map +1 -1
- package/lib/cloudflare/worker-bundle.d.ts +6 -0
- package/lib/cloudflare/worker-bundle.d.ts.map +1 -1
- package/lib/cloudflare/worker-bundle.js +34 -10
- package/lib/cloudflare/worker-bundle.js.map +1 -1
- package/lib/cloudflare/worker-metadata.d.ts.map +1 -1
- package/lib/cloudflare/worker-metadata.js +1 -0
- package/lib/cloudflare/worker-metadata.js.map +1 -1
- package/lib/cloudflare/worker.d.ts.map +1 -1
- package/lib/cloudflare/worker.js +24 -6
- package/lib/cloudflare/worker.js.map +1 -1
- package/lib/cloudflare/wrangler.json.d.ts +2 -4
- package/lib/cloudflare/wrangler.json.d.ts.map +1 -1
- package/lib/cloudflare/wrangler.json.js +16 -14
- package/lib/cloudflare/wrangler.json.js.map +1 -1
- package/lib/context.d.ts +3 -1
- package/lib/context.d.ts.map +1 -1
- package/lib/context.js +2 -2
- package/lib/context.js.map +1 -1
- package/lib/destroy.d.ts +8 -0
- package/lib/destroy.d.ts.map +1 -1
- package/lib/destroy.js +20 -4
- package/lib/destroy.js.map +1 -1
- package/lib/planetscale/api/client.gen.d.ts +1750 -0
- package/lib/planetscale/api/client.gen.d.ts.map +1 -0
- package/lib/planetscale/api/client.gen.js +2401 -0
- package/lib/planetscale/api/client.gen.js.map +1 -0
- package/lib/planetscale/api/index.d.ts +3 -0
- package/lib/planetscale/api/index.d.ts.map +1 -0
- package/lib/planetscale/api/index.js +4 -0
- package/lib/planetscale/api/index.js.map +1 -0
- package/lib/planetscale/api/types.gen.d.ts +12156 -0
- package/lib/planetscale/api/types.gen.d.ts.map +1 -0
- package/lib/planetscale/api/types.gen.js +2 -0
- package/lib/planetscale/api/types.gen.js.map +1 -0
- package/lib/planetscale/branch.d.ts +5 -8
- package/lib/planetscale/branch.d.ts.map +1 -1
- package/lib/planetscale/branch.js +111 -97
- package/lib/planetscale/branch.js.map +1 -1
- package/lib/planetscale/database.d.ts +2 -6
- package/lib/planetscale/database.d.ts.map +1 -1
- package/lib/planetscale/database.js +157 -118
- package/lib/planetscale/database.js.map +1 -1
- package/lib/planetscale/index.d.ts +1 -1
- package/lib/planetscale/index.d.ts.map +1 -1
- package/lib/planetscale/index.js +1 -1
- package/lib/planetscale/index.js.map +1 -1
- package/lib/planetscale/password.d.ts +4 -7
- package/lib/planetscale/password.d.ts.map +1 -1
- package/lib/planetscale/password.js +71 -56
- package/lib/planetscale/password.js.map +1 -1
- package/lib/planetscale/utils.d.ts +8 -6
- package/lib/planetscale/utils.d.ts.map +1 -1
- package/lib/planetscale/utils.js +85 -70
- package/lib/planetscale/utils.js.map +1 -1
- package/lib/scope.d.ts +5 -1
- package/lib/scope.d.ts.map +1 -1
- package/lib/scope.js +11 -3
- package/lib/scope.js.map +1 -1
- package/lib/util/dedent.d.ts +3 -14
- package/lib/util/dedent.d.ts.map +1 -1
- package/lib/util/dedent.js +28 -52
- package/lib/util/dedent.js.map +1 -1
- package/package.json +4 -3
- package/src/alchemy.ts +14 -6
- package/src/apply.ts +13 -1
- package/src/cloudflare/bindings.ts +3 -1
- package/src/cloudflare/bucket.ts +3 -1
- package/src/cloudflare/bundle/cloudflare-internal.ts +42 -0
- package/src/cloudflare/bundle/nodejs-builtin-modules.ts +14 -0
- package/src/cloudflare/bundle/plugin-als-external.ts +13 -0
- package/src/cloudflare/bundle/plugin-hybrid-node-compat.ts +29 -28
- package/src/cloudflare/bundle/plugin-node-compat.ts +114 -0
- package/src/cloudflare/d1-local-migrations.ts +2 -2
- package/src/cloudflare/durable-object-namespace.ts +1 -0
- package/src/cloudflare/website.ts +88 -89
- package/src/cloudflare/worker-bundle.ts +46 -9
- package/src/cloudflare/worker-metadata.ts +2 -0
- package/src/cloudflare/worker.ts +35 -7
- package/src/cloudflare/wrangler.json.ts +108 -110
- package/src/context.ts +5 -3
- package/src/destroy.ts +26 -8
- package/src/planetscale/api/client.gen.ts +2882 -0
- package/src/planetscale/api/index.ts +4 -0
- package/src/planetscale/api/types.gen.ts +13041 -0
- package/src/planetscale/branch.ts +152 -169
- package/src/planetscale/database.ts +195 -204
- package/src/planetscale/index.ts +1 -1
- package/src/planetscale/password.ts +86 -85
- package/src/planetscale/utils.ts +141 -122
- package/src/scope.ts +12 -3
- package/src/util/dedent.ts +33 -61
- package/templates/astro/alchemy.run.ts +1 -3
- package/templates/hono/alchemy.run.ts +0 -1
- package/templates/nuxt/alchemy.run.ts +1 -3
- package/templates/react-router/alchemy.run.ts +1 -3
- package/templates/rwsdk/alchemy.run.ts +0 -2
- package/templates/sveltekit/alchemy.run.ts +1 -3
- package/templates/tanstack-start/alchemy.run.ts +1 -3
- package/templates/typescript/alchemy.run.ts +0 -1
- package/templates/vite/alchemy.run.ts +0 -1
- package/workers/cloudflare-state-store.js +58 -58
- package/lib/cloudflare/bundle/externals.d.ts +0 -3
- package/lib/cloudflare/bundle/externals.d.ts.map +0 -1
- package/lib/cloudflare/bundle/externals.js +0 -35
- package/lib/cloudflare/bundle/externals.js.map +0 -1
- package/lib/cloudflare/bundle/plugin-compat-warning.d.ts +0 -10
- package/lib/cloudflare/bundle/plugin-compat-warning.d.ts.map +0 -1
- package/lib/cloudflare/bundle/plugin-compat-warning.js +0 -67
- package/lib/cloudflare/bundle/plugin-compat-warning.js.map +0 -1
- package/lib/planetscale/api.d.ts +0 -53
- package/lib/planetscale/api.d.ts.map +0 -1
- package/lib/planetscale/api.js +0 -84
- package/lib/planetscale/api.js.map +0 -1
- package/src/cloudflare/bundle/externals.ts +0 -36
- package/src/cloudflare/bundle/plugin-compat-warning.ts +0 -94
- package/src/planetscale/api.ts +0 -115
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import type { Plugin } from "esbuild";
|
|
2
|
+
import type { NodeJSCompatMode } from "miniflare";
|
|
3
|
+
import { relative } from "node:path";
|
|
4
|
+
import chalk from "picocolors";
|
|
5
|
+
import { dedent } from "../../util/dedent.ts";
|
|
6
|
+
import { logger } from "../../util/logger.ts";
|
|
7
|
+
import { NODEJS_MODULES_RE } from "./nodejs-builtin-modules.ts";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* An esbuild plugin that will:
|
|
11
|
+
* - mark any `node:...` imports as external
|
|
12
|
+
* - warn if there are node imports (if not in v1 mode)
|
|
13
|
+
*
|
|
14
|
+
* Applies to: null, als, legacy and v1 modes.
|
|
15
|
+
*/
|
|
16
|
+
export const esbuildPluginNodeCompatImports = (
|
|
17
|
+
mode: NodeJSCompatMode,
|
|
18
|
+
): Plugin => ({
|
|
19
|
+
name: "nodejs_compat-imports",
|
|
20
|
+
setup(pluginBuild) {
|
|
21
|
+
// Infinite loop detection
|
|
22
|
+
const seen = new Set<string>();
|
|
23
|
+
|
|
24
|
+
// Prevent multiple warnings per package
|
|
25
|
+
const warnedPackages = new Map<string, string[]>();
|
|
26
|
+
|
|
27
|
+
pluginBuild.onStart(() => {
|
|
28
|
+
seen.clear();
|
|
29
|
+
warnedPackages.clear();
|
|
30
|
+
});
|
|
31
|
+
pluginBuild.onResolve(
|
|
32
|
+
{ filter: NODEJS_MODULES_RE },
|
|
33
|
+
async ({ path, kind, resolveDir, importer }) => {
|
|
34
|
+
const specifier = `${path}:${kind}:${resolveDir}:${importer}`;
|
|
35
|
+
if (seen.has(specifier)) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
seen.add(specifier);
|
|
40
|
+
// Try to resolve this import as a normal package
|
|
41
|
+
const result = await pluginBuild.resolve(path, {
|
|
42
|
+
kind,
|
|
43
|
+
resolveDir,
|
|
44
|
+
importer,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
if (result.errors.length > 0) {
|
|
48
|
+
// esbuild couldn't resolve the package
|
|
49
|
+
// We should warn the user, but not fail the build
|
|
50
|
+
const pathWarnedPackages = warnedPackages.get(path) ?? [];
|
|
51
|
+
pathWarnedPackages.push(importer);
|
|
52
|
+
warnedPackages.set(path, pathWarnedPackages);
|
|
53
|
+
|
|
54
|
+
return { external: true };
|
|
55
|
+
}
|
|
56
|
+
// This is a normal package—don't treat it specially
|
|
57
|
+
return result;
|
|
58
|
+
},
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* If we are bundling a "Service Worker" formatted Worker, imports of external modules,
|
|
63
|
+
* which won't be inlined/bundled by esbuild, are invalid.
|
|
64
|
+
*
|
|
65
|
+
* This `onEnd()` handler will error if it identifies node.js external imports.
|
|
66
|
+
*/
|
|
67
|
+
pluginBuild.onEnd(() => {
|
|
68
|
+
if (
|
|
69
|
+
pluginBuild.initialOptions.format === "iife" &&
|
|
70
|
+
warnedPackages.size > 0
|
|
71
|
+
) {
|
|
72
|
+
const paths = new Intl.ListFormat("en-US").format(
|
|
73
|
+
Array.from(warnedPackages.keys())
|
|
74
|
+
.map((p) => `"${p}"`)
|
|
75
|
+
.sort(),
|
|
76
|
+
);
|
|
77
|
+
return {
|
|
78
|
+
errors: [
|
|
79
|
+
{
|
|
80
|
+
text: dedent`
|
|
81
|
+
Unexpected external import of ${paths}.
|
|
82
|
+
Your worker has no default export, which means it is assumed to be a Service Worker format Worker.
|
|
83
|
+
Did you mean to create a ES Module format Worker?
|
|
84
|
+
If so, try adding \`export default { ... }\` in your entry-point.
|
|
85
|
+
See https://developers.cloudflare.com/workers/reference/migrate-to-module-workers/.
|
|
86
|
+
`,
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// Wait until the build finishes to log warnings, so that all files which import a package
|
|
94
|
+
// can be collated
|
|
95
|
+
pluginBuild.onEnd(() => {
|
|
96
|
+
if (mode !== "v1") {
|
|
97
|
+
warnedPackages.forEach((importers: string[], path: string) => {
|
|
98
|
+
logger.warn(
|
|
99
|
+
dedent`
|
|
100
|
+
The package "${path}" wasn't found on the file system but is built into node.
|
|
101
|
+
Your Worker may throw errors at runtime unless you enable the "nodejs_compat" compatibility flag. Refer to https://developers.cloudflare.com/workers/runtime-apis/nodejs/ for more details. Imported from:
|
|
102
|
+
${toList(importers, pluginBuild.initialOptions.absWorkingDir)}`,
|
|
103
|
+
);
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
function toList(items: string[], absWorkingDir: string | undefined): string {
|
|
111
|
+
return items
|
|
112
|
+
.map((i) => ` - ${chalk.blue(relative(absWorkingDir ?? "/", i))}`)
|
|
113
|
+
.join("\n");
|
|
114
|
+
}
|
|
@@ -20,8 +20,8 @@ export const applyLocalD1Migrations = async (
|
|
|
20
20
|
});
|
|
21
21
|
try {
|
|
22
22
|
await miniflare.ready;
|
|
23
|
-
const db = await miniflare.getD1Database("DB");
|
|
24
|
-
const session = db.withSession("first-primary");
|
|
23
|
+
const db: D1Database = await miniflare.getD1Database("DB");
|
|
24
|
+
const session: D1DatabaseSession = db.withSession("first-primary");
|
|
25
25
|
await session
|
|
26
26
|
.prepare(
|
|
27
27
|
`CREATE TABLE IF NOT EXISTS ${options.migrationsTable} (
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import assert from "node:assert";
|
|
2
2
|
import fs from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import { alchemy } from "../alchemy.ts";
|
|
5
4
|
import { Exec } from "../os/index.ts";
|
|
6
5
|
import { Scope } from "../scope.ts";
|
|
7
6
|
import { isSecret } from "../secret.ts";
|
|
@@ -255,101 +254,101 @@ export async function Website<B extends Bindings>(
|
|
|
255
254
|
entrypoint: path.relative(paths.cwd, paths.entrypoint),
|
|
256
255
|
} as WorkerProps<B> & { name: string };
|
|
257
256
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
}
|
|
257
|
+
if (!workerProps.entrypoint) {
|
|
258
|
+
await fs.mkdir(path.dirname(paths.entrypoint), { recursive: true });
|
|
259
|
+
const content =
|
|
260
|
+
script ??
|
|
261
|
+
dedent`
|
|
262
|
+
export default {
|
|
263
|
+
async fetch(request, env) {
|
|
264
|
+
return new Response("Not Found", { status: 404 });
|
|
265
|
+
},
|
|
266
|
+
};`;
|
|
267
|
+
await fs.writeFile(paths.entrypoint, content);
|
|
268
|
+
}
|
|
271
269
|
|
|
272
|
-
|
|
270
|
+
await writeMiniflareSymlink(paths.cwd);
|
|
273
271
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
272
|
+
await WranglerJson({
|
|
273
|
+
path: path.relative(paths.cwd, paths.wrangler.path),
|
|
274
|
+
worker,
|
|
275
|
+
assets: {
|
|
276
|
+
binding: "ASSETS",
|
|
277
|
+
directory: path.relative(paths.cwd, paths.assets),
|
|
278
|
+
},
|
|
279
|
+
main: path.relative(paths.cwd, paths.wrangler.main),
|
|
280
|
+
secrets,
|
|
281
|
+
transform: {
|
|
282
|
+
wrangler: props.wrangler?.transform,
|
|
283
|
+
},
|
|
284
|
+
});
|
|
287
285
|
|
|
288
|
-
|
|
289
|
-
await Exec("build", {
|
|
290
|
-
cwd: path.relative(process.cwd(), paths.cwd),
|
|
291
|
-
command: build.command,
|
|
292
|
-
env: {
|
|
293
|
-
...env,
|
|
294
|
-
...(typeof build === "object" ? build.env : {}),
|
|
295
|
-
NODE_ENV: "production",
|
|
296
|
-
},
|
|
297
|
-
memoize: typeof build === "object" ? build.memoize : undefined,
|
|
298
|
-
});
|
|
299
|
-
}
|
|
286
|
+
const scope = Scope.current;
|
|
300
287
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
return match[0];
|
|
314
|
-
}
|
|
315
|
-
},
|
|
316
|
-
env: {
|
|
317
|
-
...Object.fromEntries(
|
|
318
|
-
Object.entries(env ?? {}).flatMap(([key, value]) => {
|
|
319
|
-
if (isSecret(value)) {
|
|
320
|
-
return [[key, value.unencrypted]];
|
|
321
|
-
}
|
|
322
|
-
if (typeof value === "string") {
|
|
323
|
-
return [[key, value]];
|
|
324
|
-
}
|
|
325
|
-
return [];
|
|
326
|
-
}),
|
|
327
|
-
),
|
|
328
|
-
...(typeof dev === "object" ? dev.env : {}),
|
|
329
|
-
FORCE_COLOR: "1",
|
|
330
|
-
...process.env,
|
|
331
|
-
// NOTE: we must set this to ensure the user does not accidentally set `NODE_ENV=production`
|
|
332
|
-
// which breaks `vite dev` (it won't, for example, re-write `process.env.TSS_APP_BASE` in the `.js` client side bundle)
|
|
333
|
-
NODE_ENV: "development",
|
|
334
|
-
},
|
|
335
|
-
});
|
|
336
|
-
}
|
|
288
|
+
if (build && !scope.local) {
|
|
289
|
+
await Exec(`${id}-build`, {
|
|
290
|
+
cwd: path.relative(process.cwd(), paths.cwd),
|
|
291
|
+
command: build.command,
|
|
292
|
+
env: {
|
|
293
|
+
...env,
|
|
294
|
+
...(typeof build === "object" ? build.env : {}),
|
|
295
|
+
NODE_ENV: "production",
|
|
296
|
+
},
|
|
297
|
+
memoize: typeof build === "object" ? build.memoize : undefined,
|
|
298
|
+
});
|
|
299
|
+
}
|
|
337
300
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
301
|
+
let url: string | undefined;
|
|
302
|
+
if (dev && scope.local) {
|
|
303
|
+
url = await scope.spawn(name, {
|
|
304
|
+
cmd: typeof dev === "string" ? dev : dev.command,
|
|
305
|
+
cwd: paths.cwd,
|
|
306
|
+
extract: (line) => {
|
|
307
|
+
const URL_REGEX =
|
|
308
|
+
/http:\/\/(localhost|0\.0\.0\.0|127\.0\.0\.1|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):\d+\/?/;
|
|
309
|
+
const match = line
|
|
310
|
+
.replace(/\x1B\[[0-9;]*[a-zA-Z]/g, "")
|
|
311
|
+
.match(URL_REGEX);
|
|
312
|
+
if (match) {
|
|
313
|
+
return match[0];
|
|
314
|
+
}
|
|
315
|
+
},
|
|
316
|
+
env: {
|
|
317
|
+
...Object.fromEntries(
|
|
318
|
+
Object.entries(env ?? {}).flatMap(([key, value]) => {
|
|
319
|
+
if (isSecret(value)) {
|
|
320
|
+
return [[key, value.unencrypted]];
|
|
321
|
+
}
|
|
322
|
+
if (typeof value === "string") {
|
|
323
|
+
return [[key, value]];
|
|
347
324
|
}
|
|
348
|
-
|
|
325
|
+
return [];
|
|
326
|
+
}),
|
|
327
|
+
),
|
|
328
|
+
...(typeof dev === "object" ? dev.env : {}),
|
|
329
|
+
FORCE_COLOR: "1",
|
|
330
|
+
...process.env,
|
|
331
|
+
// NOTE: we must set this to ensure the user does not accidentally set `NODE_ENV=production`
|
|
332
|
+
// which breaks `vite dev` (it won't, for example, re-write `process.env.TSS_APP_BASE` in the `.js` client side bundle)
|
|
333
|
+
NODE_ENV: "development",
|
|
349
334
|
},
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
return (await Worker(id, {
|
|
339
|
+
...worker,
|
|
340
|
+
bindings: {
|
|
341
|
+
...worker.bindings,
|
|
342
|
+
...(!scope.local
|
|
343
|
+
? {
|
|
344
|
+
ASSETS: await Assets("assets", {
|
|
345
|
+
path: path.relative(process.cwd(), paths.assets),
|
|
346
|
+
}),
|
|
347
|
+
}
|
|
348
|
+
: {}),
|
|
349
|
+
},
|
|
350
|
+
dev: url ? { url } : undefined,
|
|
351
|
+
})) as Website<B>;
|
|
353
352
|
}
|
|
354
353
|
|
|
355
354
|
async function writeMiniflareSymlink(cwd: string) {
|
|
@@ -4,11 +4,12 @@ import { err, ok, type Result } from "neverthrow";
|
|
|
4
4
|
import fs from "node:fs/promises";
|
|
5
5
|
import path from "pathe";
|
|
6
6
|
import { logger } from "../util/logger.ts";
|
|
7
|
-
import {
|
|
7
|
+
import { cloudflareInternalPlugin } from "./bundle/cloudflare-internal.ts";
|
|
8
8
|
import { esbuildPluginAlias } from "./bundle/plugin-alias.ts";
|
|
9
|
-
import {
|
|
9
|
+
import { esbuildPluginAsyncLocalStorage } from "./bundle/plugin-als-external.ts";
|
|
10
10
|
import { createHotReloadPlugin } from "./bundle/plugin-hot-reload.ts";
|
|
11
11
|
import { esbuildPluginHybridNodeCompat } from "./bundle/plugin-hybrid-node-compat.ts";
|
|
12
|
+
import { esbuildPluginNodeCompatImports } from "./bundle/plugin-node-compat.ts";
|
|
12
13
|
import { createWasmPlugin } from "./bundle/plugin-wasm.ts";
|
|
13
14
|
import { validateNodeCompat } from "./bundle/validate-node-compat.ts";
|
|
14
15
|
|
|
@@ -76,6 +77,8 @@ export function normalizeWorkerBundle(props: {
|
|
|
76
77
|
cwd: props.cwd,
|
|
77
78
|
outdir: props.outdir,
|
|
78
79
|
sourcemap: props.sourceMap !== false ? true : undefined,
|
|
80
|
+
compatibilityDate: props.compatibilityDate,
|
|
81
|
+
compatibilityFlags: props.compatibilityFlags,
|
|
79
82
|
...props.bundle,
|
|
80
83
|
}),
|
|
81
84
|
);
|
|
@@ -248,6 +251,8 @@ export namespace WorkerBundleSource {
|
|
|
248
251
|
entrypoint: string;
|
|
249
252
|
cwd: string;
|
|
250
253
|
outdir: string;
|
|
254
|
+
compatibilityDate: string;
|
|
255
|
+
compatibilityFlags: string[];
|
|
251
256
|
}
|
|
252
257
|
|
|
253
258
|
export class ESBuild implements WorkerBundleSource {
|
|
@@ -328,6 +333,8 @@ export namespace WorkerBundleSource {
|
|
|
328
333
|
nodeCompat,
|
|
329
334
|
cwd,
|
|
330
335
|
format,
|
|
336
|
+
compatibilityDate: _compatibilityDate,
|
|
337
|
+
compatibilityFlags: _compatibilityFlags,
|
|
331
338
|
...props
|
|
332
339
|
} = this.props;
|
|
333
340
|
return {
|
|
@@ -356,19 +363,49 @@ export namespace WorkerBundleSource {
|
|
|
356
363
|
conditions: props.conditions ?? ["workerd", "worker", "browser"],
|
|
357
364
|
plugins: [
|
|
358
365
|
esbuildPluginAlias(props.alias ?? {}, this.props.cwd),
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
:
|
|
366
|
+
cloudflareInternalPlugin,
|
|
367
|
+
...this.getNodeJSCompatPlugins({
|
|
368
|
+
mode: nodeCompat,
|
|
369
|
+
compatibilityDate: this.props.compatibilityDate,
|
|
370
|
+
compatibilityFlags: this.props.compatibilityFlags,
|
|
371
|
+
}),
|
|
362
372
|
...(props.plugins ?? []),
|
|
363
373
|
...additionalPlugins,
|
|
364
374
|
],
|
|
365
|
-
external: [
|
|
366
|
-
...(nodeCompat === "als" ? external_als : external),
|
|
367
|
-
...(props.external ?? []),
|
|
368
|
-
],
|
|
375
|
+
external: [...(props.external ?? [])],
|
|
369
376
|
} satisfies esbuild.BuildOptions;
|
|
370
377
|
}
|
|
371
378
|
|
|
379
|
+
/**
|
|
380
|
+
* Returns the list of ESBuild plugins to use for a given compat mode.
|
|
381
|
+
*/
|
|
382
|
+
private getNodeJSCompatPlugins({
|
|
383
|
+
mode,
|
|
384
|
+
compatibilityDate,
|
|
385
|
+
compatibilityFlags,
|
|
386
|
+
}: {
|
|
387
|
+
mode: "als" | "v2" | null;
|
|
388
|
+
compatibilityDate?: string;
|
|
389
|
+
compatibilityFlags?: string[];
|
|
390
|
+
}): esbuild.Plugin[] {
|
|
391
|
+
switch (mode) {
|
|
392
|
+
case "als":
|
|
393
|
+
return [
|
|
394
|
+
esbuildPluginAsyncLocalStorage,
|
|
395
|
+
esbuildPluginNodeCompatImports(mode),
|
|
396
|
+
];
|
|
397
|
+
case "v2":
|
|
398
|
+
return [
|
|
399
|
+
esbuildPluginHybridNodeCompat({
|
|
400
|
+
compatibilityDate,
|
|
401
|
+
compatibilityFlags,
|
|
402
|
+
}),
|
|
403
|
+
];
|
|
404
|
+
case null:
|
|
405
|
+
return [esbuildPluginNodeCompatImports(mode)];
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
372
409
|
private async formatBuildOutput(
|
|
373
410
|
metafile: esbuild.Metafile,
|
|
374
411
|
): Promise<WorkerBundle> {
|
|
@@ -442,6 +442,8 @@ export async function prepareWorkerMetadata(
|
|
|
442
442
|
type: "r2_bucket",
|
|
443
443
|
name: bindingName,
|
|
444
444
|
bucket_name: binding.name,
|
|
445
|
+
jurisdiction:
|
|
446
|
+
binding.jurisdiction === "default" ? undefined : binding.jurisdiction,
|
|
445
447
|
});
|
|
446
448
|
} else if (binding.type === "secrets_store_secret") {
|
|
447
449
|
meta.bindings.push({
|
package/src/cloudflare/worker.ts
CHANGED
|
@@ -709,14 +709,29 @@ const _Worker = Resource(
|
|
|
709
709
|
id: string,
|
|
710
710
|
props: WorkerProps<B>,
|
|
711
711
|
) {
|
|
712
|
-
|
|
712
|
+
let adopt = props.adopt ?? this.scope.adopt;
|
|
713
|
+
const workerName =
|
|
714
|
+
props.name ?? this.output?.name ?? this.scope.createPhysicalName(id);
|
|
715
|
+
if (this.phase === "create" && !props.adopt) {
|
|
716
|
+
// it is possible that this worker already exists and was created by the old Website wrapper with a nested scope
|
|
717
|
+
// we need to detect this and set adopt=true so that the previous version will be adopted seamlessly
|
|
718
|
+
|
|
719
|
+
// HEURISTIC: `this.scope` would previously be the nested outer scope alchemy.run
|
|
720
|
+
// so, if `this.scope` has a child of `wrangler.jsonc`, then it is likely that it was created by the old Website wrapper with a nested scope
|
|
721
|
+
if (await this.scope.has("wrangler.jsonc", "cloudflare::WranglerJson")) {
|
|
722
|
+
logger.warn(
|
|
723
|
+
`Migrating Worker '${workerName}' from the legacy Website wrapper.`,
|
|
724
|
+
);
|
|
725
|
+
props.adopt = true;
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
|
|
713
729
|
const options = (() => {
|
|
714
730
|
if (props.projectRoot) {
|
|
715
731
|
logger.warn("projectRoot is deprecated, use cwd instead");
|
|
716
732
|
props.cwd = props.projectRoot;
|
|
717
733
|
}
|
|
718
|
-
|
|
719
|
-
props.name ?? this.output?.name ?? this.scope.createPhysicalName(id);
|
|
734
|
+
|
|
720
735
|
const cwd = path.resolve(props.cwd ?? process.cwd());
|
|
721
736
|
const compatibilityDate =
|
|
722
737
|
props.compatibilityDate ?? DEFAULT_COMPATIBILITY_DATE;
|
|
@@ -739,7 +754,8 @@ const _Worker = Resource(
|
|
|
739
754
|
cwd,
|
|
740
755
|
compatibilityDate,
|
|
741
756
|
compatibilityFlags,
|
|
742
|
-
outdir:
|
|
757
|
+
outdir:
|
|
758
|
+
props.bundle?.outdir ?? path.join(cwd, ".alchemy", "out", workerName),
|
|
743
759
|
sourceMap: "sourceMap" in props ? props.sourceMap : undefined,
|
|
744
760
|
});
|
|
745
761
|
|
|
@@ -756,19 +772,19 @@ const _Worker = Resource(
|
|
|
756
772
|
containers.push(binding);
|
|
757
773
|
} else if (
|
|
758
774
|
binding.type === "workflow" &&
|
|
759
|
-
(!binding.scriptName || binding.scriptName ===
|
|
775
|
+
(!binding.scriptName || binding.scriptName === workerName)
|
|
760
776
|
) {
|
|
761
777
|
workflows.push(binding);
|
|
762
778
|
} else if (
|
|
763
779
|
binding.type === "durable_object_namespace" &&
|
|
764
|
-
(!binding.scriptName || binding.scriptName ===
|
|
780
|
+
(!binding.scriptName || binding.scriptName === workerName)
|
|
765
781
|
) {
|
|
766
782
|
durableObjects.push(binding);
|
|
767
783
|
}
|
|
768
784
|
}
|
|
769
785
|
|
|
770
786
|
return {
|
|
771
|
-
name,
|
|
787
|
+
name: workerName,
|
|
772
788
|
cwd,
|
|
773
789
|
compatibilityDate,
|
|
774
790
|
compatibilityFlags,
|
|
@@ -780,7 +796,19 @@ const _Worker = Resource(
|
|
|
780
796
|
durableObjects,
|
|
781
797
|
};
|
|
782
798
|
})();
|
|
799
|
+
|
|
783
800
|
if (this.phase === "delete") {
|
|
801
|
+
// Heuristic: we must detect the case where this is the Worker wrapped in the old Website nested scope and not delete it
|
|
802
|
+
// we must not delete it because what we're actually doing is migrating to a flat worker
|
|
803
|
+
// we will achieve this by checking for a sibling resource with ID wrangler.jsonc and type cloudflare::WranglerJson
|
|
804
|
+
if (await this.scope.has("wrangler.jsonc", "cloudflare::WranglerJson")) {
|
|
805
|
+
// skip deletion
|
|
806
|
+
logger.warn(
|
|
807
|
+
`Migrating Worker '${options.name}' from the legacy Website wrapper.`,
|
|
808
|
+
);
|
|
809
|
+
return this.destroy(true);
|
|
810
|
+
}
|
|
811
|
+
|
|
784
812
|
if (options.bundle.isOk()) {
|
|
785
813
|
await options.bundle.value.delete?.();
|
|
786
814
|
}
|