alchemy 0.42.1 → 0.43.1

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.
Files changed (77) hide show
  1. package/bin/alchemy.mjs +508 -316
  2. package/lib/alchemy.d.ts.map +1 -1
  3. package/lib/alchemy.js +8 -2
  4. package/lib/alchemy.js.map +1 -1
  5. package/lib/build-date.d.ts +1 -1
  6. package/lib/build-date.js +1 -1
  7. package/lib/cloudflare/astro.d.ts +1 -1
  8. package/lib/cloudflare/astro.d.ts.map +1 -1
  9. package/lib/cloudflare/astro.js +1 -1
  10. package/lib/cloudflare/astro.js.map +1 -1
  11. package/lib/cloudflare/bundle/bundle-worker-dev.d.ts +1 -0
  12. package/lib/cloudflare/bundle/bundle-worker-dev.d.ts.map +1 -1
  13. package/lib/cloudflare/bundle/bundle-worker-dev.js +2 -3
  14. package/lib/cloudflare/bundle/bundle-worker-dev.js.map +1 -1
  15. package/lib/cloudflare/bundle/bundle-worker.d.ts +1 -0
  16. package/lib/cloudflare/bundle/bundle-worker.d.ts.map +1 -1
  17. package/lib/cloudflare/bundle/bundle-worker.js +2 -3
  18. package/lib/cloudflare/bundle/bundle-worker.js.map +1 -1
  19. package/lib/cloudflare/d1-database.d.ts.map +1 -1
  20. package/lib/cloudflare/d1-database.js +17 -0
  21. package/lib/cloudflare/d1-database.js.map +1 -1
  22. package/lib/cloudflare/d1-migrations.d.ts +5 -2
  23. package/lib/cloudflare/d1-migrations.d.ts.map +1 -1
  24. package/lib/cloudflare/d1-migrations.js +166 -14
  25. package/lib/cloudflare/d1-migrations.js.map +1 -1
  26. package/lib/cloudflare/website.d.ts.map +1 -1
  27. package/lib/cloudflare/website.js +11 -22
  28. package/lib/cloudflare/website.js.map +1 -1
  29. package/lib/cloudflare/worker/http-server.d.ts.map +1 -1
  30. package/lib/cloudflare/worker/http-server.js +2 -1
  31. package/lib/cloudflare/worker/http-server.js.map +1 -1
  32. package/lib/cloudflare/worker/miniflare.d.ts +1 -0
  33. package/lib/cloudflare/worker/miniflare.d.ts.map +1 -1
  34. package/lib/cloudflare/worker/miniflare.js +2 -1
  35. package/lib/cloudflare/worker/miniflare.js.map +1 -1
  36. package/lib/cloudflare/worker.d.ts +11 -1
  37. package/lib/cloudflare/worker.d.ts.map +1 -1
  38. package/lib/cloudflare/worker.js +31 -16
  39. package/lib/cloudflare/worker.js.map +1 -1
  40. package/lib/cloudflare/wrangler.json.d.ts +1 -1
  41. package/lib/cloudflare/wrangler.json.d.ts.map +1 -1
  42. package/lib/cloudflare/wrangler.json.js +28 -10
  43. package/lib/cloudflare/wrangler.json.js.map +1 -1
  44. package/lib/internal/docs/providers.js +2 -0
  45. package/lib/internal/docs/providers.js.map +1 -1
  46. package/lib/os/exec.d.ts +15 -1
  47. package/lib/os/exec.d.ts.map +1 -1
  48. package/lib/os/exec.js +30 -3
  49. package/lib/os/exec.js.map +1 -1
  50. package/lib/scope.d.ts.map +1 -1
  51. package/lib/scope.js +4 -1
  52. package/lib/scope.js.map +1 -1
  53. package/lib/util/deferred-promise.d.ts.map +1 -1
  54. package/lib/util/deferred-promise.js +2 -1
  55. package/lib/util/deferred-promise.js.map +1 -1
  56. package/lib/util/promise-with-resolvers.d.ts +14 -0
  57. package/lib/util/promise-with-resolvers.d.ts.map +1 -0
  58. package/lib/util/promise-with-resolvers.js +19 -0
  59. package/lib/util/promise-with-resolvers.js.map +1 -0
  60. package/package.json +4 -3
  61. package/src/alchemy.ts +8 -2
  62. package/src/build-date.ts +1 -1
  63. package/src/cloudflare/astro.ts +1 -1
  64. package/src/cloudflare/bundle/bundle-worker-dev.ts +3 -4
  65. package/src/cloudflare/bundle/bundle-worker.ts +3 -4
  66. package/src/cloudflare/d1-database.ts +17 -0
  67. package/src/cloudflare/d1-migrations.ts +224 -14
  68. package/src/cloudflare/website.ts +14 -30
  69. package/src/cloudflare/worker/http-server.ts +2 -1
  70. package/src/cloudflare/worker/miniflare.ts +5 -1
  71. package/src/cloudflare/worker.ts +57 -27
  72. package/src/cloudflare/wrangler.json.ts +40 -11
  73. package/src/internal/docs/providers.ts +2 -0
  74. package/src/os/exec.ts +32 -4
  75. package/src/scope.ts +5 -1
  76. package/src/util/deferred-promise.ts +3 -1
  77. package/src/util/promise-with-resolvers.ts +30 -0
@@ -199,6 +199,8 @@ async function generateProviderDocs({
199
199
  See ${alchemy.file("./README.md")} to understand the overview of Alchemy.
200
200
  See ${alchemy.file("./.cursorrules")} to better understand the structure and convention of an Alchemy Resource.
201
201
 
202
+ Documentation should be written in the mdx format for an Astro Starlight documentation site.
203
+
202
204
  Relevant files for the ${providerName} Service:
203
205
  ${alchemy.files(files)}
204
206
 
package/src/os/exec.ts CHANGED
@@ -3,6 +3,7 @@ import { createHash } from "node:crypto";
3
3
  import { join } from "node:path";
4
4
  import type { Context } from "../context.ts";
5
5
  import { Resource } from "../resource.ts";
6
+ import type { Secret } from "../secret.ts";
6
7
 
7
8
  /**
8
9
  * Properties for executing a shell command
@@ -47,7 +48,7 @@ export interface ExecProps {
47
48
  /**
48
49
  * Environment variables to set
49
50
  */
50
- env?: Record<string, string>;
51
+ env?: Record<string, string | Secret<string>>;
51
52
 
52
53
  /**
53
54
  * Whether to inherit stdio from parent process
@@ -123,6 +124,19 @@ export interface Exec extends Resource<"os::Exec">, ExecProps {
123
124
  * });
124
125
  *
125
126
  * @example
127
+ * // Run a command with secrets in environment variables
128
+ * import alchemy from "alchemy";
129
+ *
130
+ * const deploy = await Exec("deploy-app", {
131
+ * command: "npm run deploy",
132
+ * env: {
133
+ * NODE_ENV: "production",
134
+ * API_KEY: alchemy.secret(process.env.API_KEY),
135
+ * DATABASE_URL: alchemy.secret(process.env.DATABASE_URL)
136
+ * }
137
+ * });
138
+ *
139
+ * @example
126
140
  * // Run a memoized command that only re-executes when the command changes
127
141
  * const memoizedCmd = await Exec("status-check", {
128
142
  * command: "git status",
@@ -198,10 +212,23 @@ export const Exec = Resource(
198
212
  // Parse the command into command and args
199
213
  const [cmd, ...args] = props.command.split(/\s+/);
200
214
 
215
+ // Process environment variables, extracting values from secrets
216
+ const processedEnv: Record<string, string> = {};
217
+ if (props.env) {
218
+ for (const [key, value] of Object.entries(props.env)) {
219
+ if (typeof value === "string") {
220
+ processedEnv[key] = value;
221
+ } else {
222
+ // Handle Secret objects
223
+ processedEnv[key] = value.unencrypted;
224
+ }
225
+ }
226
+ }
227
+
201
228
  // Use spawn for better stdio control
202
229
  const childProcess = spawn(cmd, args, {
203
230
  cwd: props.cwd || process.cwd(),
204
- env: { ...process.env, ...props.env },
231
+ env: { ...process.env, ...processedEnv },
205
232
  shell: true, // Use shell to handle complex commands
206
233
  stdio: inheritStdio ? "inherit" : "pipe", // Inherit stdio when requested
207
234
  });
@@ -342,13 +369,14 @@ export async function exec(
342
369
  }
343
370
 
344
371
  async function hashInputs(cwd: string, patterns: string[]) {
345
- const { glob, readFile } = await import("node:fs/promises");
372
+ const { glob } = await import("glob");
373
+ const { readFile } = await import("node:fs/promises");
346
374
 
347
375
  const hashes = new Map<string, string>();
348
376
 
349
377
  await Promise.all(
350
378
  patterns.flatMap(async (pattern) => {
351
- const files = await Array.fromAsync(glob(pattern, { cwd }));
379
+ const files = await glob(pattern, { cwd });
352
380
  return Promise.all(
353
381
  files.map(async (file: string) => {
354
382
  const path = join(cwd, file);
package/src/scope.ts CHANGED
@@ -48,7 +48,11 @@ export type PendingDeletions = Array<{
48
48
  }>;
49
49
 
50
50
  // TODO: support browser
51
- const DEFAULT_STAGE = process.env.ALCHEMY_STAGE ?? process.env.USER ?? "dev";
51
+ const DEFAULT_STAGE =
52
+ process.env.ALCHEMY_STAGE ??
53
+ process.env.USER ??
54
+ process.env.USERNAME ??
55
+ "dev";
52
56
 
53
57
  declare global {
54
58
  var __ALCHEMY_STORAGE__: AsyncLocalStorage<Scope>;
@@ -1,5 +1,7 @@
1
+ import { promiseWithResolvers } from "./promise-with-resolvers.ts";
2
+
1
3
  export class DeferredPromise<T> {
2
- private promise = Promise.withResolvers<T>();
4
+ private promise = promiseWithResolvers<T>();
3
5
 
4
6
  status: "pending" | "fulfilled" | "rejected" = "pending";
5
7
 
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Interface for the return type of promiseWithResolvers
3
+ */
4
+ export interface PromiseWithResolvers<T> {
5
+ promise: Promise<T>;
6
+ resolve: (value: T | PromiseLike<T>) => void;
7
+ reject: (reason?: any) => void;
8
+ }
9
+
10
+ /**
11
+ * Node 20+ compatible implementation of Promise.withResolvers()
12
+ * Falls back to native Promise.withResolvers when available (Node 22+)
13
+ */
14
+ export function promiseWithResolvers<T>(): PromiseWithResolvers<T> {
15
+ // Use native implementation if available
16
+ if (typeof Promise.withResolvers === "function") {
17
+ return Promise.withResolvers<T>();
18
+ }
19
+
20
+ // Fallback implementation for Node 20+
21
+ let resolve!: (value: T | PromiseLike<T>) => void;
22
+ let reject!: (reason?: any) => void;
23
+
24
+ const promise = new Promise<T>((res, rej) => {
25
+ resolve = res;
26
+ reject = rej;
27
+ });
28
+
29
+ return { promise, resolve, reject };
30
+ }