alchemy 0.63.1 → 0.65.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 +7664 -5857
- package/bin/commands/init.ts +130 -9
- package/bin/constants.ts +4 -0
- package/bin/services/cdp-manager/cdp-proxy.ts +69 -0
- package/bin/services/cdp-manager/server.ts +173 -0
- package/bin/services/execute-alchemy.ts +83 -4
- package/bin/types.ts +1 -0
- 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/bundle/plugin-wasm.d.ts.map +1 -1
- package/lib/cloudflare/bundle/plugin-wasm.js +20 -11
- package/lib/cloudflare/bundle/plugin-wasm.js.map +1 -1
- package/lib/cloudflare/compatibility-date.gen.d.ts +1 -1
- package/lib/cloudflare/compatibility-date.gen.js +1 -1
- 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/hyperdrive.d.ts +7 -2
- package/lib/cloudflare/hyperdrive.d.ts.map +1 -1
- package/lib/cloudflare/hyperdrive.js +39 -57
- package/lib/cloudflare/hyperdrive.js.map +1 -1
- package/lib/cloudflare/index.d.ts +1 -0
- package/lib/cloudflare/index.d.ts.map +1 -1
- package/lib/cloudflare/index.js +1 -0
- package/lib/cloudflare/index.js.map +1 -1
- package/lib/cloudflare/next.d.ts +13 -0
- package/lib/cloudflare/next.d.ts.map +1 -0
- package/lib/cloudflare/next.js +91 -0
- package/lib/cloudflare/next.js.map +1 -0
- 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-assets.d.ts +3 -3
- package/lib/cloudflare/worker-assets.d.ts.map +1 -1
- package/lib/cloudflare/worker-assets.js +22 -47
- package/lib/cloudflare/worker-assets.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 +4 -6
- package/lib/cloudflare/wrangler.json.d.ts.map +1 -1
- package/lib/cloudflare/wrangler.json.js +20 -15
- 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 +122 -97
- package/lib/planetscale/branch.js.map +1 -1
- package/lib/planetscale/database.d.ts +24 -11
- package/lib/planetscale/database.d.ts.map +1 -1
- package/lib/planetscale/database.js +163 -118
- package/lib/planetscale/database.js.map +1 -1
- package/lib/planetscale/index.d.ts +2 -1
- package/lib/planetscale/index.d.ts.map +1 -1
- package/lib/planetscale/index.js +2 -1
- package/lib/planetscale/index.js.map +1 -1
- package/lib/planetscale/password.d.ts +7 -8
- package/lib/planetscale/password.d.ts.map +1 -1
- package/lib/planetscale/password.js +74 -57
- package/lib/planetscale/password.js.map +1 -1
- package/lib/planetscale/role.d.ts +126 -0
- package/lib/planetscale/role.d.ts.map +1 -0
- package/lib/planetscale/role.js +144 -0
- package/lib/planetscale/role.js.map +1 -0
- package/lib/planetscale/utils.d.ts +23 -7
- package/lib/planetscale/utils.d.ts.map +1 -1
- package/lib/planetscale/utils.js +169 -75
- 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/secret.d.ts +0 -3
- package/lib/secret.d.ts.map +1 -1
- package/lib/secret.js +0 -2
- package/lib/secret.js.map +1 -1
- package/lib/state/cloudflare-state-store.js +3 -3
- package/lib/state/cloudflare-state-store.js.map +1 -1
- package/lib/test/bun.d.ts +2 -2
- package/lib/test/bun.d.ts.map +1 -1
- package/lib/test/vitest.d.ts +2 -2
- package/lib/test/vitest.d.ts.map +1 -1
- package/lib/test/vitest.js +4 -4
- package/lib/test/vitest.js.map +1 -1
- package/lib/util/content-type.js +2 -2
- package/lib/util/content-type.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 +33 -45
- package/lib/util/dedent.js.map +1 -1
- package/lib/util/memoize.d.ts.map +1 -1
- package/lib/util/memoize.js +11 -1
- package/lib/util/memoize.js.map +1 -1
- package/package.json +8 -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/bundle/plugin-wasm.ts +34 -14
- package/src/cloudflare/compatibility-date.gen.ts +1 -1
- package/src/cloudflare/d1-local-migrations.ts +2 -2
- package/src/cloudflare/durable-object-namespace.ts +1 -0
- package/src/cloudflare/hyperdrive.ts +136 -95
- package/src/cloudflare/index.ts +1 -0
- package/src/cloudflare/next.ts +123 -0
- package/src/cloudflare/website.ts +88 -89
- package/src/cloudflare/worker-assets.ts +43 -105
- 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 +114 -113
- 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 +170 -162
- package/src/planetscale/database.ts +263 -243
- package/src/planetscale/index.ts +2 -1
- package/src/planetscale/password.ts +89 -86
- package/src/planetscale/role.ts +278 -0
- package/src/planetscale/utils.ts +289 -128
- package/src/scope.ts +12 -3
- package/src/secret.ts +0 -4
- package/src/state/cloudflare-state-store.ts +4 -4
- package/src/test/bun.ts +2 -2
- package/src/test/vitest.ts +6 -6
- package/src/util/content-type.ts +2 -2
- package/src/util/dedent.ts +34 -50
- package/src/util/memoize.ts +13 -1
- package/templates/astro/alchemy.run.ts +1 -3
- package/templates/hono/alchemy.run.ts +0 -1
- package/templates/nextjs/README.md +85 -0
- package/templates/nextjs/_env +1 -0
- package/templates/nextjs/_env.example +1 -0
- package/templates/nextjs/_gitignore +46 -0
- package/templates/nextjs/alchemy.run.ts +16 -0
- package/templates/nextjs/eslint.config.mjs +16 -0
- package/templates/nextjs/next-env.d.ts +5 -0
- package/templates/nextjs/next.config.ts +10 -0
- package/templates/nextjs/open-next.config.ts +5 -0
- package/templates/nextjs/package.json +31 -0
- package/templates/nextjs/src/app/api/hello/route.ts +19 -0
- package/templates/nextjs/src/app/favicon.ico +0 -0
- package/templates/nextjs/src/app/globals.css +72 -0
- package/templates/nextjs/src/app/layout.tsx +19 -0
- package/templates/nextjs/src/app/page.tsx +55 -0
- package/templates/nextjs/tsconfig.json +33 -0
- package/templates/nextjs/types/env.d.ts +14 -0
- 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
|
@@ -2,6 +2,7 @@ import fs from "node:fs/promises";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import type { Context } from "../context.ts";
|
|
4
4
|
import { Resource } from "../resource.ts";
|
|
5
|
+
import { Scope } from "../scope.ts";
|
|
5
6
|
import { isSecret } from "../secret.ts";
|
|
6
7
|
import { assertNever } from "../util/assert-never.ts";
|
|
7
8
|
import {
|
|
@@ -9,6 +10,7 @@ import {
|
|
|
9
10
|
type Bindings,
|
|
10
11
|
type WorkerBindingRateLimit,
|
|
11
12
|
} from "./bindings.ts";
|
|
13
|
+
import type { R2BucketJurisdiction } from "./bucket.ts";
|
|
12
14
|
import type { DurableObjectNamespace } from "./durable-object-namespace.ts";
|
|
13
15
|
import type { EventSource } from "./event-source.ts";
|
|
14
16
|
import { isQueueEventSource } from "./event-source.ts";
|
|
@@ -86,9 +88,7 @@ export interface WranglerJsonProps {
|
|
|
86
88
|
/**
|
|
87
89
|
* Output returned after WranglerJson creation/update
|
|
88
90
|
*/
|
|
89
|
-
export interface WranglerJson
|
|
90
|
-
extends Resource<"cloudflare::WranglerJson">,
|
|
91
|
-
WranglerJsonProps {
|
|
91
|
+
export interface WranglerJson extends WranglerJsonProps {
|
|
92
92
|
/**
|
|
93
93
|
* Time at which the file was created
|
|
94
94
|
*/
|
|
@@ -110,128 +110,123 @@ export interface WranglerJson
|
|
|
110
110
|
spec: WranglerJsonSpec;
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
+
// we are deprecating the WranglerJson resource (it is now just a funciton)
|
|
114
|
+
// but, a user may still have a resource that depends on it, so we register a no-op dummy resource so that it can be cleanly delted
|
|
115
|
+
Resource("cloudflare::WranglerJson", async function (this: Context<any>) {
|
|
116
|
+
if (this.phase === "delete") {
|
|
117
|
+
return this.destroy();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
throw new Error("Not implemented");
|
|
121
|
+
});
|
|
122
|
+
|
|
113
123
|
/**
|
|
114
124
|
* Resource for managing wrangler.json configuration files
|
|
115
125
|
*/
|
|
116
|
-
export
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
},
|
|
121
|
-
async function (
|
|
122
|
-
this: Context<WranglerJson>,
|
|
123
|
-
_id: string,
|
|
124
|
-
props: WranglerJsonProps,
|
|
125
|
-
): Promise<WranglerJson> {
|
|
126
|
-
if (this.phase === "delete") {
|
|
127
|
-
return this.destroy();
|
|
128
|
-
}
|
|
126
|
+
export async function WranglerJson(
|
|
127
|
+
props: WranglerJsonProps,
|
|
128
|
+
): Promise<WranglerJson> {
|
|
129
|
+
const cwd = props.worker.cwd ? path.resolve(props.worker.cwd) : process.cwd();
|
|
129
130
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
const toAbsolute = <T extends string | undefined>(input: T): T => {
|
|
135
|
-
return (input ? path.resolve(cwd, input) : undefined) as T;
|
|
136
|
-
};
|
|
131
|
+
const toAbsolute = <T extends string | undefined>(input: T): T => {
|
|
132
|
+
return (input ? path.resolve(cwd, input) : undefined) as T;
|
|
133
|
+
};
|
|
137
134
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
135
|
+
const main = toAbsolute(props.main ?? props.worker.entrypoint);
|
|
136
|
+
let filePath = toAbsolute(props.path ?? cwd);
|
|
137
|
+
if (!path.basename(filePath).match(".json")) {
|
|
138
|
+
filePath = path.join(filePath, props.name ?? "wrangler.jsonc");
|
|
139
|
+
}
|
|
143
140
|
|
|
144
|
-
|
|
141
|
+
const dirname = path.dirname(filePath);
|
|
145
142
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
143
|
+
if (!main) {
|
|
144
|
+
throw new Error(
|
|
145
|
+
"Worker must have an entrypoint to generate a wrangler.json",
|
|
146
|
+
);
|
|
147
|
+
}
|
|
151
148
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
149
|
+
const worker = props.worker;
|
|
150
|
+
|
|
151
|
+
const spec: WranglerJsonSpec = {
|
|
152
|
+
name: worker.name,
|
|
153
|
+
// Use entrypoint as main if it exists
|
|
154
|
+
main: path.relative(dirname, main),
|
|
155
|
+
// see: https://developers.cloudflare.com/workers/configuration/compatibility-dates/
|
|
156
|
+
compatibility_date: worker.compatibilityDate,
|
|
157
|
+
compatibility_flags: props.worker.compatibilityFlags,
|
|
158
|
+
assets: props.assets
|
|
159
|
+
? {
|
|
160
|
+
directory: toAbsolute(props.assets.directory),
|
|
161
|
+
binding: props.assets.binding,
|
|
162
|
+
not_found_handling: props.worker.assets?.not_found_handling,
|
|
163
|
+
html_handling: props.worker.assets?.html_handling,
|
|
164
|
+
run_worker_first: props.worker.assets?.run_worker_first,
|
|
165
|
+
}
|
|
166
|
+
: undefined,
|
|
167
|
+
placement: worker.placement,
|
|
168
|
+
limits: worker.limits,
|
|
169
|
+
};
|
|
173
170
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
171
|
+
// Process bindings if they exist
|
|
172
|
+
if (worker.bindings) {
|
|
173
|
+
processBindings(
|
|
174
|
+
spec,
|
|
175
|
+
worker.bindings,
|
|
176
|
+
worker.eventSources,
|
|
177
|
+
worker.name,
|
|
178
|
+
cwd,
|
|
179
|
+
props.secrets ?? false,
|
|
180
|
+
Scope.current.local && !props.worker.dev?.remote,
|
|
181
|
+
);
|
|
182
|
+
}
|
|
186
183
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
184
|
+
// Add environment variables as vars
|
|
185
|
+
if (worker.env) {
|
|
186
|
+
spec.vars = { ...worker.env };
|
|
187
|
+
}
|
|
191
188
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
189
|
+
if (worker.crons && worker.crons.length > 0) {
|
|
190
|
+
spec.triggers = { crons: worker.crons };
|
|
191
|
+
}
|
|
195
192
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
193
|
+
if (spec.assets) {
|
|
194
|
+
spec.assets.directory = path.relative(dirname, spec.assets.directory);
|
|
195
|
+
}
|
|
199
196
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
),
|
|
197
|
+
// Apply the wrangler configuration hook as the final transformation
|
|
198
|
+
const finalSpec = props.transform?.wrangler
|
|
199
|
+
? await props.transform.wrangler(spec)
|
|
200
|
+
: spec;
|
|
201
|
+
|
|
202
|
+
await fs.mkdir(dirname, { recursive: true });
|
|
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],
|
|
217
213
|
),
|
|
218
|
-
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
214
|
+
),
|
|
215
|
+
},
|
|
216
|
+
};
|
|
217
|
+
await writeJSON(filePath, withSecretsUnwrapped);
|
|
218
|
+
} else {
|
|
219
|
+
await writeJSON(filePath, finalSpec);
|
|
220
|
+
}
|
|
224
221
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
},
|
|
234
|
-
);
|
|
222
|
+
return {
|
|
223
|
+
...props,
|
|
224
|
+
path: path.relative(cwd, filePath),
|
|
225
|
+
spec: finalSpec,
|
|
226
|
+
createdAt: Date.now(),
|
|
227
|
+
updatedAt: Date.now(),
|
|
228
|
+
};
|
|
229
|
+
}
|
|
235
230
|
|
|
236
231
|
const writeJSON = async (filePath: string, content: any) => {
|
|
237
232
|
await fs.writeFile(filePath, `${JSON.stringify(content, null, 2)}\n`);
|
|
@@ -358,8 +353,8 @@ export interface WranglerJsonSpec {
|
|
|
358
353
|
* Queue bindings
|
|
359
354
|
*/
|
|
360
355
|
queues?: {
|
|
361
|
-
producers
|
|
362
|
-
consumers
|
|
356
|
+
producers?: { queue: string; binding: string }[];
|
|
357
|
+
consumers?: {
|
|
363
358
|
queue: string;
|
|
364
359
|
max_batch_size?: number;
|
|
365
360
|
max_concurrency?: number;
|
|
@@ -537,6 +532,7 @@ function processBindings(
|
|
|
537
532
|
binding: string;
|
|
538
533
|
bucket_name: string;
|
|
539
534
|
preview_bucket_name: string;
|
|
535
|
+
jurisdiction?: R2BucketJurisdiction;
|
|
540
536
|
}[] = [];
|
|
541
537
|
const services: { binding: string; service: string; environment?: string }[] =
|
|
542
538
|
[];
|
|
@@ -683,6 +679,8 @@ function processBindings(
|
|
|
683
679
|
binding: bindingName,
|
|
684
680
|
bucket_name: name,
|
|
685
681
|
preview_bucket_name: name,
|
|
682
|
+
jurisdiction:
|
|
683
|
+
binding.jurisdiction === "default" ? undefined : binding.jurisdiction,
|
|
686
684
|
...(binding.dev?.remote ? { experimental_remote: true } : {}),
|
|
687
685
|
});
|
|
688
686
|
} else if (binding.type === "secret") {
|
|
@@ -847,7 +845,10 @@ function processBindings(
|
|
|
847
845
|
}
|
|
848
846
|
|
|
849
847
|
if (queues.consumers.length > 0) {
|
|
850
|
-
spec.queues = queues;
|
|
848
|
+
(spec.queues ??= {}).consumers = queues.consumers;
|
|
849
|
+
}
|
|
850
|
+
if (queues.producers.length > 0) {
|
|
851
|
+
(spec.queues ??= {}).producers = queues.producers;
|
|
851
852
|
}
|
|
852
853
|
|
|
853
854
|
if (vectorizeIndexes.length > 0) {
|
package/src/context.ts
CHANGED
|
@@ -65,8 +65,10 @@ export interface BaseContext<Out extends Resource> {
|
|
|
65
65
|
*
|
|
66
66
|
* It is so that the resource lifecycle handler can "return never" instead of
|
|
67
67
|
* "return undefined" so that `await MyResource()` always returns a value.
|
|
68
|
+
*
|
|
69
|
+
* @param retainChildren - Whether to retain the children of the resource.
|
|
68
70
|
*/
|
|
69
|
-
destroy(): never;
|
|
71
|
+
destroy(retainChildren?: boolean): never;
|
|
70
72
|
/**
|
|
71
73
|
* Register a cleanup function that will be called when the process exits.
|
|
72
74
|
*
|
|
@@ -161,8 +163,8 @@ export function context<
|
|
|
161
163
|
return value;
|
|
162
164
|
},
|
|
163
165
|
quiet: scope.quiet,
|
|
164
|
-
destroy: () => {
|
|
165
|
-
throw new DestroyedSignal();
|
|
166
|
+
destroy: (retainChildren = false) => {
|
|
167
|
+
throw new DestroyedSignal(retainChildren);
|
|
166
168
|
},
|
|
167
169
|
onCleanup: (fn: () => void | Promise<void>) => {
|
|
168
170
|
// make the function idempotent so repeated calls don't cause the process to hang
|
package/src/destroy.ts
CHANGED
|
@@ -15,7 +15,16 @@ import type { State } from "./state.ts";
|
|
|
15
15
|
import { formatFQN } from "./util/cli.ts";
|
|
16
16
|
import { logger } from "./util/logger.ts";
|
|
17
17
|
|
|
18
|
-
export
|
|
18
|
+
export function isDestroyedSignal(error: any): error is DestroyedSignal {
|
|
19
|
+
return error instanceof Error && (error as any).kind === "DestroyedSignal";
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export class DestroyedSignal extends Error {
|
|
23
|
+
readonly kind = "DestroyedSignal";
|
|
24
|
+
constructor(public readonly noop: boolean) {
|
|
25
|
+
super();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
19
28
|
|
|
20
29
|
export type DestroyStrategy = "sequential" | "parallel";
|
|
21
30
|
|
|
@@ -28,6 +37,10 @@ export interface DestroyOptions {
|
|
|
28
37
|
props?: ResourceProps | undefined;
|
|
29
38
|
output?: Resource<string>;
|
|
30
39
|
};
|
|
40
|
+
/**
|
|
41
|
+
* If true, children of the resource will not be destroyed (but their state will be deleted).
|
|
42
|
+
*/
|
|
43
|
+
noop?: boolean;
|
|
31
44
|
}
|
|
32
45
|
|
|
33
46
|
function isScopeArgs(a: any): a is [scope: Scope, options?: DestroyOptions] {
|
|
@@ -98,7 +111,7 @@ export async function destroy<Type extends string>(
|
|
|
98
111
|
const quiet = options?.quiet ?? scope.quiet;
|
|
99
112
|
|
|
100
113
|
try {
|
|
101
|
-
if (!quiet) {
|
|
114
|
+
if (!quiet && !options?.noop) {
|
|
102
115
|
logger.task(instance[ResourceFQN], {
|
|
103
116
|
prefix: options?.replace ? "cleanup" : "deleting",
|
|
104
117
|
prefixColor: options?.replace ? "magenta" : "redBright",
|
|
@@ -149,6 +162,8 @@ export async function destroy<Type extends string>(
|
|
|
149
162
|
});
|
|
150
163
|
|
|
151
164
|
let nestedScope: Scope | undefined;
|
|
165
|
+
let noop = options?.noop ?? false;
|
|
166
|
+
|
|
152
167
|
try {
|
|
153
168
|
// BUG: this does not restore persisted scope
|
|
154
169
|
await alchemy.run(
|
|
@@ -158,17 +173,19 @@ export async function destroy<Type extends string>(
|
|
|
158
173
|
isResource: instance[ResourceKind] !== "alchemy::Scope",
|
|
159
174
|
parent: scope,
|
|
160
175
|
destroyStrategy: instance[DestroyStrategy] ?? "sequential",
|
|
176
|
+
noop,
|
|
161
177
|
},
|
|
162
178
|
async (scope) => {
|
|
163
179
|
nestedScope = options?.replace?.props == null ? scope : undefined;
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
);
|
|
180
|
+
if (noop) {
|
|
181
|
+
return ctx.destroy(noop);
|
|
182
|
+
}
|
|
183
|
+
return Provider.handler.bind(ctx)(instance[ResourceID], ctx.props);
|
|
168
184
|
},
|
|
169
185
|
);
|
|
170
186
|
} catch (err) {
|
|
171
|
-
if (err
|
|
187
|
+
if (isDestroyedSignal(err)) {
|
|
188
|
+
noop = noop || err.noop;
|
|
172
189
|
// TODO: should we fail if the DestroyedSignal is not thrown?
|
|
173
190
|
} else {
|
|
174
191
|
throw err;
|
|
@@ -178,6 +195,7 @@ export async function destroy<Type extends string>(
|
|
|
178
195
|
if (nestedScope) {
|
|
179
196
|
await destroy(nestedScope, {
|
|
180
197
|
...options,
|
|
198
|
+
noop,
|
|
181
199
|
strategy: instance[DestroyStrategy] ?? "sequential",
|
|
182
200
|
});
|
|
183
201
|
}
|
|
@@ -195,7 +213,7 @@ export async function destroy<Type extends string>(
|
|
|
195
213
|
await scope.set("pendingDeletions", pendingDeletions);
|
|
196
214
|
}
|
|
197
215
|
|
|
198
|
-
if (!quiet) {
|
|
216
|
+
if (!quiet && !options?.noop) {
|
|
199
217
|
logger.task(instance[ResourceFQN], {
|
|
200
218
|
prefix: options?.replace ? "cleaned" : "deleted",
|
|
201
219
|
prefixColor: "greenBright",
|