alchemy 0.64.0 → 0.65.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 (117) hide show
  1. package/bin/alchemy.js +7570 -5773
  2. package/bin/commands/init.ts +130 -9
  3. package/bin/constants.ts +4 -0
  4. package/bin/services/cdp-manager/cdp-proxy.ts +69 -0
  5. package/bin/services/cdp-manager/server.ts +173 -0
  6. package/bin/services/execute-alchemy.ts +83 -4
  7. package/bin/types.ts +1 -0
  8. package/lib/cloudflare/bundle/plugin-node-compat.js +2 -2
  9. package/lib/cloudflare/bundle/plugin-node-compat.js.map +1 -1
  10. package/lib/cloudflare/bundle/plugin-wasm.d.ts.map +1 -1
  11. package/lib/cloudflare/bundle/plugin-wasm.js +20 -11
  12. package/lib/cloudflare/bundle/plugin-wasm.js.map +1 -1
  13. package/lib/cloudflare/compatibility-date.gen.d.ts +1 -1
  14. package/lib/cloudflare/compatibility-date.gen.js +1 -1
  15. package/lib/cloudflare/hyperdrive.d.ts +7 -2
  16. package/lib/cloudflare/hyperdrive.d.ts.map +1 -1
  17. package/lib/cloudflare/hyperdrive.js +39 -57
  18. package/lib/cloudflare/hyperdrive.js.map +1 -1
  19. package/lib/cloudflare/index.d.ts +1 -0
  20. package/lib/cloudflare/index.d.ts.map +1 -1
  21. package/lib/cloudflare/index.js +1 -0
  22. package/lib/cloudflare/index.js.map +1 -1
  23. package/lib/cloudflare/next.d.ts +13 -0
  24. package/lib/cloudflare/next.d.ts.map +1 -0
  25. package/lib/cloudflare/next.js +91 -0
  26. package/lib/cloudflare/next.js.map +1 -0
  27. package/lib/cloudflare/worker-assets.d.ts +3 -3
  28. package/lib/cloudflare/worker-assets.d.ts.map +1 -1
  29. package/lib/cloudflare/worker-assets.js +22 -47
  30. package/lib/cloudflare/worker-assets.js.map +1 -1
  31. package/lib/cloudflare/wrangler.json.d.ts +2 -2
  32. package/lib/cloudflare/wrangler.json.d.ts.map +1 -1
  33. package/lib/cloudflare/wrangler.json.js +4 -1
  34. package/lib/cloudflare/wrangler.json.js.map +1 -1
  35. package/lib/planetscale/branch.d.ts.map +1 -1
  36. package/lib/planetscale/branch.js +36 -25
  37. package/lib/planetscale/branch.js.map +1 -1
  38. package/lib/planetscale/database.d.ts +23 -6
  39. package/lib/planetscale/database.d.ts.map +1 -1
  40. package/lib/planetscale/database.js +11 -5
  41. package/lib/planetscale/database.js.map +1 -1
  42. package/lib/planetscale/index.d.ts +1 -0
  43. package/lib/planetscale/index.d.ts.map +1 -1
  44. package/lib/planetscale/index.js +1 -0
  45. package/lib/planetscale/index.js.map +1 -1
  46. package/lib/planetscale/password.d.ts +3 -1
  47. package/lib/planetscale/password.d.ts.map +1 -1
  48. package/lib/planetscale/password.js +3 -1
  49. package/lib/planetscale/password.js.map +1 -1
  50. package/lib/planetscale/role.d.ts +126 -0
  51. package/lib/planetscale/role.d.ts.map +1 -0
  52. package/lib/planetscale/role.js +144 -0
  53. package/lib/planetscale/role.js.map +1 -0
  54. package/lib/planetscale/utils.d.ts +17 -3
  55. package/lib/planetscale/utils.d.ts.map +1 -1
  56. package/lib/planetscale/utils.js +110 -31
  57. package/lib/planetscale/utils.js.map +1 -1
  58. package/lib/secret.d.ts +0 -3
  59. package/lib/secret.d.ts.map +1 -1
  60. package/lib/secret.js +0 -2
  61. package/lib/secret.js.map +1 -1
  62. package/lib/state/cloudflare-state-store.js +3 -3
  63. package/lib/state/cloudflare-state-store.js.map +1 -1
  64. package/lib/test/bun.d.ts +2 -2
  65. package/lib/test/bun.d.ts.map +1 -1
  66. package/lib/test/vitest.d.ts +2 -2
  67. package/lib/test/vitest.d.ts.map +1 -1
  68. package/lib/test/vitest.js +4 -4
  69. package/lib/test/vitest.js.map +1 -1
  70. package/lib/util/content-type.js +2 -2
  71. package/lib/util/content-type.js.map +1 -1
  72. package/lib/util/dedent.d.ts.map +1 -1
  73. package/lib/util/dedent.js +30 -18
  74. package/lib/util/dedent.js.map +1 -1
  75. package/lib/util/memoize.d.ts +1 -1
  76. package/lib/util/memoize.d.ts.map +1 -1
  77. package/lib/util/memoize.js +13 -3
  78. package/lib/util/memoize.js.map +1 -1
  79. package/package.json +5 -1
  80. package/src/cloudflare/bundle/plugin-node-compat.ts +2 -2
  81. package/src/cloudflare/bundle/plugin-wasm.ts +34 -14
  82. package/src/cloudflare/compatibility-date.gen.ts +1 -1
  83. package/src/cloudflare/hyperdrive.ts +136 -95
  84. package/src/cloudflare/index.ts +1 -0
  85. package/src/cloudflare/next.ts +123 -0
  86. package/src/cloudflare/worker-assets.ts +43 -105
  87. package/src/cloudflare/wrangler.json.ts +6 -3
  88. package/src/planetscale/branch.ts +52 -27
  89. package/src/planetscale/database.ts +75 -46
  90. package/src/planetscale/index.ts +1 -0
  91. package/src/planetscale/password.ts +3 -1
  92. package/src/planetscale/role.ts +278 -0
  93. package/src/planetscale/utils.ts +172 -30
  94. package/src/secret.ts +0 -4
  95. package/src/state/cloudflare-state-store.ts +4 -4
  96. package/src/test/bun.ts +2 -2
  97. package/src/test/vitest.ts +6 -6
  98. package/src/util/content-type.ts +2 -2
  99. package/src/util/dedent.ts +33 -21
  100. package/src/util/memoize.ts +15 -3
  101. package/templates/nextjs/README.md +85 -0
  102. package/templates/nextjs/_env +1 -0
  103. package/templates/nextjs/_env.example +1 -0
  104. package/templates/nextjs/_gitignore +46 -0
  105. package/templates/nextjs/alchemy.run.ts +16 -0
  106. package/templates/nextjs/eslint.config.mjs +16 -0
  107. package/templates/nextjs/next-env.d.ts +5 -0
  108. package/templates/nextjs/next.config.ts +10 -0
  109. package/templates/nextjs/open-next.config.ts +5 -0
  110. package/templates/nextjs/package.json +31 -0
  111. package/templates/nextjs/src/app/api/hello/route.ts +19 -0
  112. package/templates/nextjs/src/app/favicon.ico +0 -0
  113. package/templates/nextjs/src/app/globals.css +72 -0
  114. package/templates/nextjs/src/app/layout.tsx +19 -0
  115. package/templates/nextjs/src/app/page.tsx +55 -0
  116. package/templates/nextjs/tsconfig.json +33 -0
  117. package/templates/nextjs/types/env.d.ts +14 -0
@@ -1 +1 @@
1
- {"version":3,"file":"bun.d.ts","sourceRoot":"","sources":["../../src/test/bun.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD;;GAEG;AACH,OAAO,QAAQ,eAAe,CAAC;IAC7B,UAAU,OAAO;QACf,IAAI,EAAE,OAAO,IAAI,CAAC;KACnB;CACF;AAOD;;GAEG;AACH,KAAK,IAAI,GAAG;IACV;;;;;OAKG;IACH,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE3E;;;;;;OAMG;IACH,CACE,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,WAAW,EACpB,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,GAAG,CAAC,EAClC,OAAO,CAAC,EAAE,MAAM,GACf,IAAI,CAAC;IAER;;;OAGG;IACH,MAAM,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAAC;IAEjC,SAAS,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAErD,QAAQ,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAEpD;;OAEG;IACH,KAAK,EAAE,KAAK,CAAC;CACd,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,cAAc,CAAC,EAAE,WAAW,GAAG,IAAI,CA+EzE"}
1
+ {"version":3,"file":"bun.d.ts","sourceRoot":"","sources":["../../src/test/bun.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD;;GAEG;AACH,OAAO,QAAQ,eAAe,CAAC;IAC7B,UAAU,OAAO;QACf,IAAI,EAAE,OAAO,IAAI,CAAC;KACnB;CACF;AAOD;;GAEG;AACH,KAAK,IAAI,GAAG;IACV;;;;;OAKG;IACH,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE3E;;;;;;OAMG;IACH,CACE,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,WAAW,EACpB,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,GAAG,CAAC,EAClC,OAAO,CAAC,EAAE,MAAM,GACf,IAAI,CAAC;IAER;;;OAGG;IACH,MAAM,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAAC;IAEjC,SAAS,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEvE,QAAQ,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEtE;;OAEG;IACH,KAAK,EAAE,KAAK,CAAC;CACd,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,cAAc,CAAC,EAAE,WAAW,GAAG,IAAI,CA+EzE"}
@@ -32,8 +32,8 @@ type test = {
32
32
  * @param condition If true, test will be skipped
33
33
  */
34
34
  skipIf(condition: boolean): test;
35
- beforeAll(fn: (scope: Scope) => Promise<void>): void;
36
- afterAll(fn: (scope: Scope) => Promise<void>): void;
35
+ beforeAll(fn: (scope: Scope) => Promise<void>, timeout?: number): void;
36
+ afterAll(fn: (scope: Scope) => Promise<void>, timeout?: number): void;
37
37
  /**
38
38
  * Current test scope
39
39
  */
@@ -1 +1 @@
1
- {"version":3,"file":"vitest.d.ts","sourceRoot":"","sources":["../../src/test/vitest.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAQpC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD;;GAEG;AACH,OAAO,QAAQ,eAAe,CAAC;IAC7B,UAAU,OAAO;QACf,IAAI,EAAE,OAAO,IAAI,CAAC;KACnB;CACF;AAOD;;GAEG;AACH,KAAK,IAAI,GAAG;IACV;;;;;OAKG;IACH,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE3E;;;;;;OAMG;IACH,CACE,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,WAAW,EACpB,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,GAAG,CAAC,EAClC,OAAO,CAAC,EAAE,MAAM,GACf,IAAI,CAAC;IAER;;;OAGG;IACH,MAAM,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAAC;IAEjC,SAAS,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAErD,QAAQ,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAEpD;;OAEG;IACH,KAAK,EAAE,KAAK,CAAC;CACd,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,IAAI,CAClB,IAAI,EAAE,UAAU,EAChB,cAAc,GAAE,WAEf,GACA,IAAI,CAuGN"}
1
+ {"version":3,"file":"vitest.d.ts","sourceRoot":"","sources":["../../src/test/vitest.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAQpC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD;;GAEG;AACH,OAAO,QAAQ,eAAe,CAAC;IAC7B,UAAU,OAAO;QACf,IAAI,EAAE,OAAO,IAAI,CAAC;KACnB;CACF;AAOD;;GAEG;AACH,KAAK,IAAI,GAAG;IACV;;;;;OAKG;IACH,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE3E;;;;;;OAMG;IACH,CACE,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,WAAW,EACpB,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,GAAG,CAAC,EAClC,OAAO,CAAC,EAAE,MAAM,GACf,IAAI,CAAC;IAER;;;OAGG;IACH,MAAM,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAAC;IAEjC,SAAS,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEvE,QAAQ,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEtE;;OAEG;IACH,KAAK,EAAE,KAAK,CAAC;CACd,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,IAAI,CAClB,IAAI,EAAE,UAAU,EAChB,cAAc,GAAE,WAEf,GACA,IAAI,CAuGN"}
@@ -69,11 +69,11 @@ export function test(meta, defaultOptions = {
69
69
  quiet: defaultOptions.quiet,
70
70
  password: process.env.ALCHEMY_PASSWORD,
71
71
  });
72
- test.beforeAll = (fn) => {
73
- return beforeAll(() => scope.run(() => fn(scope)));
72
+ test.beforeAll = (fn, timeout) => {
73
+ return beforeAll(() => scope.run(() => fn(scope)), timeout);
74
74
  };
75
- test.afterAll = (fn) => {
76
- return afterAll(() => scope.run(() => fn(scope)));
75
+ test.afterAll = (fn, timeout) => {
76
+ return afterAll(() => scope.run(() => fn(scope)), timeout);
77
77
  };
78
78
  return test;
79
79
  function test(...args) {
@@ -1 +1 @@
1
- {"version":3,"file":"vitest.js","sourceRoot":"","sources":["../../src/test/vitest.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"vitest.js","sourceRoot":"","sources":["../../src/test/vitest.ts"],"names":[],"mappings":"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"}
@@ -10,10 +10,10 @@ const mimeTypes = {
10
10
  ".jpeg": "image/jpeg",
11
11
  ".jpg": "image/jpeg",
12
12
  ".js.map": "application/source-map",
13
- ".js": "application/javascript",
13
+ ".js": "text/javascript",
14
14
  ".json": "application/json",
15
15
  ".md": "text/markdown",
16
- ".mjs": "application/javascript+module",
16
+ ".mjs": "text/javascript",
17
17
  ".mp3": "audio/mpeg",
18
18
  ".mp4": "video/mp4",
19
19
  ".otf": "font/otf",
@@ -1 +1 @@
1
- {"version":3,"file":"content-type.js","sourceRoot":"","sources":["../../src/util/content-type.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,oBAAoB;AACpB,MAAM,SAAS,GAA2B;IACxC,MAAM,EAAE,UAAU;IAClB,MAAM,EAAE,+BAA+B;IACvC,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,WAAW;IACnB,OAAO,EAAE,WAAW;IACpB,MAAM,EAAE,cAAc;IACtB,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,YAAY;IACpB,SAAS,EAAE,wBAAwB;IACnC,KAAK,EAAE,wBAAwB;IAC/B,OAAO,EAAE,kBAAkB;IAC3B,KAAK,EAAE,eAAe;IACtB,MAAM,EAAE,+BAA+B;IACvC,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,UAAU;IAClB,MAAM,EAAE,iBAAiB;IACzB,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,eAAe;IACvB,MAAM,EAAE,UAAU;IAClB,MAAM,EAAE,YAAY;IACpB,OAAO,EAAE,kBAAkB;IAC3B,MAAM,EAAE,WAAW;IACnB,OAAO,EAAE,YAAY;IACrB,OAAO,EAAE,YAAY;IACrB,OAAO,EAAE,WAAW;IACpB,QAAQ,EAAE,YAAY;IACtB,MAAM,EAAE,iBAAiB;IACzB,MAAM,EAAE,iBAAiB;CAC1B,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,IAAI,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QACjC,OAAO,SAAS,CAAC,SAAS,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;AACzD,CAAC"}
1
+ {"version":3,"file":"content-type.js","sourceRoot":"","sources":["../../src/util/content-type.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,oBAAoB;AACpB,MAAM,SAAS,GAA2B;IACxC,MAAM,EAAE,UAAU;IAClB,MAAM,EAAE,+BAA+B;IACvC,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,WAAW;IACnB,OAAO,EAAE,WAAW;IACpB,MAAM,EAAE,cAAc;IACtB,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,YAAY;IACpB,SAAS,EAAE,wBAAwB;IACnC,KAAK,EAAE,iBAAiB;IACxB,OAAO,EAAE,kBAAkB;IAC3B,KAAK,EAAE,eAAe;IACtB,MAAM,EAAE,iBAAiB;IACzB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,UAAU;IAClB,MAAM,EAAE,iBAAiB;IACzB,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,eAAe;IACvB,MAAM,EAAE,UAAU;IAClB,MAAM,EAAE,YAAY;IACpB,OAAO,EAAE,kBAAkB;IAC3B,MAAM,EAAE,WAAW;IACnB,OAAO,EAAE,YAAY;IACrB,OAAO,EAAE,YAAY;IACrB,OAAO,EAAE,WAAW;IACpB,QAAQ,EAAE,YAAY;IACtB,MAAM,EAAE,iBAAiB;IACzB,MAAM,EAAE,iBAAiB;CAC1B,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,IAAI,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QACjC,OAAO,SAAS,CAAC,SAAS,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;AACzD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"dedent.d.ts","sourceRoot":"","sources":["../../src/util/dedent.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,UAmCzE"}
1
+ {"version":3,"file":"dedent.d.ts","sourceRoot":"","sources":["../../src/util/dedent.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,UAiDzE"}
@@ -1,4 +1,3 @@
1
- import assert from "node:assert";
2
1
  /**
3
2
  * Tagged template literal for removing indentation from a block of text.
4
3
  *
@@ -9,29 +8,42 @@ export function dedent(strings, ...values) {
9
8
  const raw = String.raw({ raw: strings }, ...values);
10
9
  // Split the string by lines
11
10
  let lines = raw.split("\n");
12
- assert(lines.length > 0);
13
- // If the last line is just whitespace, remove it
14
- if (lines[lines.length - 1].trim() === "") {
11
+ // Remove leading blank lines
12
+ while (lines.length > 0 && lines[0].trim() === "") {
13
+ lines = lines.slice(1);
14
+ }
15
+ // Remove trailing blank lines
16
+ while (lines.length > 0 && lines[lines.length - 1].trim() === "") {
15
17
  lines = lines.slice(0, lines.length - 1);
16
18
  }
17
- // Find the minimum-length indent, excluding the first line
18
- let minIndent = "";
19
- // (Could use `minIndent.length` for this, but then would need to start with
20
- // infinitely long string)
19
+ // If no content lines remain, return empty string
20
+ if (lines.length === 0) {
21
+ return "";
22
+ }
23
+ // Find the minimum-length indent from content lines (non-blank lines)
21
24
  let minIndentLength = Number.POSITIVE_INFINITY;
22
- for (const line of lines.slice(1)) {
23
- const indent = line.match(/^[ \t]*/)?.[0];
24
- if (indent != null && indent.length < minIndentLength) {
25
- minIndent = indent;
26
- minIndentLength = indent.length;
25
+ for (const line of lines) {
26
+ if (line.trim() !== "") {
27
+ const indent = line.match(/^[ \t]*/)?.[0];
28
+ if (indent != null && indent.length < minIndentLength) {
29
+ minIndentLength = indent.length;
30
+ }
27
31
  }
28
32
  }
29
- // If the first line is just whitespace, remove it
30
- if (lines.length > 0 && lines[0].trim() === "") {
31
- lines = lines.slice(1);
33
+ // If no indentation found, return lines as-is
34
+ if (minIndentLength === Number.POSITIVE_INFINITY) {
35
+ return lines.join("\n");
32
36
  }
33
- // Remove indent from all lines, and return them all joined together
34
- lines = lines.map((line) => line.startsWith(minIndent) ? line.substring(minIndent.length) : line);
37
+ // Remove indent from all lines, preserving blank lines
38
+ lines = lines.map((line) => {
39
+ if (line.trim() === "") {
40
+ return line; // Preserve blank lines
41
+ }
42
+ return line.startsWith(" ".repeat(minIndentLength)) ||
43
+ line.startsWith("\t".repeat(minIndentLength))
44
+ ? line.substring(minIndentLength)
45
+ : line;
46
+ });
35
47
  return lines.join("\n");
36
48
  }
37
49
  //# sourceMappingURL=dedent.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dedent.js","sourceRoot":"","sources":["../../src/util/dedent.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC;;;;GAIG;AACH,MAAM,UAAU,MAAM,CAAC,OAA6B,EAAE,GAAG,MAAiB;IACxE,8DAA8D;IAC9D,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,GAAG,MAAM,CAAC,CAAC;IACpD,4BAA4B;IAC5B,IAAI,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAEzB,iDAAiD;IACjD,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC1C,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED,2DAA2D;IAC3D,IAAI,SAAS,GAAG,EAAE,CAAC;IACnB,4EAA4E;IAC5E,0BAA0B;IAC1B,IAAI,eAAe,GAAG,MAAM,CAAC,iBAAiB,CAAC;IAC/C,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC1C,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,MAAM,GAAG,eAAe,EAAE,CAAC;YACtD,SAAS,GAAG,MAAM,CAAC;YACnB,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC;QAClC,CAAC;IACH,CAAC;IAED,kDAAkD;IAClD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC/C,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACzB,CAAC;IAED,oEAAoE;IACpE,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACzB,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CACrE,CAAC;IACF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
1
+ {"version":3,"file":"dedent.js","sourceRoot":"","sources":["../../src/util/dedent.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,MAAM,CAAC,OAA6B,EAAE,GAAG,MAAiB;IACxE,8DAA8D;IAC9D,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,GAAG,MAAM,CAAC,CAAC;IACpD,4BAA4B;IAC5B,IAAI,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAE5B,6BAA6B;IAC7B,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAClD,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACzB,CAAC;IAED,8BAA8B;IAC9B,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACjE,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED,kDAAkD;IAClD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,sEAAsE;IACtE,IAAI,eAAe,GAAG,MAAM,CAAC,iBAAiB,CAAC;IAC/C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACvB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC1C,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,MAAM,GAAG,eAAe,EAAE,CAAC;gBACtD,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC;YAClC,CAAC;QACH,CAAC;IACH,CAAC;IAED,8CAA8C;IAC9C,IAAI,eAAe,KAAK,MAAM,CAAC,iBAAiB,EAAE,CAAC;QACjD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED,uDAAuD;IACvD,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACzB,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC,CAAC,uBAAuB;QACtC,CAAC;QACD,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;YACjD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;YAC7C,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC;YACjC,CAAC,CAAC,IAAI,CAAC;IACX,CAAC,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -1,5 +1,5 @@
1
1
  type AsyncReturnType<T> = T extends (...args: any[]) => Promise<infer R> ? R : T;
2
2
  export declare function memoize<F extends (...args: any[]) => Promise<any>>(fn: F, keyFn?: (...args: Parameters<F>) => string): (...args: Parameters<F>) => Promise<AsyncReturnType<F>>;
3
- export declare const defaultKeyFn: (...args: any[]) => string;
3
+ export declare function defaultKeyFn(...args: any[]): string;
4
4
  export {};
5
5
  //# sourceMappingURL=memoize.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"memoize.d.ts","sourceRoot":"","sources":["../../src/util/memoize.ts"],"names":[],"mappings":"AAEA,KAAK,eAAe,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC,GACpE,CAAC,GACD,CAAC,CAAC;AAEN,wBAAgB,OAAO,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,EAChE,EAAE,EAAE,CAAC,EACL,KAAK,GAAE,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,MAAqB,IAG1C,GAAG,MAAM,UAAU,CAAC,CAAC,CAAC,KAAG,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAanE;AAED,eAAO,MAAM,YAAY,GAAI,GAAG,MAAM,GAAG,EAAE,WAE1C,CAAC"}
1
+ {"version":3,"file":"memoize.d.ts","sourceRoot":"","sources":["../../src/util/memoize.ts"],"names":[],"mappings":"AAGA,KAAK,eAAe,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC,GACpE,CAAC,GACD,CAAC,CAAC;AAEN,wBAAgB,OAAO,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,EAChE,EAAE,EAAE,CAAC,EACL,KAAK,GAAE,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,MAAqB,IAG1C,GAAG,MAAM,UAAU,CAAC,CAAC,CAAC,KAAG,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAanE;AAED,wBAAgB,YAAY,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,CAanD"}
@@ -1,4 +1,5 @@
1
1
  import { createHash } from "node:crypto";
2
+ import { isSecret } from "../secret.js";
2
3
  export function memoize(fn, keyFn = defaultKeyFn) {
3
4
  const cache = new Map();
4
5
  return async (...args) => {
@@ -15,7 +16,16 @@ export function memoize(fn, keyFn = defaultKeyFn) {
15
16
  return await promise;
16
17
  };
17
18
  }
18
- export const defaultKeyFn = (...args) => {
19
- return createHash("sha256").update(JSON.stringify(args)).digest("hex");
20
- };
19
+ export function defaultKeyFn(...args) {
20
+ return createHash("sha256")
21
+ .update(JSON.stringify(args, (_, value) => {
22
+ // Secret names may differ between instantiations,
23
+ // so we unwrap it to make the key deterministic.
24
+ if (isSecret(value)) {
25
+ return value.unencrypted;
26
+ }
27
+ return value;
28
+ }))
29
+ .digest("hex");
30
+ }
21
31
  //# sourceMappingURL=memoize.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"memoize.js","sourceRoot":"","sources":["../../src/util/memoize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAMzC,MAAM,UAAU,OAAO,CACrB,EAAK,EACL,QAA4C,YAAY;IAExD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAuC,CAAC;IAC7D,OAAO,KAAK,EAAE,GAAG,IAAmB,EAA+B,EAAE;QACnE,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;QAC3B,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,MAAM,MAAM,CAAC;QACtB,CAAC;QACD,MAAM,OAAO,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YAC1C,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAClB,MAAM,KAAK,CAAC;QACd,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACxB,OAAO,MAAM,OAAO,CAAC;IACvB,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,GAAG,IAAW,EAAE,EAAE;IAC7C,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACzE,CAAC,CAAC"}
1
+ {"version":3,"file":"memoize.js","sourceRoot":"","sources":["../../src/util/memoize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAMxC,MAAM,UAAU,OAAO,CACrB,EAAK,EACL,QAA4C,YAAY;IAExD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAuC,CAAC;IAC7D,OAAO,KAAK,EAAE,GAAG,IAAmB,EAA+B,EAAE;QACnE,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;QAC3B,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,MAAM,MAAM,CAAC;QACtB,CAAC;QACD,MAAM,OAAO,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YAC1C,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAClB,MAAM,KAAK,CAAC;QACd,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACxB,OAAO,MAAM,OAAO,CAAC;IACvB,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,GAAG,IAAW;IACzC,OAAO,UAAU,CAAC,QAAQ,CAAC;SACxB,MAAM,CACL,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE;QAChC,kDAAkD;QAClD,iDAAiD;QACjD,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACpB,OAAO,KAAK,CAAC,WAAW,CAAC;QAC3B,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC,CACH;SACA,MAAM,CAAC,KAAK,CAAC,CAAC;AACnB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alchemy",
3
- "version": "0.64.0",
3
+ "version": "0.65.1",
4
4
  "license": "Apache-2.0",
5
5
  "author": "Sam Goodwin <sam@alchemy.run>",
6
6
  "homepage": "https://alchemy.run",
@@ -185,6 +185,7 @@
185
185
  "@cloudflare/workers-types": "^4.20250805.0",
186
186
  "@libsql/client": "^0.15.12",
187
187
  "@octokit/rest": "^21.1.1",
188
+ "@opennextjs/cloudflare": "^1.6.5",
188
189
  "astro": "^5.13.2",
189
190
  "drizzle-orm": "^0.44.2",
190
191
  "rwsdk": "^0.1.36",
@@ -224,6 +225,9 @@
224
225
  "@cloudflare/workers-types": {
225
226
  "optional": true
226
227
  },
228
+ "@opennextjs/cloudflare": {
229
+ "optional": true
230
+ },
227
231
  "@octokit/rest": {
228
232
  "optional": true
229
233
  },
@@ -1,7 +1,7 @@
1
1
  import type { Plugin } from "esbuild";
2
2
  import type { NodeJSCompatMode } from "miniflare";
3
3
  import { relative } from "node:path";
4
- import chalk from "picocolors";
4
+ import pc from "picocolors";
5
5
  import { dedent } from "../../util/dedent.ts";
6
6
  import { logger } from "../../util/logger.ts";
7
7
  import { NODEJS_MODULES_RE } from "./nodejs-builtin-modules.ts";
@@ -109,6 +109,6 @@ export const esbuildPluginNodeCompatImports = (
109
109
 
110
110
  function toList(items: string[], absWorkingDir: string | undefined): string {
111
111
  return items
112
- .map((i) => ` - ${chalk.blue(relative(absWorkingDir ?? "/", i))}`)
112
+ .map((i) => ` - ${pc.blue(relative(absWorkingDir ?? "/", i))}`)
113
113
  .join("\n");
114
114
  }
@@ -12,21 +12,41 @@ export function createWasmPlugin() {
12
12
  build.onStart(() => {
13
13
  modules.clear();
14
14
  });
15
- build.onResolve({ filter: /\.wasm$/ }, async (args) => {
16
- if (!modules.has(args.path)) {
17
- const name = path.normalize(args.path);
18
- assert(build.initialOptions.outdir, "outdir is required");
19
- await fs.mkdir(build.initialOptions.outdir, { recursive: true });
20
- await fs.copyFile(
21
- path.join(args.resolveDir, name),
22
- path.join(build.initialOptions.outdir, name),
23
- );
24
- modules.set(args.path, {
25
- type: "wasm",
26
- path: name,
27
- });
15
+
16
+ // Handle imports like `import "./foo.wasm"` and `import "./foo.wasm?module"`
17
+ // TODO(john): Figure out why this suddenly became necessary
18
+ build.onResolve({ filter: /\.wasm(\?.*)?$/ }, async (args) => {
19
+ const resolved = modules.get(args.path);
20
+ if (resolved) {
21
+ return { path: resolved.path, external: true };
28
22
  }
29
- return { external: true };
23
+
24
+ // Normalize path and remove the `?module` query param so we have the actual file name to copy
25
+ const name = path.normalize(args.path).replace(/\?.*$/, "");
26
+
27
+ // Resolve path to outdir (required for monorepos if the workdir is not the same as process.cwd())
28
+ assert(
29
+ build.initialOptions.absWorkingDir && build.initialOptions.outdir,
30
+ "Missing absWorkingDir or outdir from esbuild options",
31
+ );
32
+ const outdir = path.resolve(
33
+ build.initialOptions.absWorkingDir,
34
+ build.initialOptions.outdir,
35
+ );
36
+
37
+ // Copy to outdir so it's included in the upload
38
+ await fs.mkdir(outdir, { recursive: true });
39
+ await fs.copyFile(
40
+ path.join(args.resolveDir, name),
41
+ path.join(outdir, name),
42
+ );
43
+ modules.set(args.path, {
44
+ type: "wasm",
45
+ path: name,
46
+ });
47
+
48
+ // Resolve to the normalized file name (the `?module` query param is not needed in workerd)
49
+ return { path: name, external: true };
30
50
  });
31
51
  },
32
52
  };
@@ -4,4 +4,4 @@
4
4
  /**
5
5
  * The default Cloudflare Workers compatibility date, set based on the latest workerd release at the time of build.
6
6
  */
7
- export const DEFAULT_COMPATIBILITY_DATE = "2025-08-26";
7
+ export const DEFAULT_COMPATIBILITY_DATE = "2025-09-06";
@@ -4,8 +4,16 @@ import { Resource } from "../resource.ts";
4
4
  import { Scope } from "../scope.ts";
5
5
  import { Secret } from "../secret.ts";
6
6
  import { logger } from "../util/logger.ts";
7
- import { handleApiError } from "./api-error.ts";
8
- import { createCloudflareApi, type CloudflareApiOptions } from "./api.ts";
7
+ import { CloudflareApiError, handleApiError } from "./api-error.ts";
8
+ import {
9
+ extractCloudflareResult,
10
+ type CloudflareApiErrorPayload,
11
+ } from "./api-response.ts";
12
+ import {
13
+ createCloudflareApi,
14
+ type CloudflareApi,
15
+ type CloudflareApiOptions,
16
+ } from "./api.ts";
9
17
 
10
18
  /**
11
19
  * Origin configuration for a PostgreSQL or MySQL database connection
@@ -163,6 +171,12 @@ export interface HyperdriveProps extends CloudflareApiOptions {
163
171
  */
164
172
  hyperdriveId?: string;
165
173
 
174
+ /**
175
+ * Whether to adopt an existing hyperdrive config
176
+ * @default false
177
+ */
178
+ adopt?: boolean;
179
+
166
180
  dev?: {
167
181
  /**
168
182
  * The database connection origin configuration for local development
@@ -176,46 +190,45 @@ export interface HyperdriveProps extends CloudflareApiOptions {
176
190
  * Output returned after Cloudflare Hyperdrive creation/update.
177
191
  * IMPORTANT: The interface name MUST match the exported resource name.
178
192
  */
179
- export interface Hyperdrive
180
- extends Resource<"cloudflare::Hyperdrive">,
181
- Omit<HyperdriveProps, "origin" | "dev"> {
182
- /**
183
- * The ID of the resource
184
- */
185
- id: string;
193
+ export type Hyperdrive = Resource<"cloudflare::Hyperdrive"> &
194
+ Omit<HyperdriveProps, "origin" | "dev"> & {
195
+ /**
196
+ * The ID of the resource
197
+ */
198
+ id: string;
186
199
 
187
- /**
188
- * Name of the Hyperdrive configuration
189
- */
190
- name: string;
200
+ /**
201
+ * Name of the Hyperdrive configuration
202
+ */
203
+ name: string;
191
204
 
192
- /**
193
- * The Cloudflare-generated UUID of the hyperdrive
194
- */
195
- hyperdriveId: string;
205
+ /**
206
+ * The Cloudflare-generated UUID of the hyperdrive
207
+ */
208
+ hyperdriveId: string;
196
209
 
197
- /**
198
- * Database connection origin configuration
199
- */
200
- origin: HyperdrivePublicOrigin | HyperdriveOriginWithAccess;
210
+ /**
211
+ * Database connection origin configuration
212
+ */
213
+ origin: HyperdrivePublicOrigin | HyperdriveOriginWithAccess;
201
214
 
202
- /**
203
- * Local development configuration
204
- * @internal
205
- */
206
- dev: {
207
215
  /**
208
- * The connection string to use for local development
216
+ * Local development configuration
217
+ * @internal
209
218
  */
210
- origin: Secret;
211
- };
219
+ dev: {
220
+ /**
221
+ * The connection string to use for local development
222
+ */
223
+ origin: Secret;
224
+ };
212
225
 
213
- /**
214
- * Resource type identifier for binding.
215
- * @internal
216
- */
217
- type: "hyperdrive";
218
- }
226
+ /**
227
+ * Resource type identifier for binding.
228
+ * @internal
229
+ */
230
+ type: "hyperdrive";
231
+ };
219
232
 
220
233
  /**
221
234
  * Represents a Cloudflare Hyperdrive configuration.
@@ -327,6 +340,7 @@ interface InternalHyperdriveProps extends CloudflareApiOptions {
327
340
  origin: Secret;
328
341
  force?: boolean;
329
342
  };
343
+ adopt?: boolean;
330
344
  }
331
345
 
332
346
  const _Hyperdrive = Resource(
@@ -337,7 +351,7 @@ const _Hyperdrive = Resource(
337
351
  props: InternalHyperdriveProps,
338
352
  ): Promise<Hyperdrive> {
339
353
  const hyperdriveId = props.hyperdriveId || this.output?.hyperdriveId;
340
-
354
+ const adopt = props.adopt || this.scope.adopt;
341
355
  const name =
342
356
  props.name ?? this.output?.name ?? this.scope.createPhysicalName(id);
343
357
 
@@ -354,13 +368,6 @@ const _Hyperdrive = Resource(
354
368
  });
355
369
  }
356
370
  const api = await createCloudflareApi(props);
357
- const configsPath = `/accounts/${api.accountId}/hyperdrive/configs`;
358
-
359
- // For create operations, we don't have a hyperdriveId yet
360
- // For update/delete operations, we need to use the hyperdriveId from props or output
361
- const configPath = hyperdriveId
362
- ? `${configsPath}/${hyperdriveId}`
363
- : `${configsPath}`;
364
371
 
365
372
  if (this.phase === "delete") {
366
373
  if (!hyperdriveId) {
@@ -369,7 +376,9 @@ const _Hyperdrive = Resource(
369
376
  }
370
377
 
371
378
  try {
372
- const deleteResponse = await api.delete(configPath);
379
+ const deleteResponse = await api.delete(
380
+ `/accounts/${api.accountId}/hyperdrive/configs/${hyperdriveId}`,
381
+ );
373
382
  // Only swallow 404 Not Found errors, all other errors should be handled
374
383
  if (!deleteResponse.ok && deleteResponse.status !== 404) {
375
384
  await handleApiError(deleteResponse, "delete", "hyperdrive", id);
@@ -381,75 +390,107 @@ const _Hyperdrive = Resource(
381
390
  return this.destroy();
382
391
  }
383
392
 
384
- let response: Response | undefined;
385
- let apiResource: any;
386
-
387
393
  // Prepare request body with unwrapped secrets
388
- const requestBody = prepareRequestBody(props);
389
-
390
- try {
391
- if (this.phase === "update" && hyperdriveId) {
392
- // Update existing hyperdrive
393
- response = await api.put(configPath, requestBody);
394
- } else {
395
- // Create new hyperdrive
396
- if (hyperdriveId) {
397
- // If we have a hyperdriveId but we're in create phase, it could be because
398
- // the resource exists but wasn't in state. Do a GET to check.
399
- const getResponse = await api.get(configPath);
400
- if (getResponse.status === 200) {
401
- // Hyperdrive exists, update it
402
- logger.log(
403
- `Hyperdrive '${id}' already exists. Updating existing resource.`,
394
+ const requestBody = prepareRequestBody({ ...props, name });
395
+ let result: HyperdriveResponse;
396
+
397
+ if (hyperdriveId) {
398
+ result = await extractCloudflareResult<HyperdriveResponse>(
399
+ `update hyperdrive config "${hyperdriveId}"`,
400
+ api.put(
401
+ `/accounts/${api.accountId}/hyperdrive/configs/${hyperdriveId}`,
402
+ requestBody,
403
+ ),
404
+ );
405
+ } else {
406
+ try {
407
+ result = await extractCloudflareResult<HyperdriveResponse>(
408
+ `create hyperdrive config "${name}"`,
409
+ api.post(
410
+ `/accounts/${api.accountId}/hyperdrive/configs`,
411
+ requestBody,
412
+ ),
413
+ );
414
+ } catch (error) {
415
+ if (
416
+ error instanceof CloudflareApiError &&
417
+ (error.errorData as CloudflareApiErrorPayload[]).some(
418
+ (e) => e.code === 2017, // 2017 is the error code for name conflict
419
+ )
420
+ ) {
421
+ if (!adopt) {
422
+ throw new Error(
423
+ `Hyperdrive config "${name}" already exists. Use adopt: true to adopt it.`,
424
+ { cause: error },
425
+ );
426
+ }
427
+ const existing = await findHyperdriveConfigByName(api, name);
428
+ if (!existing) {
429
+ throw new Error(
430
+ `Hyperdrive config "${name}" failed to create due to name conflict and could not be found for adoption.`,
431
+ { cause: error },
404
432
  );
405
- response = await api.put(configPath, requestBody);
406
- } else if (getResponse.status === 404) {
407
- // Hyperdrive doesn't exist, create new
408
- response = await api.post(configsPath, {
409
- ...requestBody,
410
- // Ensure name is set correctly if not already set
411
- name: props.name || id,
412
- });
413
- } else {
414
- // Unexpected error during GET check
415
- await handleApiError(getResponse, "get", "hyperdrive", id);
416
433
  }
434
+ result = await extractCloudflareResult<HyperdriveResponse>(
435
+ `adopt hyperdrive config "${name}"`,
436
+ api.put(
437
+ `/accounts/${api.accountId}/hyperdrive/configs/${existing.id}`,
438
+ requestBody,
439
+ ),
440
+ );
417
441
  } else {
418
- // No hyperdriveId, create new
419
- response = await api.post(configsPath, {
420
- ...requestBody,
421
- // Ensure name is set correctly if not already set
422
- name: props.name || id,
423
- });
442
+ throw error;
424
443
  }
425
444
  }
426
-
427
- if (!response?.ok) {
428
- const action = this.phase === "update" ? "update" : "create";
429
- await handleApiError(response!, action, "hyperdrive", id);
430
- }
431
-
432
- const data: { result: Record<string, any> } = await response!.json();
433
- apiResource = data.result;
434
- } catch (error) {
435
- logger.error(`Error ${this.phase} Hyperdrive '${id}':`, error);
436
- throw error;
437
445
  }
438
446
 
439
447
  // Construct the output object from API response and props
440
448
  return this({
441
449
  id,
442
- hyperdriveId: apiResource.id, // Store the Cloudflare-assigned UUID
443
- name: apiResource.name,
450
+ hyperdriveId: result.id, // Store the Cloudflare-assigned UUID
451
+ name: result.name,
444
452
  origin: props.origin,
445
- caching: apiResource.caching,
446
- mtls: apiResource.mtls,
453
+ caching: result.caching,
454
+ mtls: result.mtls,
447
455
  dev: props.dev,
448
456
  type: "hyperdrive",
449
457
  });
450
458
  },
451
459
  );
452
460
 
461
+ interface HyperdriveResponse {
462
+ id: string;
463
+ name: string;
464
+ origin: HyperdriveOrigin;
465
+ caching?: HyperdriveCaching;
466
+ created_on?: string;
467
+ modified_on?: string;
468
+ mtls?: HyperdriveMtls;
469
+ origin_connection_limit?: number;
470
+ }
471
+
472
+ async function findHyperdriveConfigByName(
473
+ api: CloudflareApi,
474
+ name: string,
475
+ page = 1,
476
+ ) {
477
+ const response = await api.get(
478
+ `/accounts/${api.accountId}/hyperdrive/configs?page=${page}`,
479
+ );
480
+ const data: {
481
+ result: HyperdriveResponse[];
482
+ result_info?: { total_pages?: number };
483
+ } = await response.json();
484
+ const found = data.result.find((config) => config.name === name);
485
+ if (found) {
486
+ return found;
487
+ }
488
+ if (data.result_info?.total_pages && page < data.result_info.total_pages) {
489
+ return await findHyperdriveConfigByName(api, name, page + 1);
490
+ }
491
+ return null;
492
+ }
493
+
453
494
  /**
454
495
  * Prepare the request body by unwrapping secret values
455
496
  */
@@ -33,6 +33,7 @@ export * from "./email-rule.ts";
33
33
  export * from "./hyperdrive.ts";
34
34
  export * from "./images.ts";
35
35
  export * from "./kv-namespace.ts";
36
+ export * from "./next.ts";
36
37
  export * from "./nuxt/nuxt.ts";
37
38
  export * from "./orange.ts";
38
39
  export * from "./permission-groups.ts";