alchemy 0.43.4 → 0.44.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.mjs +430 -346
- package/bin/alchemy.ts +7 -21
- package/bin/commands/create.ts +79 -23
- package/bin/services/package-manager.ts +0 -3
- package/bin/services/template-manager.ts +9 -4
- package/bin/services/vibe-rules.ts +47 -0
- package/bin/types.ts +25 -5
- package/lib/alchemy.d.ts.map +1 -1
- package/lib/alchemy.js +8 -11
- package/lib/alchemy.js.map +1 -1
- package/lib/apply.js +2 -0
- package/lib/apply.js.map +1 -1
- package/lib/build-date.d.ts +1 -1
- package/lib/build-date.js +1 -1
- package/lib/cloudflare/assets.d.ts +1 -1
- package/lib/cloudflare/assets.d.ts.map +1 -1
- package/lib/cloudflare/bucket.d.ts.map +1 -1
- package/lib/cloudflare/bucket.js +9 -6
- package/lib/cloudflare/bucket.js.map +1 -1
- package/lib/cloudflare/bundle/bundle-worker-dev.d.ts.map +1 -1
- package/lib/cloudflare/bundle/bundle-worker-dev.js +4 -1
- package/lib/cloudflare/bundle/bundle-worker-dev.js.map +1 -1
- package/lib/cloudflare/bundle/bundle-worker.d.ts.map +1 -1
- package/lib/cloudflare/bundle/bundle-worker.js +4 -1
- package/lib/cloudflare/bundle/bundle-worker.js.map +1 -1
- package/lib/cloudflare/bundle/external.d.ts +1 -0
- package/lib/cloudflare/bundle/external.d.ts.map +1 -1
- package/lib/cloudflare/bundle/external.js +1 -1
- package/lib/cloudflare/bundle/external.js.map +1 -1
- package/lib/cloudflare/bundle/nodejs-import-warning-plugin.d.ts +10 -0
- package/lib/cloudflare/bundle/nodejs-import-warning-plugin.d.ts.map +1 -0
- package/lib/cloudflare/bundle/nodejs-import-warning-plugin.js +67 -0
- package/lib/cloudflare/bundle/nodejs-import-warning-plugin.js.map +1 -0
- package/lib/cloudflare/container.d.ts +27 -2
- package/lib/cloudflare/container.d.ts.map +1 -1
- package/lib/cloudflare/container.js +82 -24
- package/lib/cloudflare/container.js.map +1 -1
- package/lib/cloudflare/redirect-rule.js +1 -1
- package/lib/cloudflare/redirect-rule.js.map +1 -1
- package/lib/cloudflare/website.d.ts +17 -0
- package/lib/cloudflare/website.d.ts.map +1 -1
- package/lib/cloudflare/website.js +1 -0
- package/lib/cloudflare/website.js.map +1 -1
- package/lib/cloudflare/worker/miniflare.d.ts +4 -1
- package/lib/cloudflare/worker/miniflare.d.ts.map +1 -1
- package/lib/cloudflare/worker/miniflare.js +22 -2
- package/lib/cloudflare/worker/miniflare.js.map +1 -1
- package/lib/cloudflare/worker-metadata.d.ts.map +1 -1
- package/lib/cloudflare/worker-metadata.js +12 -0
- package/lib/cloudflare/worker-metadata.js.map +1 -1
- package/lib/cloudflare/worker.d.ts +1 -1
- package/lib/cloudflare/wrangler.json.d.ts +24 -0
- package/lib/cloudflare/wrangler.json.d.ts.map +1 -1
- package/lib/cloudflare/wrangler.json.js +20 -2
- package/lib/cloudflare/wrangler.json.js.map +1 -1
- package/lib/context.d.ts +6 -1
- package/lib/context.d.ts.map +1 -1
- package/lib/context.js +2 -1
- package/lib/context.js.map +1 -1
- package/lib/destroy.d.ts.map +1 -1
- package/lib/destroy.js +1 -0
- package/lib/destroy.js.map +1 -1
- package/lib/docker/api.d.ts +11 -0
- package/lib/docker/api.d.ts.map +1 -1
- package/lib/docker/api.js +41 -1
- package/lib/docker/api.js.map +1 -1
- package/lib/docker/image.d.ts +1 -1
- package/lib/docker/image.d.ts.map +1 -1
- package/lib/docker/image.js +11 -5
- package/lib/docker/image.js.map +1 -1
- package/lib/esbuild/bundle.d.ts +2 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/llms.cloudflare.txt +379 -0
- package/lib/llms.d.ts +10 -0
- package/lib/llms.d.ts.map +1 -0
- package/lib/llms.js +12 -0
- package/lib/llms.js.map +1 -0
- package/lib/planetscale/index.d.ts +3 -2
- package/lib/planetscale/index.d.ts.map +1 -1
- package/lib/planetscale/index.js +3 -2
- package/lib/planetscale/index.js.map +1 -1
- package/lib/planetscale/password.d.ts +233 -0
- package/lib/planetscale/password.d.ts.map +1 -0
- package/lib/planetscale/password.js +238 -0
- package/lib/planetscale/password.js.map +1 -0
- package/lib/scope.d.ts +6 -5
- package/lib/scope.d.ts.map +1 -1
- package/lib/scope.js +18 -7
- package/lib/scope.js.map +1 -1
- package/lib/test/bun.d.ts.map +1 -1
- package/lib/test/bun.js +1 -0
- package/lib/test/bun.js.map +1 -1
- package/lib/test/vitest.d.ts.map +1 -1
- package/lib/test/vitest.js +1 -0
- package/lib/test/vitest.js.map +1 -1
- package/lib/util/nanoid.d.ts +3 -0
- package/lib/util/nanoid.d.ts.map +1 -0
- package/lib/util/nanoid.js +13 -0
- package/lib/util/nanoid.js.map +1 -0
- package/lib/util/safe-fetch.d.ts.map +1 -1
- package/lib/util/safe-fetch.js +0 -1
- package/lib/util/safe-fetch.js.map +1 -1
- package/lib/util/telemetry/client.d.ts.map +1 -1
- package/lib/util/telemetry/client.js +13 -3
- package/lib/util/telemetry/client.js.map +1 -1
- package/lib/util/telemetry/constants.d.ts +2 -1
- package/lib/util/telemetry/constants.d.ts.map +1 -1
- package/lib/util/telemetry/constants.js +3 -2
- package/lib/util/telemetry/constants.js.map +1 -1
- package/package.json +10 -2
- package/src/alchemy.ts +8 -13
- package/src/apply.ts +2 -0
- package/src/build-date.ts +1 -1
- package/src/cloudflare/bucket.ts +22 -14
- package/src/cloudflare/bundle/bundle-worker-dev.ts +4 -1
- package/src/cloudflare/bundle/bundle-worker.ts +4 -1
- package/src/cloudflare/bundle/external.ts +1 -1
- package/src/cloudflare/bundle/nodejs-import-warning-plugin.ts +94 -0
- package/src/cloudflare/container.ts +113 -28
- package/src/cloudflare/redirect-rule.ts +1 -1
- package/src/cloudflare/website.ts +21 -1
- package/src/cloudflare/worker/miniflare.ts +33 -8
- package/src/cloudflare/worker-metadata.ts +15 -0
- package/src/cloudflare/wrangler.json.ts +61 -5
- package/src/context.ts +7 -0
- package/src/destroy.ts +1 -0
- package/src/docker/api.ts +57 -1
- package/src/docker/image.ts +15 -6
- package/src/index.ts +1 -0
- package/src/llms.cloudflare.txt +379 -0
- package/src/llms.ts +25 -0
- package/src/planetscale/index.ts +3 -2
- package/src/planetscale/password.ts +366 -0
- package/src/scope.ts +25 -11
- package/src/test/bun.ts +1 -0
- package/src/test/vitest.ts +1 -0
- package/src/util/nanoid.ts +13 -0
- package/src/util/safe-fetch.ts +0 -1
- package/src/util/telemetry/client.ts +17 -3
- package/src/util/telemetry/constants.ts +5 -3
package/lib/docker/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/docker/api.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/docker/api.ts"],"names":[],"mappings":"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"}
|
package/lib/docker/api.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import { Buffer } from "node:buffer";
|
|
1
2
|
import { spawn } from "node:child_process";
|
|
3
|
+
import fs from "node:fs/promises";
|
|
4
|
+
import path from "node:path";
|
|
2
5
|
import { exec } from "../os/exec.js";
|
|
3
6
|
/**
|
|
4
7
|
* Docker API client that wraps Docker CLI commands
|
|
@@ -6,6 +9,8 @@ import { exec } from "../os/exec.js";
|
|
|
6
9
|
export class DockerApi {
|
|
7
10
|
/** Path to Docker CLI */
|
|
8
11
|
dockerPath;
|
|
12
|
+
/** Directory to use for Docker CLI config */
|
|
13
|
+
configDir;
|
|
9
14
|
/**
|
|
10
15
|
* Create a new Docker API client
|
|
11
16
|
*
|
|
@@ -13,6 +18,7 @@ export class DockerApi {
|
|
|
13
18
|
*/
|
|
14
19
|
constructor(options = {}) {
|
|
15
20
|
this.dockerPath = options.dockerPath || "docker";
|
|
21
|
+
this.configDir = options.configDir;
|
|
16
22
|
}
|
|
17
23
|
/**
|
|
18
24
|
* Run a Docker CLI command
|
|
@@ -21,11 +27,16 @@ export class DockerApi {
|
|
|
21
27
|
* @returns Result of the command
|
|
22
28
|
*/
|
|
23
29
|
async exec(args) {
|
|
30
|
+
// If a custom config directory is provided, ensure all commands use it by
|
|
31
|
+
// setting the DOCKER_CONFIG env variable for the spawned process.
|
|
32
|
+
const env = this.configDir
|
|
33
|
+
? { ...process.env, DOCKER_CONFIG: this.configDir }
|
|
34
|
+
: process.env;
|
|
24
35
|
const command = `${this.dockerPath} ${args.join(" ")}`;
|
|
25
36
|
const result = (await exec(command, {
|
|
26
37
|
captureOutput: true,
|
|
27
38
|
shell: true,
|
|
28
|
-
env
|
|
39
|
+
env,
|
|
29
40
|
}));
|
|
30
41
|
return result;
|
|
31
42
|
}
|
|
@@ -294,6 +305,22 @@ export class DockerApi {
|
|
|
294
305
|
* @returns Promise that resolves when login is successful
|
|
295
306
|
*/
|
|
296
307
|
async login(registry, username, password) {
|
|
308
|
+
// If we have a custom config directory, write credentials directly to
|
|
309
|
+
// config.json to avoid race conditions with the global credential store
|
|
310
|
+
if (this.configDir) {
|
|
311
|
+
const authConfigPath = path.join(this.configDir, "config.json");
|
|
312
|
+
const authToken = Buffer.from(`${username}:${password}`).toString("base64");
|
|
313
|
+
const configJson = {
|
|
314
|
+
auths: {
|
|
315
|
+
[registry]: {
|
|
316
|
+
auth: authToken,
|
|
317
|
+
},
|
|
318
|
+
},
|
|
319
|
+
};
|
|
320
|
+
await fs.writeFile(authConfigPath, JSON.stringify(configJson));
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
// Fallback to original docker login behavior for backwards compatibility
|
|
297
324
|
return new Promise((resolve, reject) => {
|
|
298
325
|
const args = [
|
|
299
326
|
"login",
|
|
@@ -335,6 +362,19 @@ export class DockerApi {
|
|
|
335
362
|
* @param registry Registry URL
|
|
336
363
|
*/
|
|
337
364
|
async logout(registry) {
|
|
365
|
+
// If we have a custom config directory, we can just remove the auth entry
|
|
366
|
+
// or delete the config file entirely since it's isolated
|
|
367
|
+
if (this.configDir) {
|
|
368
|
+
try {
|
|
369
|
+
const authConfigPath = path.join(this.configDir, "config.json");
|
|
370
|
+
await fs.unlink(authConfigPath);
|
|
371
|
+
}
|
|
372
|
+
catch {
|
|
373
|
+
// Ignore errors - file might not exist or already be deleted
|
|
374
|
+
}
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
// Fallback to original docker logout behavior
|
|
338
378
|
try {
|
|
339
379
|
await this.exec(["logout", registry]);
|
|
340
380
|
}
|
package/lib/docker/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/docker/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/docker/api.ts"],"names":[],"mappings":"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"}
|
package/lib/docker/image.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../src/docker/image.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../src/docker/image.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAG3C;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE9B;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAE3B;;OAEG;IACH,QAAQ,CAAC,EAAE,aAAa,CAAC;IAEzB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,KAAM,SAAQ,QAAQ,CAAC,eAAe,CAAC,EAAE,UAAU;IAClE;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,KAAK,yFAGR,OAAO,CAAC,KAAK,CAAC,MAChB,MAAM,SACH,UAAU,KAChB,OAAO,CAAC,KAAK,CAAC,CA8IlB,CAAC"}
|
package/lib/docker/image.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
|
+
import os from "node:os";
|
|
2
3
|
import path from "node:path";
|
|
3
4
|
import { Resource } from "../resource.js";
|
|
4
5
|
import { DockerApi } from "./api.js";
|
|
@@ -20,8 +21,13 @@ import { DockerApi } from "./api.js";
|
|
|
20
21
|
* });
|
|
21
22
|
*/
|
|
22
23
|
export const Image = Resource("docker::Image", async function (id, props) {
|
|
23
|
-
//
|
|
24
|
-
|
|
24
|
+
// Create a temporary directory that will act as an isolated Docker config
|
|
25
|
+
// (credentials) directory. This prevents race-conditions when multiple
|
|
26
|
+
// concurrent tests perform `docker login` / `logout` by ensuring each
|
|
27
|
+
// Image operation has its own credential store.
|
|
28
|
+
const tempConfigDir = await fs.mkdtemp(path.join(os.tmpdir(), "docker-config-"));
|
|
29
|
+
// Initialize Docker API client with the isolated config directory
|
|
30
|
+
const api = new DockerApi({ configDir: tempConfigDir });
|
|
25
31
|
if (this.phase === "delete") {
|
|
26
32
|
// No action needed for delete as Docker images aren't automatically removed
|
|
27
33
|
// This is intentional as other resources might depend on the same image
|
|
@@ -53,7 +59,7 @@ export const Image = Resource("docker::Image", async function (id, props) {
|
|
|
53
59
|
await fs.access(context);
|
|
54
60
|
await fs.access(dockerfile);
|
|
55
61
|
// Prepare build options
|
|
56
|
-
const buildOptions = props.build?.
|
|
62
|
+
const buildOptions = props.build?.args || {};
|
|
57
63
|
// Add platform if specified
|
|
58
64
|
let buildArgs = ["build", "-t", imageRef];
|
|
59
65
|
if (props.build?.platform) {
|
|
@@ -96,7 +102,7 @@ export const Image = Resource("docker::Image", async function (id, props) {
|
|
|
96
102
|
? imageRef // already fully-qualified
|
|
97
103
|
: `${registryHost}/${imageRef}`;
|
|
98
104
|
try {
|
|
99
|
-
// Authenticate to registry
|
|
105
|
+
// Authenticate to registry using the isolated config directory
|
|
100
106
|
await api.login(registryHost, username, password.unencrypted);
|
|
101
107
|
// Tag local image with fully qualified name if necessary
|
|
102
108
|
if (targetImage !== imageRef) {
|
|
@@ -118,7 +124,7 @@ export const Image = Resource("docker::Image", async function (id, props) {
|
|
|
118
124
|
finalImageRef = targetImage;
|
|
119
125
|
}
|
|
120
126
|
finally {
|
|
121
|
-
//
|
|
127
|
+
// Clean up credentials from the isolated config
|
|
122
128
|
await api.logout(registryHost);
|
|
123
129
|
}
|
|
124
130
|
}
|
package/lib/docker/image.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image.js","sourceRoot":"","sources":["../../src/docker/image.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AA2GrC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,QAAQ,CAC3B,eAAe,EACf,KAAK,WAEH,EAAU,EACV,KAAiB;IAEjB
|
|
1
|
+
{"version":3,"file":"image.js","sourceRoot":"","sources":["../../src/docker/image.ts"],"names":[],"mappings":"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"}
|
package/lib/esbuild/bundle.d.ts
CHANGED
|
@@ -102,12 +102,12 @@ export declare function bundle(props: BundleProps): Promise<esbuild.BuildResult<
|
|
|
102
102
|
outdir: string | undefined;
|
|
103
103
|
outfile: string | undefined;
|
|
104
104
|
bundle: boolean;
|
|
105
|
-
format: "
|
|
105
|
+
format: "esm" | "cjs" | "iife" | undefined;
|
|
106
106
|
target: string | string[] | undefined;
|
|
107
107
|
minify: boolean | undefined;
|
|
108
108
|
sourcemap: boolean | "external" | "inline" | "both" | undefined;
|
|
109
109
|
external: string[] | undefined;
|
|
110
|
-
platform: "
|
|
110
|
+
platform: "browser" | "node" | "neutral" | undefined;
|
|
111
111
|
metafile: boolean;
|
|
112
112
|
splitting?: boolean | undefined;
|
|
113
113
|
preserveSymlinks?: boolean | undefined;
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC1D,mBAAmB,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC1D,mBAAmB,cAAc,CAAC;AAElC,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AAEjC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,eAAe,OAAO,CAAC"}
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AAEjC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,eAAe,OAAO,CAAC"}
|
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
# Alchemy - TypeScript-native Infrastructure as Code
|
|
2
|
+
|
|
3
|
+
Alchemy is a TypeScript-native Infrastructure-as-Code framework that allows you to define cloud resources using familiar TypeScript patterns. This guide focuses on Cloudflare integration.
|
|
4
|
+
|
|
5
|
+
## Core Concepts
|
|
6
|
+
|
|
7
|
+
**Resources**: Async functions that manage cloud infrastructure lifecycle (create, update, delete)
|
|
8
|
+
**Bindings**: Type-safe connections between resources (workers, KV stores, databases)
|
|
9
|
+
**State Management**: Tracks resource state for consistent deployments
|
|
10
|
+
**Finalization**: Always call `app.finalize()` to clean up orphaned resources
|
|
11
|
+
|
|
12
|
+
## Basic Setup
|
|
13
|
+
|
|
14
|
+
### Project Structure
|
|
15
|
+
```typescript
|
|
16
|
+
// alchemy.run.ts - Your infrastructure definition
|
|
17
|
+
import alchemy from "alchemy";
|
|
18
|
+
import { Worker, KVNamespace } from "alchemy/cloudflare";
|
|
19
|
+
|
|
20
|
+
const app = await alchemy("my-app");
|
|
21
|
+
|
|
22
|
+
export const worker = await Worker("api", {
|
|
23
|
+
entrypoint: "./src/worker.ts",
|
|
24
|
+
bindings: {
|
|
25
|
+
CACHE: await KVNamespace("cache", { title: "cache-store" })
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
console.log({ url: worker.url });
|
|
30
|
+
await app.finalize(); // ⚠️ ALWAYS call finalize()
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Environment Setup
|
|
34
|
+
```bash
|
|
35
|
+
# .env - Required for secret encryption
|
|
36
|
+
ALCHEMY_PASSWORD=your-secure-password
|
|
37
|
+
|
|
38
|
+
# Optional: Use Cloudflare state store in production
|
|
39
|
+
ALCHEMY_STATE_STORE=cloudflare
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Commands
|
|
43
|
+
```bash
|
|
44
|
+
bun ./alchemy.run.ts # Deploy
|
|
45
|
+
bun ./alchemy.run.ts --destroy # Destroy all resources
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Workers
|
|
49
|
+
|
|
50
|
+
### Basic Worker
|
|
51
|
+
```typescript
|
|
52
|
+
const worker = await Worker("api", {
|
|
53
|
+
entrypoint: "./src/worker.ts",
|
|
54
|
+
url: true, // Get public URL
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Worker with Bindings
|
|
59
|
+
```typescript
|
|
60
|
+
const worker = await Worker("api", {
|
|
61
|
+
entrypoint: "./src/worker.ts",
|
|
62
|
+
bindings: {
|
|
63
|
+
// Resource bindings
|
|
64
|
+
CACHE: kvNamespace,
|
|
65
|
+
STORAGE: r2Bucket,
|
|
66
|
+
COUNTER: durableObjectNamespace,
|
|
67
|
+
QUEUE: queue,
|
|
68
|
+
API: otherWorker,
|
|
69
|
+
|
|
70
|
+
// Environment variables
|
|
71
|
+
API_KEY: alchemy.secret(process.env.API_KEY),
|
|
72
|
+
DEBUG: "true"
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Worker Implementation
|
|
78
|
+
```typescript
|
|
79
|
+
// src/worker.ts
|
|
80
|
+
import type { worker } from "../alchemy.run";
|
|
81
|
+
|
|
82
|
+
export default {
|
|
83
|
+
async fetch(request: Request, env: typeof worker.Env): Promise<Response> {
|
|
84
|
+
// Type-safe access to all bindings
|
|
85
|
+
const cached = await env.CACHE.get("key");
|
|
86
|
+
const apiKey = env.API_KEY;
|
|
87
|
+
|
|
88
|
+
return new Response("Hello World");
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Type Safety Setup
|
|
94
|
+
```typescript
|
|
95
|
+
// types/env.d.ts
|
|
96
|
+
import type { worker } from "../alchemy.run";
|
|
97
|
+
|
|
98
|
+
declare module "cloudflare:workers" {
|
|
99
|
+
namespace Cloudflare {
|
|
100
|
+
export interface Env extends typeof worker.Env {}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Durable Objects
|
|
106
|
+
|
|
107
|
+
### Creating Durable Object Namespace
|
|
108
|
+
```typescript
|
|
109
|
+
// Use 'new' instead of 'await' for DurableObjectNamespace
|
|
110
|
+
const counter = new DurableObjectNamespace("counter", {
|
|
111
|
+
className: "Counter",
|
|
112
|
+
sqlite: true, // Enable SQLite storage
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
const worker = await Worker("api", {
|
|
116
|
+
entrypoint: "./src/worker.ts",
|
|
117
|
+
bindings: {
|
|
118
|
+
COUNTER: counter, // Bind to worker
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Durable Object Implementation
|
|
124
|
+
```typescript
|
|
125
|
+
// src/counter.ts
|
|
126
|
+
import { DurableObject } from "cloudflare:workers";
|
|
127
|
+
|
|
128
|
+
export class Counter extends DurableObject {
|
|
129
|
+
async increment(): Promise<number> {
|
|
130
|
+
let count = (await this.ctx.storage.get("count")) || 0;
|
|
131
|
+
count++;
|
|
132
|
+
await this.ctx.storage.put("count", count);
|
|
133
|
+
return count;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async fetch(request: Request): Promise<Response> {
|
|
137
|
+
const count = await this.increment();
|
|
138
|
+
return new Response(JSON.stringify({ count }));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Using Durable Objects in Worker
|
|
144
|
+
```typescript
|
|
145
|
+
// src/worker.ts
|
|
146
|
+
export default {
|
|
147
|
+
async fetch(request: Request, env: typeof worker.Env) {
|
|
148
|
+
// Get a Durable Object instance
|
|
149
|
+
const id = env.COUNTER.idFromName("global-counter");
|
|
150
|
+
const obj = env.COUNTER.get(id);
|
|
151
|
+
|
|
152
|
+
// Call the Durable Object
|
|
153
|
+
return obj.fetch(request);
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Cross-Script Durable Objects
|
|
159
|
+
```typescript
|
|
160
|
+
// Method 1: Re-export from provider worker
|
|
161
|
+
const sharedCounter = host.bindings.SHARED_COUNTER;
|
|
162
|
+
|
|
163
|
+
// Method 2: Reference by worker script name
|
|
164
|
+
const counter = new DurableObjectNamespace("counter", {
|
|
165
|
+
className: "Counter",
|
|
166
|
+
scriptName: "provider-worker"
|
|
167
|
+
});
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Key Resources
|
|
171
|
+
|
|
172
|
+
### KV Namespace
|
|
173
|
+
```typescript
|
|
174
|
+
const cache = await KVNamespace("cache", {
|
|
175
|
+
title: "my-cache-store"
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
// Usage in worker
|
|
179
|
+
const value = await env.CACHE.get("key");
|
|
180
|
+
await env.CACHE.put("key", "value", { expirationTtl: 3600 });
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### R2 Bucket
|
|
184
|
+
```typescript
|
|
185
|
+
const storage = await R2Bucket("storage", {
|
|
186
|
+
allowPublicAccess: false
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
// Usage in worker
|
|
190
|
+
const object = await env.STORAGE.get("file.txt");
|
|
191
|
+
await env.STORAGE.put("file.txt", "content");
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Queue
|
|
195
|
+
```typescript
|
|
196
|
+
// Typed queue
|
|
197
|
+
const queue = await Queue<{ name: string; email: string }>("notifications");
|
|
198
|
+
|
|
199
|
+
// Producer worker
|
|
200
|
+
const producer = await Worker("producer", {
|
|
201
|
+
bindings: { QUEUE: queue },
|
|
202
|
+
// Queue sending code
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
// Consumer worker
|
|
206
|
+
const consumer = await Worker("consumer", {
|
|
207
|
+
eventSources: [queue], // Register as consumer
|
|
208
|
+
// Queue processing code
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// Worker implementation for queue processing
|
|
212
|
+
export default {
|
|
213
|
+
async queue(batch: typeof queue.Batch, env: Env) {
|
|
214
|
+
for (const message of batch.messages) {
|
|
215
|
+
console.log("Processing:", message.body);
|
|
216
|
+
message.ack(); // Acknowledge message
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Custom Domains
|
|
223
|
+
```typescript
|
|
224
|
+
const worker = await Worker("api", {
|
|
225
|
+
entrypoint: "./src/worker.ts",
|
|
226
|
+
routes: [
|
|
227
|
+
{ pattern: "api.example.com/*", zone: "example.com" },
|
|
228
|
+
{ pattern: "example.com/api/*", zone: "example.com" }
|
|
229
|
+
]
|
|
230
|
+
});
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Converting Existing Cloudflare Projects
|
|
234
|
+
|
|
235
|
+
### 1. Migrate wrangler.toml Configuration
|
|
236
|
+
```toml
|
|
237
|
+
# Old wrangler.toml
|
|
238
|
+
name = "my-worker"
|
|
239
|
+
main = "src/index.js"
|
|
240
|
+
|
|
241
|
+
[env.production]
|
|
242
|
+
kv_namespaces = [
|
|
243
|
+
{ binding = "CACHE", id = "abc123" }
|
|
244
|
+
]
|
|
245
|
+
|
|
246
|
+
[[env.production.r2_buckets]]
|
|
247
|
+
binding = "STORAGE"
|
|
248
|
+
bucket_name = "my-bucket"
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
// New alchemy.run.ts
|
|
253
|
+
const worker = await Worker("my-worker", {
|
|
254
|
+
entrypoint: "./src/index.js",
|
|
255
|
+
bindings: {
|
|
256
|
+
CACHE: await KVNamespace("cache", {
|
|
257
|
+
title: "cache-store",
|
|
258
|
+
adopt: true // Use existing KV namespace
|
|
259
|
+
}),
|
|
260
|
+
STORAGE: await R2Bucket("storage", {
|
|
261
|
+
name: "my-bucket",
|
|
262
|
+
adopt: true // Use existing bucket
|
|
263
|
+
})
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### 2. Enable Development Compatibility
|
|
269
|
+
```typescript
|
|
270
|
+
// Generate wrangler.json for local development
|
|
271
|
+
await WranglerJson("wrangler.json", {
|
|
272
|
+
worker,
|
|
273
|
+
});
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### 3. Adopt Existing Resources
|
|
277
|
+
```typescript
|
|
278
|
+
// Use adopt: true to use existing resources instead of failing
|
|
279
|
+
const bucket = await R2Bucket("storage", {
|
|
280
|
+
name: "existing-bucket-name",
|
|
281
|
+
adopt: true // Won't fail if bucket already exists
|
|
282
|
+
});
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### 4. State Store Migration
|
|
286
|
+
```typescript
|
|
287
|
+
// Local development (default)
|
|
288
|
+
const app = await alchemy("my-app");
|
|
289
|
+
|
|
290
|
+
// Production with Cloudflare state store
|
|
291
|
+
const app = await alchemy("my-app", {
|
|
292
|
+
stateStore: process.env.NODE_ENV === "production"
|
|
293
|
+
? (scope) => new DOStateStore(scope)
|
|
294
|
+
: undefined
|
|
295
|
+
});
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
## Advanced Patterns
|
|
299
|
+
|
|
300
|
+
### Framework Integration (Vite/React/etc.)
|
|
301
|
+
```typescript
|
|
302
|
+
const website = await Vite("website", {
|
|
303
|
+
main: "./src/worker.ts",
|
|
304
|
+
command: "bun run build", // Build command
|
|
305
|
+
bindings: {
|
|
306
|
+
API: await Worker("api", { entrypoint: "./api/worker.ts" }),
|
|
307
|
+
STORAGE: await R2Bucket("assets")
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### Resource Scoping
|
|
313
|
+
```typescript
|
|
314
|
+
// Organize resources into logical groups
|
|
315
|
+
await alchemy.run("backend", async () => {
|
|
316
|
+
await Worker("api", { entrypoint: "./api.ts" });
|
|
317
|
+
await KVNamespace("cache", { title: "api-cache" });
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
await alchemy.run("frontend", async () => {
|
|
321
|
+
await Vite("website", { main: "./src/worker.ts" });
|
|
322
|
+
});
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### Testing Pattern
|
|
326
|
+
```typescript
|
|
327
|
+
import { alchemy } from "../../src/alchemy";
|
|
328
|
+
const test = alchemy.test(import.meta, { prefix: "test" });
|
|
329
|
+
|
|
330
|
+
describe("Worker Tests", () => {
|
|
331
|
+
test("creates worker", async (scope) => {
|
|
332
|
+
const worker = await Worker("test-worker", {
|
|
333
|
+
entrypoint: "./src/worker.ts"
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
expect(worker.url).toBeTruthy();
|
|
337
|
+
// Resources auto-cleaned after test
|
|
338
|
+
});
|
|
339
|
+
});
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
## Best Practices
|
|
343
|
+
|
|
344
|
+
1. **Always call finalize()**: `await app.finalize()` at the end of your script
|
|
345
|
+
2. **Use adoption for migrations**: `adopt: true` when converting existing projects
|
|
346
|
+
3. **Type-safe bindings**: Set up env.d.ts for full type safety
|
|
347
|
+
4. **Resource naming**: Use consistent, descriptive names for resources
|
|
348
|
+
5. **State store**: Use DOStateStore for production deployments
|
|
349
|
+
6. **Secrets**: Use `alchemy.secret()` for sensitive values
|
|
350
|
+
7. **Scoping**: Organize related resources using `alchemy.run()`
|
|
351
|
+
8. **Testing**: Use `alchemy.test()` for integration tests
|
|
352
|
+
|
|
353
|
+
## Common Issues
|
|
354
|
+
|
|
355
|
+
- **Missing finalize()**: Resources won't be cleaned up properly
|
|
356
|
+
- **Wrong DurableObject syntax**: Use `new DurableObjectNamespace()` not `await`
|
|
357
|
+
- **Type errors**: Set up env.d.ts file for binding types
|
|
358
|
+
- **State conflicts**: Use different stages/prefixes for different environments
|
|
359
|
+
- **Resource adoption**: Use `adopt: true` when migrating existing resources
|
|
360
|
+
|
|
361
|
+
## Development Workflow
|
|
362
|
+
|
|
363
|
+
```bash
|
|
364
|
+
# Create new project
|
|
365
|
+
bunx alchemy create my-app --template=vite
|
|
366
|
+
cd my-app
|
|
367
|
+
|
|
368
|
+
# Set up authentication (one-time)
|
|
369
|
+
bun wrangler login
|
|
370
|
+
|
|
371
|
+
# Deploy infrastructure
|
|
372
|
+
bun run deploy
|
|
373
|
+
|
|
374
|
+
# Local development
|
|
375
|
+
bun run dev
|
|
376
|
+
|
|
377
|
+
# Clean up
|
|
378
|
+
bun run destroy
|
|
379
|
+
```
|
package/lib/llms.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llms.d.ts","sourceRoot":"","sources":["../src/llms.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAC3B;AAaD,QAAA,MAAM,YAAY,EAAE,WAAW,EAAc,CAAC;AAE9C,eAAe,YAAY,CAAC"}
|
package/lib/llms.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
const alchemy = {
|
|
4
|
+
name: "cloudflare",
|
|
5
|
+
description: "Core Alchemy development guidelines and patterns",
|
|
6
|
+
alwaysApply: true,
|
|
7
|
+
globs: ["*.ts"],
|
|
8
|
+
rule: await fs.readFile(path.join(import.meta.dirname, "llms.cloudflare.txt"), "utf-8"),
|
|
9
|
+
};
|
|
10
|
+
const alchemyRules = [alchemy];
|
|
11
|
+
export default alchemyRules;
|
|
12
|
+
//# sourceMappingURL=llms.js.map
|
package/lib/llms.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llms.js","sourceRoot":"","sources":["../src/llms.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAU7B,MAAM,OAAO,GAAgB;IAC3B,IAAI,EAAE,YAAY;IAClB,WAAW,EAAE,kDAAkD;IAC/D,WAAW,EAAE,IAAI;IACjB,KAAK,EAAE,CAAC,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,EAAE,CAAC,QAAQ,CACrB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,qBAAqB,CAAC,EACrD,OAAO,CACR;CACF,CAAC;AAEF,MAAM,YAAY,GAAkB,CAAC,OAAO,CAAC,CAAC;AAE9C,eAAe,YAAY,CAAC"}
|