wrangler 0.0.0-e98613f8 → 0.0.0-e9a45766c

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 (244) hide show
  1. package/README.md +10 -4
  2. package/bin/wrangler.js +10 -2
  3. package/miniflare-dist/index.mjs +257 -132
  4. package/package.json +26 -19
  5. package/src/__tests__/api-dev.test.ts +65 -36
  6. package/src/__tests__/api-devregistry.test.ts +121 -0
  7. package/src/__tests__/api.test.ts +27 -5
  8. package/src/__tests__/configuration.test.ts +575 -39
  9. package/src/__tests__/constellation.test.ts +371 -0
  10. package/src/__tests__/d1/d1.test.ts +82 -0
  11. package/src/__tests__/d1/execute.test.ts +66 -0
  12. package/src/__tests__/d1/migrate.test.ts +257 -0
  13. package/src/__tests__/d1/splitter.test.ts +255 -0
  14. package/src/__tests__/delete.test.ts +11 -2
  15. package/src/__tests__/deployments.test.ts +330 -52
  16. package/src/__tests__/dev.test.tsx +146 -82
  17. package/src/__tests__/generate.test.ts +10 -8
  18. package/src/__tests__/guess-worker-format.test.ts +35 -0
  19. package/src/__tests__/helpers/end-event-loop.ts +6 -0
  20. package/src/__tests__/helpers/mock-auth-domain.ts +20 -0
  21. package/src/__tests__/helpers/mock-console.ts +6 -0
  22. package/src/__tests__/helpers/mock-dialogs.ts +71 -85
  23. package/src/__tests__/helpers/mock-get-pages-upload-token.ts +25 -0
  24. package/src/__tests__/helpers/mock-get-zone-from-host.ts +8 -5
  25. package/src/__tests__/helpers/mock-known-routes.ts +7 -2
  26. package/src/__tests__/helpers/mock-kv.ts +29 -16
  27. package/src/__tests__/helpers/mock-oauth-flow.ts +99 -92
  28. package/src/__tests__/helpers/mock-process.ts +8 -13
  29. package/src/__tests__/helpers/mock-set-timeout.ts +16 -0
  30. package/src/__tests__/helpers/msw/blob-worker.cjs +19 -0
  31. package/src/__tests__/helpers/msw/handlers/deployments.ts +127 -26
  32. package/src/__tests__/helpers/msw/handlers/namespaces.ts +18 -41
  33. package/src/__tests__/helpers/msw/handlers/r2.ts +14 -34
  34. package/src/__tests__/helpers/msw/handlers/script.ts +9 -28
  35. package/src/__tests__/helpers/msw/handlers/user.ts +13 -24
  36. package/src/__tests__/helpers/msw/handlers/zones.ts +6 -8
  37. package/src/__tests__/helpers/msw/index.ts +32 -1
  38. package/src/__tests__/helpers/msw/read-file-sync.js +61 -0
  39. package/src/__tests__/helpers/string-dynamic-values-matcher.ts +28 -0
  40. package/src/__tests__/helpers/worker-scripts/parent-worker.js +4 -1
  41. package/src/__tests__/index.test.ts +92 -74
  42. package/src/__tests__/init.test.ts +909 -628
  43. package/src/__tests__/jest.setup.ts +19 -42
  44. package/src/__tests__/kv.test.ts +355 -231
  45. package/src/__tests__/logger.test.ts +68 -2
  46. package/src/__tests__/logout.test.ts +1 -1
  47. package/src/__tests__/metrics.test.ts +93 -50
  48. package/src/__tests__/middleware.scheduled.test.ts +42 -32
  49. package/src/__tests__/middleware.test.ts +212 -122
  50. package/src/__tests__/mtls-certificates.test.ts +589 -0
  51. package/src/__tests__/pages/deployment-list.test.ts +80 -0
  52. package/src/__tests__/pages/functions-build.test.ts +528 -0
  53. package/src/__tests__/pages/pages.test.ts +81 -0
  54. package/src/__tests__/pages/project-create.test.ts +63 -0
  55. package/src/__tests__/pages/project-list.test.ts +110 -0
  56. package/src/__tests__/pages/project-upload.test.ts +500 -0
  57. package/src/__tests__/pages/publish.test.ts +2864 -0
  58. package/src/__tests__/pages-deployment-tail.test.ts +239 -102
  59. package/src/__tests__/parse.test.ts +106 -0
  60. package/src/__tests__/publish.test.ts +2218 -1002
  61. package/src/__tests__/pubsub.test.ts +226 -100
  62. package/src/__tests__/queues.test.ts +42 -32
  63. package/src/__tests__/r2.test.ts +37 -56
  64. package/src/__tests__/secret.test.ts +179 -130
  65. package/src/__tests__/tail.test.ts +113 -23
  66. package/src/__tests__/test-old-node-version.js +3 -3
  67. package/src/__tests__/traverse-module-graph.test.ts +220 -0
  68. package/src/__tests__/tsconfig-sanity.ts +12 -0
  69. package/src/__tests__/tsconfig.json +8 -0
  70. package/src/__tests__/tsconfig.tsbuildinfo +1 -0
  71. package/src/__tests__/type-generation.test.ts +8 -0
  72. package/src/__tests__/user.test.ts +7 -18
  73. package/src/__tests__/whoami.test.tsx +8 -114
  74. package/src/__tests__/worker-namespace.test.ts +83 -69
  75. package/src/api/dev.ts +172 -61
  76. package/src/api/index.ts +10 -1
  77. package/src/api/mtls-certificate.ts +148 -0
  78. package/src/api/pages/create-worker-bundle-contents.ts +77 -0
  79. package/src/api/pages/index.ts +5 -0
  80. package/src/api/pages/publish.tsx +371 -0
  81. package/src/bundle.ts +139 -33
  82. package/src/cfetch/index.ts +0 -2
  83. package/src/cfetch/internal.ts +16 -21
  84. package/src/cli.ts +4 -4
  85. package/src/config/config.ts +14 -7
  86. package/src/config/environment.ts +80 -16
  87. package/src/config/index.ts +99 -30
  88. package/src/config/validation-helpers.ts +1 -1
  89. package/src/config/validation.ts +275 -9
  90. package/src/constellation/createProject.tsx +51 -0
  91. package/src/constellation/deleteProject.ts +51 -0
  92. package/src/constellation/deleteProjectModel.ts +68 -0
  93. package/src/constellation/index.ts +75 -0
  94. package/src/constellation/listCatalog.tsx +35 -0
  95. package/src/constellation/listModel.tsx +41 -0
  96. package/src/constellation/listProject.tsx +28 -0
  97. package/src/constellation/listRuntime.tsx +28 -0
  98. package/src/constellation/options.ts +17 -0
  99. package/src/constellation/types.ts +17 -0
  100. package/src/constellation/uploadModel.tsx +64 -0
  101. package/src/constellation/utils.ts +90 -0
  102. package/src/create-worker-preview.ts +19 -8
  103. package/src/create-worker-upload-form.ts +52 -5
  104. package/src/d1/backups.tsx +40 -44
  105. package/src/d1/create.tsx +50 -43
  106. package/src/d1/{delete.tsx → delete.ts} +8 -11
  107. package/src/d1/execute.tsx +171 -166
  108. package/src/d1/index.ts +5 -6
  109. package/src/d1/list.tsx +27 -13
  110. package/src/d1/migrations/apply.tsx +92 -64
  111. package/src/d1/migrations/create.tsx +31 -29
  112. package/src/d1/migrations/helpers.ts +66 -44
  113. package/src/d1/migrations/list.tsx +47 -31
  114. package/src/d1/migrations/options.ts +7 -2
  115. package/src/d1/options.ts +3 -3
  116. package/src/d1/splitter.ts +161 -0
  117. package/src/d1/{types.tsx → types.ts} +1 -0
  118. package/src/d1/utils.ts +2 -1
  119. package/src/delete.ts +8 -16
  120. package/src/deployments.ts +333 -42
  121. package/src/deprecated/index.ts +8 -302
  122. package/src/dev/dev.tsx +13 -22
  123. package/src/dev/local.tsx +131 -69
  124. package/src/dev/remote.tsx +35 -3
  125. package/src/dev/start-server.ts +83 -77
  126. package/src/dev/use-esbuild.ts +63 -52
  127. package/src/dev/validate-dev-props.ts +9 -0
  128. package/src/{dev-registry.tsx → dev-registry.ts} +9 -8
  129. package/src/dev.tsx +131 -110
  130. package/src/dialogs.ts +136 -0
  131. package/src/dispatch-namespace.ts +21 -17
  132. package/src/docs/helpers.ts +50 -0
  133. package/src/docs/index.ts +54 -0
  134. package/src/entry.ts +26 -11
  135. package/src/environment-variables/factory.ts +89 -0
  136. package/src/environment-variables/misc-variables.ts +30 -0
  137. package/src/generate/index.ts +298 -0
  138. package/src/{index.tsx → index.ts} +137 -56
  139. package/src/init.ts +254 -187
  140. package/src/inspect.ts +170 -9
  141. package/src/jest.d.ts +4 -0
  142. package/src/kv/helpers.ts +7 -4
  143. package/src/kv/index.ts +15 -17
  144. package/src/logger.ts +36 -5
  145. package/src/metrics/metrics-config.ts +1 -1
  146. package/src/metrics/send-event.ts +4 -1
  147. package/src/miniflare-cli/assets.ts +66 -31
  148. package/src/miniflare-cli/index.ts +5 -8
  149. package/src/miniflare-cli/tsconfig.json +9 -0
  150. package/src/miniflare-cli/tsconfig.tsbuildinfo +1 -0
  151. package/src/miniflare-cli/types.ts +11 -0
  152. package/src/module-collection.ts +92 -26
  153. package/src/mtls-certificate/cli.ts +155 -0
  154. package/src/pages/build.ts +423 -0
  155. package/src/pages/buildFunctions.ts +140 -0
  156. package/src/pages/{deployment-tails.tsx → deployment-tails.ts} +7 -10
  157. package/src/pages/deployments.tsx +9 -9
  158. package/src/pages/{dev.tsx → dev.ts} +167 -139
  159. package/src/pages/errors.ts +1 -0
  160. package/src/pages/functions/buildPlugin.ts +61 -54
  161. package/src/pages/functions/buildWorker.ts +217 -33
  162. package/src/pages/functions/tsconfig.json +8 -0
  163. package/src/pages/functions/tsconfig.tsbuildinfo +1 -0
  164. package/src/pages/{functions.tsx → functions.ts} +8 -4
  165. package/src/pages/{index.tsx → index.ts} +3 -3
  166. package/src/pages/projects.tsx +12 -22
  167. package/src/pages/publish.tsx +43 -227
  168. package/src/pages/types.ts +5 -0
  169. package/src/pages/upload.tsx +57 -14
  170. package/src/pages/utils.ts +1 -1
  171. package/src/parse.ts +23 -1
  172. package/src/paths.ts +1 -1
  173. package/src/publish/index.ts +20 -16
  174. package/src/publish/publish.ts +76 -46
  175. package/src/pubsub/{pubsub-commands.tsx → pubsub-commands.ts} +19 -20
  176. package/src/queues/cli/commands/consumer/add.ts +24 -24
  177. package/src/queues/cli/commands/consumer/index.ts +3 -6
  178. package/src/queues/cli/commands/consumer/remove.ts +11 -18
  179. package/src/queues/cli/commands/create.ts +8 -8
  180. package/src/queues/cli/commands/delete.ts +8 -8
  181. package/src/queues/cli/commands/index.ts +3 -4
  182. package/src/queues/cli/commands/list.ts +8 -8
  183. package/src/queues/client.ts +1 -0
  184. package/src/r2/helpers.ts +1 -0
  185. package/src/r2/index.ts +28 -28
  186. package/src/secret/index.ts +15 -16
  187. package/src/{sites.tsx → sites.ts} +165 -53
  188. package/src/tail/createTail.ts +37 -1
  189. package/src/tail/filters.ts +1 -1
  190. package/src/tail/index.ts +8 -11
  191. package/src/tail/printing.ts +25 -0
  192. package/src/traverse-module-graph.ts +54 -0
  193. package/src/tsconfig-sanity.ts +16 -0
  194. package/src/type-generation.ts +11 -3
  195. package/src/user/access.ts +0 -1
  196. package/src/user/auth-variables.ts +113 -0
  197. package/src/user/choose-account.tsx +1 -31
  198. package/src/user/index.ts +0 -1
  199. package/src/user/{user.tsx → user.ts} +114 -77
  200. package/src/utils/render.ts +93 -0
  201. package/src/{whoami.tsx → whoami.ts} +37 -71
  202. package/src/worker.ts +35 -1
  203. package/src/yargs-types.ts +18 -5
  204. package/templates/__tests__/tsconfig-sanity.ts +12 -0
  205. package/templates/__tests__/tsconfig.json +8 -0
  206. package/templates/__tests__/tsconfig.tsbuildinfo +1 -0
  207. package/templates/checked-fetch.js +9 -3
  208. package/templates/d1-beta-facade.js +42 -3
  209. package/templates/facade.d.ts +14 -0
  210. package/templates/first-party-worker-module-facade.ts +4 -3
  211. package/templates/format-dev-errors.ts +8 -6
  212. package/templates/gitignore +1 -0
  213. package/templates/init-tests/test-jest-new-worker.js +3 -5
  214. package/templates/init-tests/test-vitest-new-worker.js +3 -5
  215. package/templates/init-tests/test-vitest-new-worker.ts +25 -0
  216. package/templates/middleware/loader-modules.ts +2 -2
  217. package/templates/middleware/loader-sw.ts +6 -0
  218. package/templates/middleware/middleware-miniflare3-json-error.ts +17 -5
  219. package/templates/new-worker.ts +3 -0
  220. package/templates/pages-dev-pipeline.ts +4 -1
  221. package/templates/pages-shim.ts +4 -1
  222. package/templates/pages-template-plugin.ts +19 -10
  223. package/templates/serve-static-assets.ts +17 -14
  224. package/templates/service-bindings-module-facade.js +1 -0
  225. package/templates/tsconfig-sanity.ts +11 -0
  226. package/templates/tsconfig.init.json +105 -0
  227. package/templates/tsconfig.json +5 -103
  228. package/templates/tsconfig.tsbuildinfo +1 -0
  229. package/wrangler-dist/cli.d.ts +871 -73
  230. package/wrangler-dist/cli.js +80512 -90686
  231. package/wrangler-dist/wasm-sync.wasm +0 -0
  232. package/src/__tests__/api-devregistry.test.js +0 -56
  233. package/src/__tests__/d1.test.ts +0 -80
  234. package/src/__tests__/dialogs.test.tsx +0 -40
  235. package/src/__tests__/helpers/mock-cfetch.ts +0 -333
  236. package/src/__tests__/pages.test.ts +0 -2442
  237. package/src/dialogs.tsx +0 -168
  238. package/src/environment-variables.ts +0 -50
  239. package/src/pages/build.tsx +0 -270
  240. package/src/user/env-vars.ts +0 -46
  241. /package/src/{bundle-reporter.tsx → bundle-reporter.ts} +0 -0
  242. /package/src/d1/migrations/{index.tsx → index.ts} +0 -0
  243. /package/src/dev/{get-local-persistence-path.tsx → get-local-persistence-path.ts} +0 -0
  244. /package/src/pages/{hash.tsx → hash.ts} +0 -0
@@ -0,0 +1,41 @@
1
+ import { withConfig } from "../config";
2
+ import { logger } from "../logger";
3
+ import { requireAuth } from "../user";
4
+ import { takeName } from "./options";
5
+ import {
6
+ constellationBetaWarning,
7
+ getProjectByName,
8
+ listModels,
9
+ } from "./utils";
10
+ import type {
11
+ CommonYargsArgv,
12
+ StrictYargsOptionsToInterface,
13
+ } from "../yargs-types";
14
+ import type { Project } from "./types";
15
+
16
+ export function options(yargs: CommonYargsArgv) {
17
+ return takeName(yargs)
18
+ .option("json", {
19
+ describe: "return output as clean JSON",
20
+ type: "boolean",
21
+ default: false,
22
+ })
23
+ .epilogue(constellationBetaWarning);
24
+ }
25
+
26
+ type HandlerOptions = StrictYargsOptionsToInterface<typeof options>;
27
+ export const handler = withConfig<HandlerOptions>(
28
+ async ({ name, json, config }): Promise<void> => {
29
+ const accountId = await requireAuth(config);
30
+ const proj: Project = await getProjectByName(config, accountId, name);
31
+
32
+ const models = await listModels(accountId, proj);
33
+
34
+ if (json) {
35
+ logger.log(JSON.stringify(models, null, 2));
36
+ } else {
37
+ logger.log(constellationBetaWarning);
38
+ logger.table(models);
39
+ }
40
+ }
41
+ );
@@ -0,0 +1,28 @@
1
+ import { withConfig } from "../config";
2
+ import { logger } from "../logger";
3
+ import { requireAuth } from "../user";
4
+ import { asJson } from "./options";
5
+ import { constellationBetaWarning, listProjects } from "./utils";
6
+ import type {
7
+ CommonYargsArgv,
8
+ StrictYargsOptionsToInterface,
9
+ } from "../yargs-types";
10
+
11
+ export function options(yargs: CommonYargsArgv) {
12
+ return asJson(yargs).epilogue(constellationBetaWarning);
13
+ }
14
+
15
+ type HandlerOptions = StrictYargsOptionsToInterface<typeof options>;
16
+ export const handler = withConfig<HandlerOptions>(
17
+ async ({ json, config }): Promise<void> => {
18
+ const accountId = await requireAuth(config);
19
+ const projs = await listProjects(accountId);
20
+
21
+ if (json) {
22
+ logger.log(JSON.stringify(projs, null, 2));
23
+ } else {
24
+ logger.log(constellationBetaWarning);
25
+ logger.table(projs);
26
+ }
27
+ }
28
+ );
@@ -0,0 +1,28 @@
1
+ import { withConfig } from "../config";
2
+ import { logger } from "../logger";
3
+ import { requireAuth } from "../user";
4
+ import { asJson } from "./options";
5
+ import { constellationBetaWarning, listRuntimes } from "./utils";
6
+ import type {
7
+ CommonYargsArgv,
8
+ StrictYargsOptionsToInterface,
9
+ } from "../yargs-types";
10
+
11
+ export function options(yargs: CommonYargsArgv) {
12
+ return asJson(yargs).epilogue(constellationBetaWarning);
13
+ }
14
+
15
+ type HandlerOptions = StrictYargsOptionsToInterface<typeof options>;
16
+ export const handler = withConfig<HandlerOptions>(
17
+ async ({ json, config }): Promise<void> => {
18
+ const accountId = await requireAuth(config);
19
+ const runtimes = await listRuntimes(accountId);
20
+
21
+ if (json) {
22
+ logger.log(JSON.stringify(runtimes, null, 2));
23
+ } else {
24
+ logger.log(constellationBetaWarning);
25
+ logger.table(runtimes.map((runtime) => ({ name: runtime })));
26
+ }
27
+ }
28
+ );
@@ -0,0 +1,17 @@
1
+ import type { CommonYargsArgv } from "../yargs-types";
2
+
3
+ export function takeName(yargs: CommonYargsArgv) {
4
+ return yargs.positional("name", {
5
+ describe: "The name of the project",
6
+ type: "string",
7
+ demandOption: true,
8
+ });
9
+ }
10
+
11
+ export function asJson(yargs: CommonYargsArgv) {
12
+ return yargs.option("json", {
13
+ describe: "return output as clean JSON",
14
+ type: "boolean",
15
+ default: false,
16
+ });
17
+ }
@@ -0,0 +1,17 @@
1
+ export type Project = {
2
+ id: string;
3
+ name: string;
4
+ runtime: string;
5
+ };
6
+
7
+ export type Model = {
8
+ id: string;
9
+ project_id: string;
10
+ name: string;
11
+ description: string;
12
+ };
13
+
14
+ export type CatalogEntry = {
15
+ project: Project;
16
+ models: Model[];
17
+ };
@@ -0,0 +1,64 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { FormData, File } from "undici";
3
+ import { fetchResult } from "../cfetch";
4
+ import { withConfig } from "../config";
5
+ import { logger } from "../logger";
6
+ import { requireAuth } from "../user";
7
+ import { takeName } from "./options";
8
+ import { constellationBetaWarning, getProjectByName } from "./utils";
9
+ import type {
10
+ CommonYargsArgv,
11
+ StrictYargsOptionsToInterface,
12
+ } from "../yargs-types";
13
+ import type { Model } from "./types";
14
+
15
+ export function options(yargs: CommonYargsArgv) {
16
+ return takeName(yargs)
17
+ .positional("modelName", {
18
+ describe: "The name of the uploaded model",
19
+ type: "string",
20
+ demandOption: true,
21
+ })
22
+ .positional("modelFile", {
23
+ describe: "The name of the local file with the model contents",
24
+ type: "string",
25
+ demandOption: true,
26
+ })
27
+ .epilogue(constellationBetaWarning);
28
+ }
29
+ type HandlerOptions = StrictYargsOptionsToInterface<typeof options>;
30
+ export const handler = withConfig<HandlerOptions>(
31
+ async ({ name, modelName, modelFile, config }): Promise<void> => {
32
+ const accountId = await requireAuth(config);
33
+ logger.log(constellationBetaWarning);
34
+
35
+ const proj = await getProjectByName(config, accountId, name);
36
+
37
+ const formData = new FormData();
38
+ formData.set(
39
+ "file",
40
+ new File([readFileSync(modelFile)], modelFile, {
41
+ type: "application/octet-stream",
42
+ })
43
+ );
44
+ formData.set("name", modelName);
45
+
46
+ let model: Model;
47
+ try {
48
+ model = await fetchResult(
49
+ `/accounts/${accountId}/constellation/project/${proj.id}/model`,
50
+ {
51
+ method: "POST",
52
+ body: formData,
53
+ }
54
+ );
55
+ } catch (e) {
56
+ if ((e as { code: number }).code === 7408) {
57
+ throw new Error("A model with that name already exists");
58
+ }
59
+ throw e;
60
+ }
61
+
62
+ logger.log(`✅ Successfully uploaded Model "${model.name}"!`);
63
+ }
64
+ );
@@ -0,0 +1,90 @@
1
+ import { fetchResult } from "../cfetch";
2
+ import { getEnvironmentVariableFactory } from "../environment-variables/factory";
3
+ import type { Config } from "../config";
4
+ import type { Project, Model, CatalogEntry } from "./types";
5
+
6
+ export const getConstellationWarningFromEnv = getEnvironmentVariableFactory({
7
+ variableName: "NO_CONSTELLATION_WARNING",
8
+ });
9
+
10
+ export const constellationBetaWarning =
11
+ getConstellationWarningFromEnv() !== undefined
12
+ ? ""
13
+ : "--------------------\n🚧 Constellation AI is currently in open alpha and is not recommended for production data and traffic\n🚧 Please report any bugs to https://github.com/cloudflare/workers-sdk/issues/new/choose\n🚧 To give feedback, visit https://discord.gg/cloudflaredev\n--------------------\n";
14
+
15
+ export const getProjectByName = async (
16
+ config: Config,
17
+ accountId: string,
18
+ name: string
19
+ ): Promise<Project> => {
20
+ const allProjects = await listProjects(accountId);
21
+ const matchingProj = allProjects.find((proj) => proj.name === name);
22
+ if (!matchingProj) {
23
+ throw new Error(`Couldn't find Project with name '${name}'`);
24
+ }
25
+ return matchingProj;
26
+ };
27
+
28
+ export const getProjectModelByName = async (
29
+ config: Config,
30
+ accountId: string,
31
+ proj: Project,
32
+ modelName: string
33
+ ): Promise<Model> => {
34
+ const allModels = await listModels(accountId, proj);
35
+ const matchingModel = allModels.find((model) => model.name === modelName);
36
+ if (!matchingModel) {
37
+ throw new Error(`Couldn't find Model with name '${modelName}'`);
38
+ }
39
+ return matchingModel;
40
+ };
41
+
42
+ export async function constellationList<ResponseType>(
43
+ accountId: string,
44
+ partialUrl: string
45
+ ): Promise<Array<ResponseType>> {
46
+ const pageSize = 50;
47
+ let page = 1;
48
+ const results = [];
49
+ while (results.length % pageSize === 0) {
50
+ const json: Array<ResponseType> = await fetchResult(
51
+ `/accounts/${accountId}/constellation/${partialUrl}`,
52
+ {},
53
+ new URLSearchParams({
54
+ per_page: pageSize.toString(),
55
+ page: page.toString(),
56
+ })
57
+ );
58
+ page++;
59
+ results.push(...json);
60
+ if (json.length < pageSize) {
61
+ break;
62
+ }
63
+ }
64
+ return results;
65
+ }
66
+
67
+ export const listCatalogEntries = async (
68
+ accountId: string
69
+ ): Promise<Array<CatalogEntry>> => {
70
+ return await constellationList(accountId, "catalog");
71
+ };
72
+
73
+ export const listModels = async (
74
+ accountId: string,
75
+ proj: Project
76
+ ): Promise<Array<Model>> => {
77
+ return constellationList(accountId, `project/${proj.id}/model`);
78
+ };
79
+
80
+ export const listProjects = async (
81
+ accountId: string
82
+ ): Promise<Array<Project>> => {
83
+ return await constellationList(accountId, "project");
84
+ };
85
+
86
+ export const listRuntimes = async (
87
+ accountId: string
88
+ ): Promise<Array<string>> => {
89
+ return await constellationList(accountId, "runtime");
90
+ };
@@ -109,6 +109,14 @@ function randomId(): string {
109
109
  });
110
110
  }
111
111
 
112
+ // URLs are often relative to the zone. Sometimes the base zone
113
+ // will be grey-clouded, and so the host must be swapped out for
114
+ // the worker route host, which is more likely to be orange-clouded
115
+ function switchHost(originalUrl: string, host?: string): URL {
116
+ const url = new URL(originalUrl);
117
+ url.hostname = host ?? url.hostname;
118
+ return url;
119
+ }
112
120
  /**
113
121
  * Generates a preview session token.
114
122
  */
@@ -129,9 +137,13 @@ export async function createPreviewSession(
129
137
  abortSignal
130
138
  );
131
139
 
132
- logger.debug(`-- START EXCHANGE API REQUEST: GET ${exchange_url}`);
140
+ const switchedExchangeUrl = switchHost(exchange_url, ctx.host).toString();
141
+
142
+ logger.debug(`-- START EXCHANGE API REQUEST: GET ${switchedExchangeUrl}`);
133
143
  logger.debug("-- END EXCHANGE API REQUEST");
134
- const exchangeResponse = await fetch(exchange_url, { signal: abortSignal });
144
+ const exchangeResponse = await fetch(switchedExchangeUrl, {
145
+ signal: abortSignal,
146
+ });
135
147
  const bodyText = await exchangeResponse.text();
136
148
  logger.debug(
137
149
  "-- START EXCHANGE API RESPONSE:",
@@ -147,16 +159,15 @@ export async function createPreviewSession(
147
159
  token: string;
148
160
  prewarm: string;
149
161
  }>(bodyText);
150
-
151
- const { host } = new URL(inspector_websocket);
152
- const query = `cf_workers_preview_token=${token}`;
162
+ const inspector = new URL(inspector_websocket);
163
+ inspector.searchParams.append("cf_workers_preview_token", token);
153
164
 
154
165
  return {
155
166
  id: randomId(),
156
167
  value: token,
157
- host,
158
- inspectorUrl: new URL(`${inspector_websocket}?${query}`),
159
- prewarmUrl: new URL(prewarm),
168
+ host: ctx.host ?? inspector.host,
169
+ inspectorUrl: switchHost(inspector.href, ctx.host),
170
+ prewarmUrl: switchHost(prewarm, ctx.host),
160
171
  };
161
172
  }
162
173
 
@@ -4,6 +4,7 @@ import type {
4
4
  CfWorkerInit,
5
5
  CfModuleType,
6
6
  CfDurableObjectMigrations,
7
+ CfPlacement,
7
8
  } from "./worker.js";
8
9
 
9
10
  export function toMimeType(type: CfModuleType): string {
@@ -23,7 +24,7 @@ export function toMimeType(type: CfModuleType): string {
23
24
  }
24
25
  }
25
26
 
26
- type WorkerMetadataBinding =
27
+ export type WorkerMetadataBinding =
27
28
  // If you add any new binding types here, also add it to safeBindings
28
29
  // under validateUnsafeBinding in config/validation.ts
29
30
  | { type: "plain_text"; name: string; text: string }
@@ -32,6 +33,12 @@ type WorkerMetadataBinding =
32
33
  | { type: "text_blob"; name: string; part: string }
33
34
  | { type: "data_blob"; name: string; part: string }
34
35
  | { type: "kv_namespace"; name: string; namespace_id: string }
36
+ | {
37
+ type: "send_email";
38
+ name: string;
39
+ destination_address?: string;
40
+ allowed_destination_addresses?: string[];
41
+ }
35
42
  | {
36
43
  type: "durable_object_namespace";
37
44
  name: string;
@@ -43,7 +50,9 @@ type WorkerMetadataBinding =
43
50
  | { type: "r2_bucket"; name: string; bucket_name: string }
44
51
  | { type: "d1"; name: string; id: string; internalEnv?: string }
45
52
  | { type: "service"; name: string; service: string; environment?: string }
46
- | { type: "namespace"; name: string; namespace: string }
53
+ | { type: "analytics_engine"; name: string; dataset?: string }
54
+ | { type: "dispatch_namespace"; name: string; namespace: string }
55
+ | { type: "mtls_certificate"; name: string; certificate_id: string }
47
56
  | {
48
57
  type: "logfwdr";
49
58
  name: string;
@@ -63,6 +72,9 @@ export interface WorkerMetadata {
63
72
  bindings: WorkerMetadataBinding[];
64
73
  keep_bindings?: WorkerMetadataBinding["type"][];
65
74
  logpush?: boolean;
75
+ placement?: CfPlacement;
76
+ // Allow unsafe.metadata to add arbitary properties at runtime
77
+ [key: string]: unknown;
66
78
  }
67
79
 
68
80
  /**
@@ -79,6 +91,7 @@ export function createWorkerUploadForm(worker: CfWorkerInit): FormData {
79
91
  compatibility_flags,
80
92
  keepVars,
81
93
  logpush,
94
+ placement,
82
95
  } = worker;
83
96
 
84
97
  let { modules } = worker;
@@ -101,6 +114,17 @@ export function createWorkerUploadForm(worker: CfWorkerInit): FormData {
101
114
  });
102
115
  });
103
116
 
117
+ bindings.send_email?.forEach(
118
+ ({ name, destination_address, allowed_destination_addresses }) => {
119
+ metadataBindings.push({
120
+ name: name,
121
+ type: "send_email",
122
+ destination_address,
123
+ allowed_destination_addresses,
124
+ });
125
+ }
126
+ );
127
+
104
128
  bindings.durable_objects?.bindings.forEach(
105
129
  ({ name, class_name, script_name, environment }) => {
106
130
  metadataBindings.push({
@@ -149,14 +173,30 @@ export function createWorkerUploadForm(worker: CfWorkerInit): FormData {
149
173
  });
150
174
  });
151
175
 
176
+ bindings.analytics_engine_datasets?.forEach(({ binding, dataset }) => {
177
+ metadataBindings.push({
178
+ name: binding,
179
+ type: "analytics_engine",
180
+ dataset,
181
+ });
182
+ });
183
+
152
184
  bindings.dispatch_namespaces?.forEach(({ binding, namespace }) => {
153
185
  metadataBindings.push({
154
186
  name: binding,
155
- type: "namespace",
187
+ type: "dispatch_namespace",
156
188
  namespace,
157
189
  });
158
190
  });
159
191
 
192
+ bindings.mtls_certificates?.forEach(({ binding, certificate_id }) => {
193
+ metadataBindings.push({
194
+ name: binding,
195
+ type: "mtls_certificate",
196
+ certificate_id,
197
+ });
198
+ });
199
+
160
200
  bindings.logfwdr?.bindings.forEach(({ name, destination }) => {
161
201
  metadataBindings.push({
162
202
  name: name,
@@ -266,9 +306,9 @@ export function createWorkerUploadForm(worker: CfWorkerInit): FormData {
266
306
  }
267
307
  }
268
308
 
269
- if (bindings.unsafe) {
309
+ if (bindings.unsafe?.bindings) {
270
310
  // @ts-expect-error unsafe bindings don't need to match a specific type here
271
- metadataBindings.push(...bindings.unsafe);
311
+ metadataBindings.push(...bindings.unsafe.bindings);
272
312
  }
273
313
 
274
314
  const metadata: WorkerMetadata = {
@@ -283,8 +323,15 @@ export function createWorkerUploadForm(worker: CfWorkerInit): FormData {
283
323
  capnp_schema: bindings.logfwdr?.schema,
284
324
  ...(keepVars && { keep_bindings: ["plain_text", "json"] }),
285
325
  ...(logpush !== undefined && { logpush }),
326
+ ...(placement && { placement }),
286
327
  };
287
328
 
329
+ if (bindings.unsafe?.metadata !== undefined) {
330
+ for (const key of Object.keys(bindings.unsafe.metadata)) {
331
+ metadata[key] = bindings.unsafe.metadata[key];
332
+ }
333
+ }
334
+
288
335
  formData.set("metadata", JSON.stringify(metadata));
289
336
 
290
337
  if (main.type === "commonjs" && modules && modules.length > 0) {
@@ -1,6 +1,5 @@
1
1
  import fs from "node:fs/promises";
2
2
  import * as path from "path";
3
- import { render } from "ink";
4
3
  import Table from "ink-table";
5
4
  import React from "react";
6
5
  import { fetchResult } from "../cfetch";
@@ -8,22 +7,24 @@ import { performApiFetch } from "../cfetch/internal";
8
7
  import { withConfig } from "../config";
9
8
  import { logger } from "../logger";
10
9
  import { requireAuth } from "../user";
10
+ import { renderToString } from "../utils/render";
11
11
  import { formatBytes, formatTimeAgo } from "./formatTimeAgo";
12
12
  import { Name } from "./options";
13
13
  import { d1BetaWarning, getDatabaseByNameOrBinding } from "./utils";
14
+ import type {
15
+ CommonYargsArgv,
16
+ StrictYargsOptionsToInterface,
17
+ } from "../yargs-types";
14
18
  import type { Backup, Database } from "./types";
15
19
  import type { Response } from "undici";
16
- import type { Argv } from "yargs";
17
20
 
18
- type BackupListArgs = { config?: string; name: string };
19
-
20
- export function ListOptions(yargs: Argv): Argv<BackupListArgs> {
21
+ export function ListOptions(yargs: CommonYargsArgv) {
21
22
  return Name(yargs);
22
23
  }
23
-
24
- export const ListHandler = withConfig<BackupListArgs>(
24
+ type ListHandlerOptions = StrictYargsOptionsToInterface<typeof ListOptions>;
25
+ export const ListHandler = withConfig<ListHandlerOptions>(
25
26
  async ({ config, name }): Promise<void> => {
26
- const accountId = await requireAuth({});
27
+ const accountId = await requireAuth(config);
27
28
  logger.log(d1BetaWarning);
28
29
  const db: Database = await getDatabaseByNameOrBinding(
29
30
  config,
@@ -32,11 +33,13 @@ export const ListHandler = withConfig<BackupListArgs>(
32
33
  );
33
34
 
34
35
  const backups: Backup[] = await listBackups(accountId, db.uuid);
35
- render(
36
- <Table
37
- data={backups}
38
- columns={["created_at", "id", "num_tables", "size"]}
39
- ></Table>
36
+ logger.log(
37
+ renderToString(
38
+ <Table
39
+ data={backups}
40
+ columns={["created_at", "id", "num_tables", "size"]}
41
+ ></Table>
42
+ )
40
43
  );
41
44
  }
42
45
  );
@@ -77,15 +80,14 @@ export const listBackups = async (
77
80
  return Object.values(results);
78
81
  };
79
82
 
80
- type BackupCreateArgs = BackupListArgs;
81
-
82
- export function CreateOptions(yargs: Argv): Argv<BackupCreateArgs> {
83
+ export function CreateOptions(yargs: CommonYargsArgv) {
83
84
  return ListOptions(yargs);
84
85
  }
86
+ type CreateHandlerOptions = StrictYargsOptionsToInterface<typeof CreateOptions>;
85
87
 
86
- export const CreateHandler = withConfig<BackupCreateArgs>(
88
+ export const CreateHandler = withConfig<CreateHandlerOptions>(
87
89
  async ({ config, name }): Promise<void> => {
88
- const accountId = await requireAuth({});
90
+ const accountId = await requireAuth(config);
89
91
  logger.log(d1BetaWarning);
90
92
  const db: Database = await getDatabaseByNameOrBinding(
91
93
  config,
@@ -94,11 +96,13 @@ export const CreateHandler = withConfig<BackupCreateArgs>(
94
96
  );
95
97
 
96
98
  const backup: Backup = await createBackup(accountId, db.uuid);
97
- render(
98
- <Table
99
- data={[backup]}
100
- columns={["created_at", "id", "num_tables", "size", "state"]}
101
- ></Table>
99
+ logger.log(
100
+ renderToString(
101
+ <Table
102
+ data={[backup]}
103
+ columns={["created_at", "id", "num_tables", "size", "state"]}
104
+ ></Table>
105
+ )
102
106
  );
103
107
  }
104
108
  );
@@ -119,21 +123,19 @@ export const createBackup = async (
119
123
  };
120
124
  };
121
125
 
122
- type BackupRestoreArgs = BackupListArgs & {
123
- "backup-id": string;
124
- };
125
-
126
- export function RestoreOptions(yargs: Argv): Argv<BackupRestoreArgs> {
126
+ export function RestoreOptions(yargs: CommonYargsArgv) {
127
127
  return ListOptions(yargs).positional("backup-id", {
128
128
  describe: "The Backup ID to restore",
129
129
  type: "string",
130
130
  demandOption: true,
131
131
  });
132
132
  }
133
-
134
- export const RestoreHandler = withConfig<BackupRestoreArgs>(
133
+ type RestoreHandlerOptions = StrictYargsOptionsToInterface<
134
+ typeof RestoreOptions
135
+ >;
136
+ export const RestoreHandler = withConfig<RestoreHandlerOptions>(
135
137
  async ({ config, name, backupId }): Promise<void> => {
136
- const accountId = await requireAuth({});
138
+ const accountId = await requireAuth(config);
137
139
  logger.log(d1BetaWarning);
138
140
  const db: Database = await getDatabaseByNameOrBinding(
139
141
  config,
@@ -163,11 +165,7 @@ export const restoreBackup = async (
163
165
  );
164
166
  };
165
167
 
166
- type BackupDownloadArgs = BackupRestoreArgs & {
167
- output?: string;
168
- };
169
-
170
- export function DownloadOptions(yargs: Argv): Argv<BackupDownloadArgs> {
168
+ export function DownloadOptions(yargs: CommonYargsArgv) {
171
169
  return ListOptions(yargs)
172
170
  .positional("backup-id", {
173
171
  describe: "The Backup ID to download",
@@ -180,10 +178,12 @@ export function DownloadOptions(yargs: Argv): Argv<BackupDownloadArgs> {
180
178
  type: "string",
181
179
  });
182
180
  }
183
-
184
- export const DownloadHandler = withConfig<BackupDownloadArgs>(
181
+ type DownloadHandlerOptions = StrictYargsOptionsToInterface<
182
+ typeof DownloadOptions
183
+ >;
184
+ export const DownloadHandler = withConfig<DownloadHandlerOptions>(
185
185
  async ({ name, backupId, output, config }): Promise<void> => {
186
- const accountId = await requireAuth({});
186
+ const accountId = await requireAuth(config);
187
187
  logger.log(d1BetaWarning);
188
188
  const db: Database = await getDatabaseByNameOrBinding(
189
189
  config,
@@ -191,11 +191,7 @@ export const DownloadHandler = withConfig<BackupDownloadArgs>(
191
191
  name
192
192
  );
193
193
  const filename =
194
- output ||
195
- path.join(
196
- process.env.INIT_CWD as string,
197
- `${name}.${backupId.slice(0, 8)}.sqlite3`
198
- );
194
+ output || path.resolve(`${name}.${backupId.slice(0, 8)}.sqlite3`);
199
195
 
200
196
  logger.log(`🌀 Downloading backup ${backupId} from '${name}'`);
201
197
  const response = await getBackupResponse(accountId, db.uuid, backupId);