alchemy 0.12.21 → 0.13.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.
Files changed (269) hide show
  1. package/lib/ai/client.d.ts.map +1 -1
  2. package/lib/ai/client.js +3 -5
  3. package/lib/ai/client.js.map +1 -1
  4. package/lib/alchemy.d.ts +2 -1
  5. package/lib/alchemy.d.ts.map +1 -1
  6. package/lib/alchemy.js +87 -92
  7. package/lib/alchemy.js.map +1 -1
  8. package/lib/apply.d.ts.map +1 -1
  9. package/lib/apply.js +6 -0
  10. package/lib/apply.js.map +1 -1
  11. package/lib/aws/bucket.d.ts.map +1 -1
  12. package/lib/aws/bucket.js +55 -57
  13. package/lib/aws/bucket.js.map +1 -1
  14. package/lib/aws/function.d.ts.map +1 -1
  15. package/lib/aws/function.js +250 -252
  16. package/lib/aws/function.js.map +1 -1
  17. package/lib/aws/policy-attachment.d.ts.map +1 -1
  18. package/lib/aws/policy-attachment.js +4 -6
  19. package/lib/aws/policy-attachment.js.map +1 -1
  20. package/lib/aws/policy.d.ts.map +1 -1
  21. package/lib/aws/policy.js +63 -65
  22. package/lib/aws/policy.js.map +1 -1
  23. package/lib/aws/queue.js +88 -90
  24. package/lib/aws/queue.js.map +1 -1
  25. package/lib/aws/table.d.ts.map +1 -1
  26. package/lib/aws/table.js +95 -99
  27. package/lib/aws/table.js.map +1 -1
  28. package/lib/cloudflare/account-api-token.d.ts +1 -1
  29. package/lib/cloudflare/account-api-token.d.ts.map +1 -1
  30. package/lib/cloudflare/account-api-token.js +0 -1
  31. package/lib/cloudflare/account-api-token.js.map +1 -1
  32. package/lib/cloudflare/ai-gateway.js.map +1 -1
  33. package/lib/cloudflare/ai.d.ts +1 -1
  34. package/lib/cloudflare/ai.d.ts.map +1 -1
  35. package/lib/cloudflare/ai.js.map +1 -1
  36. package/lib/cloudflare/api.js +1 -5
  37. package/lib/cloudflare/api.js.map +1 -1
  38. package/lib/cloudflare/bucket.d.ts +2 -2
  39. package/lib/cloudflare/bucket.d.ts.map +1 -1
  40. package/lib/cloudflare/bucket.js +22 -24
  41. package/lib/cloudflare/bucket.js.map +1 -1
  42. package/lib/cloudflare/bundle/hybrid-nodejs-compat.d.ts +0 -3
  43. package/lib/cloudflare/bundle/hybrid-nodejs-compat.d.ts.map +1 -1
  44. package/lib/cloudflare/bundle/hybrid-nodejs-compat.js +3 -4
  45. package/lib/cloudflare/bundle/hybrid-nodejs-compat.js.map +1 -1
  46. package/lib/cloudflare/custom-domain.d.ts.map +1 -1
  47. package/lib/cloudflare/custom-domain.js +3 -5
  48. package/lib/cloudflare/custom-domain.js.map +1 -1
  49. package/lib/cloudflare/d1-database.d.ts +1 -1
  50. package/lib/cloudflare/d1-database.d.ts.map +1 -1
  51. package/lib/cloudflare/d1-database.js +70 -72
  52. package/lib/cloudflare/d1-database.js.map +1 -1
  53. package/lib/cloudflare/d1-migrations.d.ts +1 -1
  54. package/lib/cloudflare/d1-migrations.d.ts.map +1 -1
  55. package/lib/cloudflare/d1-migrations.js +2 -3
  56. package/lib/cloudflare/d1-migrations.js.map +1 -1
  57. package/lib/cloudflare/dns-records.d.ts.map +1 -1
  58. package/lib/cloudflare/dns-records.js +2 -4
  59. package/lib/cloudflare/dns-records.js.map +1 -1
  60. package/lib/cloudflare/kv-namespace.d.ts +1 -1
  61. package/lib/cloudflare/kv-namespace.d.ts.map +1 -1
  62. package/lib/cloudflare/kv-namespace.js +24 -27
  63. package/lib/cloudflare/kv-namespace.js.map +1 -1
  64. package/lib/cloudflare/pipeline.d.ts +1 -1
  65. package/lib/cloudflare/pipeline.d.ts.map +1 -1
  66. package/lib/cloudflare/pipeline.js +32 -34
  67. package/lib/cloudflare/pipeline.js.map +1 -1
  68. package/lib/cloudflare/queue-consumer.d.ts +1 -1
  69. package/lib/cloudflare/queue-consumer.d.ts.map +1 -1
  70. package/lib/cloudflare/queue-consumer.js +31 -33
  71. package/lib/cloudflare/queue-consumer.js.map +1 -1
  72. package/lib/cloudflare/queue.d.ts +1 -1
  73. package/lib/cloudflare/queue.d.ts.map +1 -1
  74. package/lib/cloudflare/queue.js +36 -38
  75. package/lib/cloudflare/queue.js.map +1 -1
  76. package/lib/cloudflare/r2-rest-state-store.js +4 -8
  77. package/lib/cloudflare/r2-rest-state-store.js.map +1 -1
  78. package/lib/cloudflare/types.d.ts.map +1 -1
  79. package/lib/cloudflare/types.js +1 -3
  80. package/lib/cloudflare/types.js.map +1 -1
  81. package/lib/cloudflare/vectorize-index.d.ts.map +1 -1
  82. package/lib/cloudflare/vectorize-index.js +37 -39
  83. package/lib/cloudflare/vectorize-index.js.map +1 -1
  84. package/lib/cloudflare/vectorize-metadata-index.d.ts +1 -1
  85. package/lib/cloudflare/vectorize-metadata-index.d.ts.map +1 -1
  86. package/lib/cloudflare/vectorize-metadata-index.js +10 -13
  87. package/lib/cloudflare/vectorize-metadata-index.js.map +1 -1
  88. package/lib/cloudflare/worker.js +6 -12
  89. package/lib/cloudflare/worker.js.map +1 -1
  90. package/lib/cloudflare/workflow.d.ts +1 -1
  91. package/lib/cloudflare/workflow.d.ts.map +1 -1
  92. package/lib/cloudflare/workflow.js.map +1 -1
  93. package/lib/cloudflare/zone.d.ts.map +1 -1
  94. package/lib/cloudflare/zone.js +48 -50
  95. package/lib/cloudflare/zone.js.map +1 -1
  96. package/lib/dns/godaddy.js +1 -1
  97. package/lib/dns/import-dns.js +1 -1
  98. package/lib/dns/import-dns.js.map +1 -1
  99. package/lib/env.js +7 -9
  100. package/lib/env.js.map +1 -1
  101. package/lib/esbuild/bundle.js +8 -10
  102. package/lib/esbuild/bundle.js.map +1 -1
  103. package/lib/fs/copy-file.d.ts.map +1 -1
  104. package/lib/fs/copy-file.js +27 -29
  105. package/lib/fs/copy-file.js.map +1 -1
  106. package/lib/fs/file.d.ts +1 -1
  107. package/lib/fs/file.d.ts.map +1 -1
  108. package/lib/fs/file.js +1 -1
  109. package/lib/fs/file.js.map +1 -1
  110. package/lib/fs/folder.d.ts.map +1 -1
  111. package/lib/fs/folder.js +1 -3
  112. package/lib/fs/folder.js.map +1 -1
  113. package/lib/github/client.d.ts.map +1 -1
  114. package/lib/github/client.js +3 -5
  115. package/lib/github/client.js.map +1 -1
  116. package/lib/github/repository-environment.d.ts.map +1 -1
  117. package/lib/github/repository-environment.js +173 -176
  118. package/lib/github/repository-environment.js.map +1 -1
  119. package/lib/github/secret.d.ts.map +1 -1
  120. package/lib/github/secret.js +97 -99
  121. package/lib/github/secret.js.map +1 -1
  122. package/lib/internal/docs/providers.d.ts.map +1 -1
  123. package/lib/internal/docs/providers.js +5 -7
  124. package/lib/internal/docs/providers.js.map +1 -1
  125. package/lib/neon/api.js +1 -2
  126. package/lib/neon/api.js.map +1 -1
  127. package/lib/neon/project.js +2 -2
  128. package/lib/neon/project.js.map +1 -1
  129. package/lib/os/exec.d.ts +5 -0
  130. package/lib/os/exec.d.ts.map +1 -1
  131. package/lib/os/exec.js +88 -56
  132. package/lib/os/exec.js.map +1 -1
  133. package/lib/scope.d.ts +3 -0
  134. package/lib/scope.d.ts.map +1 -1
  135. package/lib/scope.js +10 -3
  136. package/lib/scope.js.map +1 -1
  137. package/lib/secret.d.ts.map +1 -1
  138. package/lib/secret.js +1 -3
  139. package/lib/secret.js.map +1 -1
  140. package/lib/serde.d.ts.map +1 -1
  141. package/lib/serde.js +13 -15
  142. package/lib/serde.js.map +1 -1
  143. package/lib/stripe/price.d.ts.map +1 -1
  144. package/lib/stripe/price.js +69 -73
  145. package/lib/stripe/price.js.map +1 -1
  146. package/lib/stripe/product.d.ts.map +1 -1
  147. package/lib/stripe/product.js +50 -52
  148. package/lib/stripe/product.js.map +1 -1
  149. package/lib/stripe/webhook.d.ts.map +1 -1
  150. package/lib/stripe/webhook.js +51 -53
  151. package/lib/stripe/webhook.js.map +1 -1
  152. package/lib/test/bun.d.ts +1 -1
  153. package/lib/test/bun.d.ts.map +1 -1
  154. package/lib/test/bun.js +1 -0
  155. package/lib/test/bun.js.map +1 -1
  156. package/lib/test/prune.d.ts.map +1 -1
  157. package/lib/test/prune.js.map +1 -1
  158. package/lib/util/dedent.js +4 -4
  159. package/lib/util/dedent.js.map +1 -1
  160. package/lib/web/astro.js +1 -1
  161. package/lib/web/shadcn.js +4 -4
  162. package/lib/web/shadcn.js.map +1 -1
  163. package/lib/web/tailwind.d.ts.map +1 -1
  164. package/lib/web/tailwind.js +0 -1
  165. package/lib/web/tailwind.js.map +1 -1
  166. package/lib/web/vite.js +3 -3
  167. package/lib/web/vitepress/home-page.d.ts.map +1 -1
  168. package/lib/web/vitepress/home-page.js +6 -8
  169. package/lib/web/vitepress/home-page.js.map +1 -1
  170. package/lib/web/vitepress/process-front-matter-files.js +1 -1
  171. package/lib/web/vitepress/process-front-matter-files.js.map +1 -1
  172. package/lib/web/vitepress/vitepress.js +2 -2
  173. package/lib/web/vitepress/vitepress.js.map +1 -1
  174. package/package.json +1 -1
  175. package/src/ai/astro-file.ts +4 -4
  176. package/src/ai/client.ts +4 -5
  177. package/src/ai/css-file.ts +4 -4
  178. package/src/ai/document.ts +3 -3
  179. package/src/ai/html-file.ts +4 -4
  180. package/src/ai/json-file.ts +1 -1
  181. package/src/ai/typescript-file.ts +4 -4
  182. package/src/ai/vue-file.ts +4 -4
  183. package/src/ai/yaml-file.ts +1 -1
  184. package/src/alchemy.ts +111 -104
  185. package/src/apply.ts +13 -5
  186. package/src/aws/bucket.ts +72 -75
  187. package/src/aws/function.ts +296 -297
  188. package/src/aws/oidc/github-oidc-provider.ts +1 -1
  189. package/src/aws/oidc/oidc-provider.ts +15 -15
  190. package/src/aws/policy-attachment.ts +10 -11
  191. package/src/aws/policy.ts +91 -94
  192. package/src/aws/queue.ts +111 -111
  193. package/src/aws/role.ts +24 -24
  194. package/src/aws/ses.ts +17 -17
  195. package/src/aws/table.ts +114 -115
  196. package/src/cloudflare/account-api-token.ts +11 -11
  197. package/src/cloudflare/account-id.ts +1 -1
  198. package/src/cloudflare/ai-gateway.ts +4 -4
  199. package/src/cloudflare/ai.ts +1 -1
  200. package/src/cloudflare/api-error.ts +1 -1
  201. package/src/cloudflare/api.ts +7 -11
  202. package/src/cloudflare/assets.ts +4 -4
  203. package/src/cloudflare/auth.ts +13 -13
  204. package/src/cloudflare/bucket.ts +62 -63
  205. package/src/cloudflare/bundle/hybrid-nodejs-compat.ts +13 -14
  206. package/src/cloudflare/custom-domain.ts +27 -28
  207. package/src/cloudflare/d1-database.ts +101 -102
  208. package/src/cloudflare/d1-migrations.ts +10 -10
  209. package/src/cloudflare/dns-records.ts +23 -24
  210. package/src/cloudflare/durable-object-namespace.ts +1 -1
  211. package/src/cloudflare/event-source.ts +1 -1
  212. package/src/cloudflare/hyperdrive.ts +3 -3
  213. package/src/cloudflare/kv-namespace.ts +36 -37
  214. package/src/cloudflare/nuxt.ts +1 -1
  215. package/src/cloudflare/permission-groups.ts +7 -7
  216. package/src/cloudflare/pipeline.ts +55 -56
  217. package/src/cloudflare/queue-consumer.ts +53 -54
  218. package/src/cloudflare/queue.ts +56 -57
  219. package/src/cloudflare/r2-rest-state-store.ts +11 -11
  220. package/src/cloudflare/redwood.ts +1 -1
  221. package/src/cloudflare/tanstack-start.ts +1 -1
  222. package/src/cloudflare/types.ts +1 -2
  223. package/src/cloudflare/vectorize-index.ts +60 -61
  224. package/src/cloudflare/vectorize-metadata-index.ts +25 -25
  225. package/src/cloudflare/vite.ts +1 -1
  226. package/src/cloudflare/website.ts +3 -3
  227. package/src/cloudflare/worker.ts +61 -61
  228. package/src/cloudflare/workflow.ts +4 -4
  229. package/src/cloudflare/wrangler.json.ts +4 -4
  230. package/src/cloudflare/zone.ts +69 -70
  231. package/src/destroy.ts +4 -4
  232. package/src/dns/godaddy.ts +1 -1
  233. package/src/dns/import-dns.ts +5 -5
  234. package/src/encrypt.ts +6 -6
  235. package/src/env.ts +10 -10
  236. package/src/esbuild/bundle.ts +14 -14
  237. package/src/fs/copy-file.ts +35 -36
  238. package/src/fs/file-system-state-store.ts +4 -4
  239. package/src/fs/file.ts +9 -8
  240. package/src/fs/folder.ts +6 -7
  241. package/src/github/client.ts +15 -14
  242. package/src/github/repository-environment.ts +206 -210
  243. package/src/github/secret.ts +111 -116
  244. package/src/internal/docs/providers.ts +16 -17
  245. package/src/neon/api-error.ts +1 -1
  246. package/src/neon/api.ts +6 -6
  247. package/src/neon/project.ts +18 -17
  248. package/src/os/exec.ts +107 -66
  249. package/src/resource.ts +3 -3
  250. package/src/scope.ts +14 -4
  251. package/src/secret.ts +2 -3
  252. package/src/serde.ts +30 -22
  253. package/src/stripe/price.ts +74 -77
  254. package/src/stripe/product.ts +55 -56
  255. package/src/stripe/webhook.ts +56 -57
  256. package/src/test/bun.ts +7 -6
  257. package/src/test/prune.ts +4 -4
  258. package/src/util/dedent.ts +4 -4
  259. package/src/web/astro.ts +10 -10
  260. package/src/web/shadcn-component.ts +4 -4
  261. package/src/web/shadcn.ts +10 -10
  262. package/src/web/tailwind.ts +2 -3
  263. package/src/web/vite.ts +11 -11
  264. package/src/web/vitepress/config.ts +2 -2
  265. package/src/web/vitepress/custom-theme.ts +7 -7
  266. package/src/web/vitepress/dependencies.ts +4 -4
  267. package/src/web/vitepress/home-page.ts +8 -9
  268. package/src/web/vitepress/process-front-matter-files.ts +5 -5
  269. package/src/web/vitepress/vitepress.ts +7 -7
@@ -305,7 +305,7 @@ export const Zone = Resource(
305
305
  async function (
306
306
  this: Context<Zone>,
307
307
  id: string,
308
- props: ZoneProps
308
+ props: ZoneProps,
309
309
  ): Promise<Zone> {
310
310
  // Create Cloudflare API client with automatic account discovery
311
311
  const api = await createCloudflareApi(props);
@@ -320,7 +320,7 @@ export const Zone = Resource(
320
320
  errors: [{ message: deleteResponse.statusText }],
321
321
  }));
322
322
  throw new Error(
323
- `Error deleting zone '${props.name}': ${errorData.errors?.[0]?.message || deleteResponse.statusText}`
323
+ `Error deleting zone '${props.name}': ${errorData.errors?.[0]?.message || deleteResponse.statusText}`,
324
324
  );
325
325
  }
326
326
  } else {
@@ -335,7 +335,7 @@ export const Zone = Resource(
335
335
 
336
336
  if (!response.ok) {
337
337
  throw new Error(
338
- `Error getting zone '${props.name}': ${response.statusText}`
338
+ `Error getting zone '${props.name}': ${response.statusText}`,
339
339
  );
340
340
  }
341
341
 
@@ -365,77 +365,76 @@ export const Zone = Resource(
365
365
  : null,
366
366
  settings: await getZoneSettings(api, zoneData.id),
367
367
  });
368
- } else {
369
- // Create new zone
370
-
371
- const response = await api.post("/zones", {
372
- name: props.name,
373
- type: props.type || "full",
374
- jump_start: props.jumpStart !== false,
375
- account: {
376
- id: api.accountId,
377
- },
378
- });
368
+ }
369
+ // Create new zone
370
+
371
+ const response = await api.post("/zones", {
372
+ name: props.name,
373
+ type: props.type || "full",
374
+ jump_start: props.jumpStart !== false,
375
+ account: {
376
+ id: api.accountId,
377
+ },
378
+ });
379
+
380
+ const body = await response.text();
381
+ let zoneData;
382
+ if (!response.ok) {
383
+ if (response.status === 400 && body.includes("already exists")) {
384
+ // Zone already exists, fetch it instead
385
+ console.warn(
386
+ `Zone '${props.name}' already exists during Zone create, adopting it...`,
387
+ );
388
+ const getResponse = await api.get(`/zones?name=${props.name}`);
379
389
 
380
- const body = await response.text();
381
- let zoneData;
382
- if (!response.ok) {
383
- if (response.status === 400 && body.includes("already exists")) {
384
- // Zone already exists, fetch it instead
385
- console.warn(
386
- `Zone '${props.name}' already exists during Zone create, adopting it...`
390
+ if (!getResponse.ok) {
391
+ throw new Error(
392
+ `Error fetching existing zone '${props.name}': ${getResponse.statusText}`,
387
393
  );
388
- const getResponse = await api.get(`/zones?name=${props.name}`);
389
-
390
- if (!getResponse.ok) {
391
- throw new Error(
392
- `Error fetching existing zone '${props.name}': ${getResponse.statusText}`
393
- );
394
- }
394
+ }
395
395
 
396
- const zones = (
397
- (await getResponse.json()) as { result: CloudflareZone[] }
398
- ).result;
399
- if (zones.length === 0) {
400
- throw new Error(
401
- `Zone '${props.name}' does not exist, but the name is reserved for another user.`
402
- );
403
- }
404
- zoneData = zones[0];
405
- } else {
396
+ const zones = (
397
+ (await getResponse.json()) as { result: CloudflareZone[] }
398
+ ).result;
399
+ if (zones.length === 0) {
406
400
  throw new Error(
407
- `Error creating zone '${props.name}': ${response.statusText}\n${body}`
401
+ `Zone '${props.name}' does not exist, but the name is reserved for another user.`,
408
402
  );
409
403
  }
404
+ zoneData = zones[0];
410
405
  } else {
411
- zoneData = (JSON.parse(body) as { result: CloudflareZone }).result;
412
- }
413
-
414
- // Update zone settings if provided
415
- if (props.settings) {
416
- await updateZoneSettings(api, zoneData.id, props.settings);
417
- // Add a small delay to ensure settings are propagated
418
- await new Promise((resolve) => setTimeout(resolve, 2000));
406
+ throw new Error(
407
+ `Error creating zone '${props.name}': ${response.statusText}\n${body}`,
408
+ );
419
409
  }
410
+ } else {
411
+ zoneData = (JSON.parse(body) as { result: CloudflareZone }).result;
412
+ }
420
413
 
421
- return this({
422
- id: zoneData.id,
423
- name: zoneData.name,
424
- type: zoneData.type,
425
- status: zoneData.status,
426
- paused: zoneData.paused,
427
- accountId: zoneData.account.id,
428
- nameservers: zoneData.name_servers,
429
- originalNameservers: zoneData.original_name_servers,
430
- createdAt: new Date(zoneData.created_on).getTime(),
431
- modifiedAt: new Date(zoneData.modified_on).getTime(),
432
- activatedAt: zoneData.activated_on
433
- ? new Date(zoneData.activated_on).getTime()
434
- : null,
435
- settings: await getZoneSettings(api, zoneData.id),
436
- });
414
+ // Update zone settings if provided
415
+ if (props.settings) {
416
+ await updateZoneSettings(api, zoneData.id, props.settings);
417
+ // Add a small delay to ensure settings are propagated
418
+ await new Promise((resolve) => setTimeout(resolve, 2000));
437
419
  }
438
- }
420
+
421
+ return this({
422
+ id: zoneData.id,
423
+ name: zoneData.name,
424
+ type: zoneData.type,
425
+ status: zoneData.status,
426
+ paused: zoneData.paused,
427
+ accountId: zoneData.account.id,
428
+ nameservers: zoneData.name_servers,
429
+ originalNameservers: zoneData.original_name_servers,
430
+ createdAt: new Date(zoneData.created_on).getTime(),
431
+ modifiedAt: new Date(zoneData.modified_on).getTime(),
432
+ activatedAt: zoneData.activated_on
433
+ ? new Date(zoneData.activated_on).getTime()
434
+ : null,
435
+ settings: await getZoneSettings(api, zoneData.id),
436
+ });
437
+ },
439
438
  );
440
439
 
441
440
  /**
@@ -444,7 +443,7 @@ export const Zone = Resource(
444
443
  async function updateZoneSettings(
445
444
  api: any,
446
445
  zoneId: string,
447
- settings: ZoneProps["settings"]
446
+ settings: ZoneProps["settings"],
448
447
  ): Promise<void> {
449
448
  if (!settings) return;
450
449
 
@@ -478,7 +477,7 @@ async function updateZoneSettings(
478
477
  `/zones/${zoneId}/settings/${settingId}`,
479
478
  {
480
479
  value,
481
- } as UpdateZoneSettingParams
480
+ } as UpdateZoneSettingParams,
482
481
  );
483
482
 
484
483
  if (!response.ok) {
@@ -488,10 +487,10 @@ async function updateZoneSettings(
488
487
  return;
489
488
  }
490
489
  throw new Error(
491
- `Failed to update zone setting ${key}: ${response.statusText}`
490
+ `Failed to update zone setting ${key}: ${response.statusText}`,
492
491
  );
493
492
  }
494
- })
493
+ }),
495
494
  );
496
495
  }
497
496
 
@@ -500,13 +499,13 @@ async function updateZoneSettings(
500
499
  */
501
500
  async function getZoneSettings(
502
501
  api: any,
503
- zoneId: string
502
+ zoneId: string,
504
503
  ): Promise<Zone["settings"]> {
505
504
  const settingsResponse = await api.get(`/zones/${zoneId}/settings`);
506
505
 
507
506
  if (!settingsResponse.ok) {
508
507
  throw new Error(
509
- `Failed to fetch zone settings: ${settingsResponse.status} ${settingsResponse.statusText}`
508
+ `Failed to fetch zone settings: ${settingsResponse.status} ${settingsResponse.statusText}`,
510
509
  );
511
510
  }
512
511
 
package/src/destroy.ts CHANGED
@@ -39,7 +39,7 @@ export async function destroy<Type extends string>(
39
39
  ...orphan.output,
40
40
  Scope: scope,
41
41
  })),
42
- options
42
+ options,
43
43
  );
44
44
  // finally, destroy the scope container
45
45
  await scope.deinit();
@@ -64,7 +64,7 @@ export async function destroy<Type extends string>(
64
64
  const Provider: Provider<Type> | undefined = PROVIDERS.get(instance.Kind);
65
65
  if (!Provider) {
66
66
  throw new Error(
67
- `Cannot destroy resource "${instance.FQN}" type ${instance.Kind} - no provider found. You may need to import the provider in your alchemy.config.ts.`
67
+ `Cannot destroy resource "${instance.FQN}" type ${instance.Kind} - no provider found. You may need to import the provider in your alchemy.config.ts.`,
68
68
  );
69
69
  }
70
70
 
@@ -112,7 +112,7 @@ export async function destroy<Type extends string>(
112
112
  async (scope) => {
113
113
  nestedScope = scope;
114
114
  return await Provider.handler.bind(ctx)(instance.ID, state.props);
115
- }
115
+ },
116
116
  );
117
117
  } catch (err) {
118
118
  if (err instanceof DestroyedSignal) {
@@ -146,7 +146,7 @@ export namespace destroy {
146
146
  }
147
147
  } else {
148
148
  await Promise.all(
149
- resources.map((resource) => destroy(resource, options))
149
+ resources.map((resource) => destroy(resource, options)),
150
150
  );
151
151
  }
152
152
  }
@@ -24,6 +24,6 @@ export async function updateNameservers(options: UpdateNameserversOptions) {
24
24
  console.log(`✅ Nameservers updated for ${options.domain}`);
25
25
  } else {
26
26
  const error = await response.json();
27
- console.error(`❌ Failed to update nameservers:`, error);
27
+ console.error("❌ Failed to update nameservers:", error);
28
28
  }
29
29
  }
@@ -134,7 +134,7 @@ export const ImportDnsRecords = Resource(
134
134
  async function (
135
135
  this: Context<ImportDnsRecords>,
136
136
  id: string,
137
- props: ImportDnsRecordsProps
137
+ props: ImportDnsRecordsProps,
138
138
  ): Promise<ImportDnsRecords> {
139
139
  // For delete phase, just return destroyed state since this is a read-only resource
140
140
  if (this.phase === "delete") {
@@ -152,7 +152,7 @@ export const ImportDnsRecords = Resource(
152
152
  headers: {
153
153
  accept: "application/dns-json",
154
154
  },
155
- }
155
+ },
156
156
  );
157
157
 
158
158
  if (!res.ok) {
@@ -182,7 +182,7 @@ export const ImportDnsRecords = Resource(
182
182
  // Join the rest as hostname in case there are spaces
183
183
  const hostname = parts.slice(1).join(" ");
184
184
 
185
- if (!isNaN(priority)) {
185
+ if (!Number.isNaN(priority)) {
186
186
  result.priority = priority;
187
187
  result.content = hostname;
188
188
  }
@@ -197,7 +197,7 @@ export const ImportDnsRecords = Resource(
197
197
  } catch (error) {
198
198
  console.warn(
199
199
  `Failed to fetch ${type} records for ${props.domain}:`,
200
- error
200
+ error,
201
201
  );
202
202
  }
203
203
  }
@@ -209,5 +209,5 @@ export const ImportDnsRecords = Resource(
209
209
  records: allRecords,
210
210
  importedAt: Date.now(),
211
211
  });
212
- }
212
+ },
213
213
  );
package/src/encrypt.ts CHANGED
@@ -14,7 +14,7 @@ export async function encrypt(value: string, key: string): Promise<string> {
14
14
  // Derive a key from the passphrase
15
15
  const cryptoKey = sodium.crypto_generichash(
16
16
  sodium.crypto_secretbox_KEYBYTES,
17
- sodium.from_string(key)
17
+ sodium.from_string(key),
18
18
  );
19
19
 
20
20
  // Generate a random nonce
@@ -24,7 +24,7 @@ export async function encrypt(value: string, key: string): Promise<string> {
24
24
  const encryptedBin = sodium.crypto_secretbox_easy(
25
25
  sodium.from_string(value),
26
26
  nonce,
27
- cryptoKey
27
+ cryptoKey,
28
28
  );
29
29
 
30
30
  // Combine nonce and ciphertext, then encode to base64
@@ -44,7 +44,7 @@ export async function encrypt(value: string, key: string): Promise<string> {
44
44
  */
45
45
  export async function decryptWithKey(
46
46
  encryptedValue: string,
47
- key: string
47
+ key: string,
48
48
  ): Promise<string> {
49
49
  // Initialize libsodium
50
50
  await sodium.ready;
@@ -52,13 +52,13 @@ export async function decryptWithKey(
52
52
  // Derive a key from the passphrase
53
53
  const cryptoKey = sodium.crypto_generichash(
54
54
  sodium.crypto_secretbox_KEYBYTES,
55
- sodium.from_string(key)
55
+ sodium.from_string(key),
56
56
  );
57
57
 
58
58
  // Decode the base64 combined value
59
59
  const combined = sodium.from_base64(
60
60
  encryptedValue,
61
- sodium.base64_variants.ORIGINAL
61
+ sodium.base64_variants.ORIGINAL,
62
62
  );
63
63
 
64
64
  // Extract nonce and ciphertext
@@ -69,7 +69,7 @@ export async function decryptWithKey(
69
69
  const decryptedBin = sodium.crypto_secretbox_open_easy(
70
70
  ciphertext,
71
71
  nonce,
72
- cryptoKey
72
+ cryptoKey,
73
73
  );
74
74
 
75
75
  return sodium.to_string(decryptedBin);
package/src/env.ts CHANGED
@@ -11,21 +11,21 @@ export const env = new Proxy(_env, {
11
11
  async function _env<T = string>(
12
12
  name: string,
13
13
  value?: T | undefined,
14
- error?: string
14
+ error?: string,
15
15
  ): Promise<T> {
16
16
  if (value !== undefined) {
17
17
  return value;
18
- } else if (typeof process !== undefined) {
18
+ }
19
+ if (typeof process !== "undefined") {
19
20
  // we are in a node environment
20
21
  return process.env[name]! as T;
21
- } else {
22
- // we are in a browser environment
23
- try {
24
- const { env } = await import("cloudflare:workers");
25
- if (name in env) {
26
- return env[name as keyof typeof env] as T;
27
- }
28
- } catch (error) {}
29
22
  }
23
+ // we are in a browser environment
24
+ try {
25
+ const { env } = await import("cloudflare:workers");
26
+ if (name in env) {
27
+ return env[name as keyof typeof env] as T;
28
+ }
29
+ } catch (error) {}
30
30
  throw new Error(error ?? `Environment variable ${name} is not set`);
31
31
  }
@@ -123,7 +123,7 @@ export const Bundle = Resource(
123
123
  async function <Props extends BundleProps>(
124
124
  this: Context<Bundle<any>>,
125
125
  id: string,
126
- props: Props
126
+ props: Props,
127
127
  ): Promise<Bundle<Props>> {
128
128
  if (this.phase === "delete") {
129
129
  console.log("delete", this.output.path);
@@ -151,38 +151,38 @@ export const Bundle = Resource(
151
151
  // resolve to absolute and then relative to ensure consistent result (e.g. ./src/handler.ts instead of src/handler.ts)
152
152
  const relativeOutput = path.relative(
153
153
  process.cwd(),
154
- path.resolve(output.entryPoint)
154
+ path.resolve(output.entryPoint),
155
155
  );
156
156
  return (
157
157
  relativeOutput ===
158
158
  path.relative(
159
159
  process.cwd(),
160
- path.resolve(process.cwd(), props.entryPoint)
160
+ path.resolve(process.cwd(), props.entryPoint),
161
161
  )
162
162
  );
163
- }
163
+ },
164
164
  )?.[0];
165
165
 
166
166
  const outputFile = result.outputFiles?.[0];
167
167
  if (outputFile === undefined && bundlePath === undefined) {
168
168
  throw new Error("Failed to create bundle");
169
- } else if (outputFile) {
169
+ }
170
+ if (outputFile) {
170
171
  return this({
171
172
  ...props,
172
173
  path: bundlePath,
173
174
  hash: outputFile.hash,
174
175
  content: outputFile.text,
175
176
  });
176
- } else {
177
- const content = await fs.readFile(bundlePath!, "utf-8");
178
- return this({
179
- ...props,
180
- path: bundlePath,
181
- hash: crypto.createHash("sha256").update(content).digest("hex"),
182
- content,
183
- });
184
177
  }
185
- }
178
+ const content = await fs.readFile(bundlePath!, "utf-8");
179
+ return this({
180
+ ...props,
181
+ path: bundlePath,
182
+ hash: crypto.createHash("sha256").update(content).digest("hex"),
183
+ content,
184
+ });
185
+ },
186
186
  );
187
187
 
188
188
  export async function bundle(props: BundleProps) {
@@ -64,7 +64,7 @@ export const CopyFile = Resource(
64
64
  async function (
65
65
  this: Context<CopyFile>,
66
66
  id: string,
67
- props: CopyFileProps
67
+ props: CopyFileProps,
68
68
  ): Promise<CopyFile> {
69
69
  const { src, dest, overwrite = true } = props;
70
70
 
@@ -72,44 +72,43 @@ export const CopyFile = Resource(
72
72
  // When deleting, remove the destination file
73
73
  await ignore("ENOENT", async () => fs.promises.unlink(dest));
74
74
  return this.destroy();
75
- } else {
76
- try {
77
- // Check if source file exists
78
- await fs.promises.access(src, fs.constants.F_OK);
79
-
80
- // If this is an update and the destination has changed, delete the old file
81
- if (
82
- this.phase === "update" &&
83
- this.output?.dest &&
84
- this.output.dest !== dest
85
- ) {
86
- await ignore("ENOENT", async () =>
87
- fs.promises.unlink(this.output.dest)
88
- );
89
- }
75
+ }
76
+ try {
77
+ // Check if source file exists
78
+ await fs.promises.access(src, fs.constants.F_OK);
90
79
 
91
- // Check if destination file exists
92
- const destinationExists = await fs.promises
93
- .access(dest, fs.constants.F_OK)
94
- .then(() => true)
95
- .catch(() => false);
80
+ // If this is an update and the destination has changed, delete the old file
81
+ if (
82
+ this.phase === "update" &&
83
+ this.output?.dest &&
84
+ this.output.dest !== dest
85
+ ) {
86
+ await ignore("ENOENT", async () =>
87
+ fs.promises.unlink(this.output.dest),
88
+ );
89
+ }
96
90
 
97
- // Copy file if destination doesn't exist or overwrite is true
98
- if (!destinationExists || overwrite) {
99
- await fs.promises.copyFile(src, dest);
100
- }
91
+ // Check if destination file exists
92
+ const destinationExists = await fs.promises
93
+ .access(dest, fs.constants.F_OK)
94
+ .then(() => true)
95
+ .catch(() => false);
101
96
 
102
- return this({
103
- src,
104
- dest,
105
- overwrite,
106
- copied: true,
107
- createdAt: Date.now(),
108
- });
109
- } catch (error) {
110
- console.error(`Error copying file from ${src} to ${dest}:`, error);
111
- throw error;
97
+ // Copy file if destination doesn't exist or overwrite is true
98
+ if (!destinationExists || overwrite) {
99
+ await fs.promises.copyFile(src, dest);
112
100
  }
101
+
102
+ return this({
103
+ src,
104
+ dest,
105
+ overwrite,
106
+ copied: true,
107
+ createdAt: Date.now(),
108
+ });
109
+ } catch (error) {
110
+ console.error(`Error copying file from ${src} to ${dest}:`, error);
111
+ throw error;
113
112
  }
114
- }
113
+ },
115
114
  );
@@ -52,7 +52,7 @@ export class FileSystemStateStore implements StateStore {
52
52
  const content = await fs.promises.readFile(this.getPath(key), "utf8");
53
53
  const state = (await deserialize(
54
54
  this.scope,
55
- JSON.parse(content)
55
+ JSON.parse(content),
56
56
  )) as State;
57
57
  if (state.output === undefined) {
58
58
  state.output = {} as any;
@@ -71,7 +71,7 @@ export class FileSystemStateStore implements StateStore {
71
71
  await this.init();
72
72
  await fs.promises.writeFile(
73
73
  this.getPath(key),
74
- JSON.stringify(await serialize(this.scope, value), null, 2)
74
+ JSON.stringify(await serialize(this.scope, value), null, 2),
75
75
  );
76
76
  }
77
77
 
@@ -100,9 +100,9 @@ export class FileSystemStateStore implements StateStore {
100
100
  return [] as const;
101
101
  }
102
102
  return [[id, s]] as const;
103
- })
103
+ }),
104
104
  )
105
- ).flat()
105
+ ).flat(),
106
106
  );
107
107
  }
108
108
 
package/src/fs/file.ts CHANGED
@@ -8,7 +8,7 @@ import { alchemy } from "../alchemy.js";
8
8
  import type { FileCollection } from "./file-collection.js";
9
9
  import type { FileRef } from "./file-ref.js";
10
10
 
11
- declare module "../alchemy" {
11
+ declare module "../alchemy.js" {
12
12
  interface Alchemy {
13
13
  /**
14
14
  * Creates a reference to a file in the filesystem.
@@ -72,7 +72,7 @@ declare module "../alchemy" {
72
72
  * @default false
73
73
  */
74
74
  recursive?: boolean;
75
- }
75
+ },
76
76
  ): Promise<FileCollection>;
77
77
  }
78
78
  }
@@ -94,8 +94,8 @@ alchemy.files = async (
94
94
  paths.map(async (path) => [
95
95
  path,
96
96
  await fs.promises.readFile(path, "utf-8"),
97
- ])
98
- )
97
+ ]),
98
+ ),
99
99
  ),
100
100
  };
101
101
  };
@@ -162,21 +162,22 @@ export const File = Resource(
162
162
  props: {
163
163
  path: string;
164
164
  content: string;
165
- }
165
+ },
166
166
  ): Promise<File> {
167
167
  const filePath = props?.path ?? id;
168
168
 
169
169
  if (this.phase === "delete") {
170
170
  await ignore("ENOENT", async () => fs.promises.unlink(filePath));
171
171
  return this.destroy();
172
- } else if (
172
+ }
173
+ if (
173
174
  this.phase === "update" &&
174
175
  this.output &&
175
176
  this.output.path !== filePath
176
177
  ) {
177
178
  // If path has changed, delete the old file
178
179
  console.log(
179
- `File: Path changed from ${this.output.path} to ${filePath}, removing old file`
180
+ `File: Path changed from ${this.output.path} to ${filePath}, removing old file`,
180
181
  );
181
182
  await ignore("ENOENT", async () => fs.promises.unlink(this.output.path));
182
183
  }
@@ -191,5 +192,5 @@ export const File = Resource(
191
192
  path: filePath,
192
193
  content: props.content,
193
194
  });
194
- }
195
+ },
195
196
  );
package/src/fs/folder.ts CHANGED
@@ -61,24 +61,23 @@ export const Folder = Resource(
61
61
  async function (
62
62
  this: Context<Folder>,
63
63
  id: string,
64
- props?: FolderProps
64
+ props?: FolderProps,
65
65
  ): Promise<Folder> {
66
66
  const dirPath = props?.path ?? id;
67
67
  if (this.phase === "delete") {
68
68
  if (props?.delete !== false) {
69
69
  // we just do a best effort attempt
70
70
  await ignore(["ENOENT", "ENOTEMPTY"], async () =>
71
- fs.promises.rmdir(dirPath, { recursive: props?.clean ?? false })
71
+ fs.promises.rmdir(dirPath, { recursive: props?.clean ?? false }),
72
72
  );
73
73
  }
74
74
  return this.destroy();
75
- } else {
76
- await ignore("EEXIST", async () =>
77
- fs.promises.mkdir(dirPath, { recursive: props?.recursive ?? true })
78
- );
79
75
  }
76
+ await ignore("EEXIST", async () =>
77
+ fs.promises.mkdir(dirPath, { recursive: props?.recursive ?? true }),
78
+ );
80
79
  return this({
81
80
  path: dirPath,
82
81
  });
83
- }
82
+ },
84
83
  );