@pithy-sh/cloudflare 0.1.2 → 0.1.3

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 (139) hide show
  1. package/dist/ai/aiManager.d.ts +99 -0
  2. package/dist/ai/aiManager.d.ts.map +1 -0
  3. package/dist/ai/aiManager.js +148 -0
  4. package/dist/ai/vectorizeManager.d.ts +67 -0
  5. package/dist/ai/vectorizeManager.d.ts.map +1 -0
  6. package/dist/ai/vectorizeManager.js +101 -0
  7. package/dist/ai/vectorizeProvisioner.d.ts +123 -0
  8. package/dist/ai/vectorizeProvisioner.d.ts.map +1 -0
  9. package/dist/ai/vectorizeProvisioner.js +195 -0
  10. package/dist/client/accounts.d.ts +48 -0
  11. package/dist/client/accounts.d.ts.map +1 -0
  12. package/dist/client/accounts.js +55 -0
  13. package/dist/client/clients.d.ts +122 -0
  14. package/dist/client/clients.d.ts.map +1 -0
  15. package/dist/client/clients.js +216 -0
  16. package/dist/client/errors.d.ts +73 -0
  17. package/dist/client/errors.d.ts.map +1 -0
  18. package/dist/client/errors.js +98 -0
  19. package/dist/client/manager.d.ts +45 -0
  20. package/dist/client/manager.d.ts.map +1 -0
  21. package/dist/client/manager.js +51 -0
  22. package/dist/d1/d1Manager.d.ts +74 -0
  23. package/dist/d1/d1Manager.d.ts.map +1 -0
  24. package/dist/d1/d1Manager.js +128 -0
  25. package/dist/d1/d1PreparedStatement.d.ts +24 -0
  26. package/dist/d1/d1PreparedStatement.d.ts.map +1 -0
  27. package/dist/d1/d1PreparedStatement.js +91 -0
  28. package/dist/d1/d1Provisioner.d.ts +28 -0
  29. package/dist/d1/d1Provisioner.d.ts.map +1 -0
  30. package/dist/d1/d1Provisioner.js +67 -0
  31. package/dist/email/emailRoutingManager.d.ts +36 -0
  32. package/dist/email/emailRoutingManager.d.ts.map +1 -0
  33. package/dist/email/emailRoutingManager.js +124 -0
  34. package/dist/email/emailSendManager.d.ts +45 -0
  35. package/dist/email/emailSendManager.d.ts.map +1 -0
  36. package/dist/email/emailSendManager.js +52 -0
  37. package/dist/env/devVars.d.ts +65 -0
  38. package/dist/env/devVars.d.ts.map +1 -0
  39. package/dist/env/devVars.js +84 -0
  40. package/dist/hostnames/customHostnamesManager.d.ts +51 -0
  41. package/dist/hostnames/customHostnamesManager.d.ts.map +1 -0
  42. package/dist/hostnames/customHostnamesManager.js +84 -0
  43. package/dist/kv/kvManager.d.ts +76 -0
  44. package/dist/kv/kvManager.d.ts.map +1 -0
  45. package/dist/kv/kvManager.js +135 -0
  46. package/dist/kv/kvProvisioner.d.ts +28 -0
  47. package/dist/kv/kvProvisioner.d.ts.map +1 -0
  48. package/dist/kv/kvProvisioner.js +71 -0
  49. package/dist/media/assetSeeder.d.ts +31 -0
  50. package/dist/media/assetSeeder.d.ts.map +1 -0
  51. package/dist/media/assetSeeder.js +70 -0
  52. package/dist/media/imageManager.d.ts +34 -0
  53. package/dist/media/imageManager.d.ts.map +1 -0
  54. package/dist/media/imageManager.js +103 -0
  55. package/dist/media/ownership.d.ts +40 -0
  56. package/dist/media/ownership.d.ts.map +1 -0
  57. package/dist/media/ownership.js +46 -0
  58. package/dist/media/streamManager.d.ts +83 -0
  59. package/dist/media/streamManager.d.ts.map +1 -0
  60. package/dist/media/streamManager.js +145 -0
  61. package/dist/queue/queueManager.d.ts +84 -0
  62. package/dist/queue/queueManager.d.ts.map +1 -0
  63. package/dist/queue/queueManager.js +114 -0
  64. package/dist/r2/r2Credentials.d.ts +12 -0
  65. package/dist/r2/r2Credentials.d.ts.map +1 -0
  66. package/dist/r2/r2Credentials.js +13 -0
  67. package/dist/r2/r2Manager.d.ts +226 -0
  68. package/dist/r2/r2Manager.d.ts.map +1 -0
  69. package/dist/r2/r2Manager.js +405 -0
  70. package/dist/r2/r2Provisioner.d.ts +39 -0
  71. package/dist/r2/r2Provisioner.d.ts.map +1 -0
  72. package/dist/r2/r2Provisioner.js +86 -0
  73. package/dist/secrets/secretsStoreManager.d.ts +82 -0
  74. package/dist/secrets/secretsStoreManager.d.ts.map +1 -0
  75. package/dist/secrets/secretsStoreManager.js +147 -0
  76. package/dist/secrets/secretsStores.d.ts +47 -0
  77. package/dist/secrets/secretsStores.d.ts.map +1 -0
  78. package/dist/secrets/secretsStores.js +65 -0
  79. package/dist/test-utils/emailRoutingRules.d.ts +39 -0
  80. package/dist/test-utils/emailRoutingRules.d.ts.map +1 -0
  81. package/dist/test-utils/emailRoutingRules.js +89 -0
  82. package/dist/test-utils/fixtureReportSetup.d.ts +25 -0
  83. package/dist/test-utils/fixtureReportSetup.d.ts.map +1 -0
  84. package/dist/test-utils/fixtureReportSetup.js +30 -0
  85. package/dist/test-utils/fixtures.d.ts +224 -0
  86. package/dist/test-utils/fixtures.d.ts.map +1 -0
  87. package/dist/test-utils/fixtures.js +277 -0
  88. package/dist/test-utils/harness.d.ts +192 -0
  89. package/dist/test-utils/harness.d.ts.map +1 -0
  90. package/dist/test-utils/harness.js +351 -0
  91. package/dist/test-utils/inboundRecorder.d.ts +91 -0
  92. package/dist/test-utils/inboundRecorder.d.ts.map +1 -0
  93. package/dist/test-utils/inboundRecorder.js +141 -0
  94. package/dist/test-utils/integrationSetup.d.ts +22 -0
  95. package/dist/test-utils/integrationSetup.d.ts.map +1 -0
  96. package/dist/test-utils/integrationSetup.js +37 -0
  97. package/dist/test-utils/reap.d.ts +112 -0
  98. package/dist/test-utils/reap.d.ts.map +1 -0
  99. package/dist/test-utils/reap.js +185 -0
  100. package/dist/tokens/accountTokensManager.d.ts +157 -0
  101. package/dist/tokens/accountTokensManager.d.ts.map +1 -0
  102. package/dist/tokens/accountTokensManager.js +280 -0
  103. package/dist/tokens/permissions.d.ts +36 -0
  104. package/dist/tokens/permissions.d.ts.map +1 -0
  105. package/dist/tokens/permissions.js +50 -0
  106. package/dist/tokens/profiles.d.ts +102 -0
  107. package/dist/tokens/profiles.d.ts.map +1 -0
  108. package/dist/tokens/profiles.js +137 -0
  109. package/dist/turnstile/turnstileManager.d.ts +75 -0
  110. package/dist/turnstile/turnstileManager.d.ts.map +1 -0
  111. package/dist/turnstile/turnstileManager.js +138 -0
  112. package/dist/user/userManager.d.ts +36 -0
  113. package/dist/user/userManager.d.ts.map +1 -0
  114. package/dist/user/userManager.js +58 -0
  115. package/dist/workers/buildsManager.d.ts +116 -0
  116. package/dist/workers/buildsManager.d.ts.map +1 -0
  117. package/dist/workers/buildsManager.js +237 -0
  118. package/dist/workers/buildsTypes.d.ts +102 -0
  119. package/dist/workers/buildsTypes.d.ts.map +1 -0
  120. package/dist/workers/buildsTypes.js +87 -0
  121. package/dist/workers/workersBuildEvent.d.ts +64 -0
  122. package/dist/workers/workersBuildEvent.d.ts.map +1 -0
  123. package/dist/workers/workersBuildEvent.js +47 -0
  124. package/dist/workers/workersManager.d.ts +136 -0
  125. package/dist/workers/workersManager.d.ts.map +1 -0
  126. package/dist/workers/workersManager.js +312 -0
  127. package/dist/workers/workersProvisioner.d.ts +80 -0
  128. package/dist/workers/workersProvisioner.d.ts.map +1 -0
  129. package/dist/workers/workersProvisioner.js +106 -0
  130. package/dist/workflows/stepFailure.d.ts +180 -0
  131. package/dist/workflows/stepFailure.d.ts.map +1 -0
  132. package/dist/workflows/stepFailure.js +227 -0
  133. package/dist/workflows/workflowsClient.d.ts +87 -0
  134. package/dist/workflows/workflowsClient.d.ts.map +1 -0
  135. package/dist/workflows/workflowsClient.js +156 -0
  136. package/dist/zones/zonesManager.d.ts +50 -0
  137. package/dist/zones/zonesManager.d.ts.map +1 -0
  138. package/dist/zones/zonesManager.js +74 -0
  139. package/package.json +18 -9
@@ -0,0 +1,136 @@
1
+ import type { RouteCreateResponse, RouteListResponse } from "cloudflare/resources/workers/routes";
2
+ import type { Deployment } from "cloudflare/resources/workers/scripts/deployments";
3
+ import type { Script } from "cloudflare/resources/workers/scripts/scripts";
4
+ import type { SecretListResponse } from "cloudflare/resources/workers/scripts/secrets";
5
+ import type { SettingEditParams } from "cloudflare/resources/workers/scripts/settings";
6
+ import type { VersionGetResponse, VersionListResponse } from "cloudflare/resources/workers/scripts/versions";
7
+ import { CloudflareManager } from "../client/manager";
8
+ /** Worker settings a caller may edit (observability, logpush, tags, …); the account id is supplied. */
9
+ export type WorkerSettings = Omit<SettingEditParams, "account_id">;
10
+ /**
11
+ * One ES-module file of a Worker upload.
12
+ *
13
+ * **ES modules only.** `name` becomes both the multipart part name and the upload's `main_module`,
14
+ * and the part is sent as `application/javascript+module`. Classic service-worker scripts — the
15
+ * `body_part` shape, with a global `addEventListener("fetch", …)` — are not supported by this
16
+ * manager and never were: every upload it has ever sent set `main_module`. {@link
17
+ * CloudflareWorkersManager.createWorker} refuses a `body_part` in metadata rather than sending a
18
+ * request with both shapes half-declared.
19
+ */
20
+ export interface WorkerModule {
21
+ /** The module's filename, e.g. `index.js`. Becomes the part name and the upload's `main_module`. */
22
+ name: string;
23
+ /** The module's ES-module source, uploaded verbatim as `application/javascript+module`. */
24
+ body: string;
25
+ }
26
+ /**
27
+ * Out-of-Worker Workers access over the REST API: script create/list/delete, subdomain + settings,
28
+ * versions, deployments, secrets, and routes from a CLI/CI/provisioning context. Inside a Worker you
29
+ * manage scripts through wrangler/bindings; this manager is the REST counterpart, addressed by
30
+ * account (and zone, for routes).
31
+ */
32
+ export declare class CloudflareWorkersManager extends CloudflareManager {
33
+ /** List every Worker script on the account. */
34
+ listWorkers(): Promise<Script[]>;
35
+ /** Find a Worker script by name. Returns null when none matches. */
36
+ getWorker(scriptName: string): Promise<Script | null>;
37
+ /**
38
+ * Resolve a Worker's immutable `id` (the hex UUID) from the beta `/workers/workers` endpoint. CF
39
+ * Builds' `external_script_id` uses this immutable id, not the worker name. This is an explicit
40
+ * get: it throws `core/not_found` when no worker on the account carries the given name.
41
+ */
42
+ getWorkerInternalId(workerName: string): Promise<string>;
43
+ /**
44
+ * Create (upload) a Worker script. With no `module` the placeholder above is uploaded and the real
45
+ * build output replaces it via a later version upload; pass one to upload real source. `metadata`
46
+ * is merged into the upload's metadata — bindings, compatibility flags, tags — and this method
47
+ * fixes `main_module`.
48
+ *
49
+ * **`compatibilityDate` is required, and there is no default (#396).** This method used to supply
50
+ * `2026-04-07` when the caller named none, which is one date below the floor `compatibility.ts`
51
+ * holds every other Worker in this repository to, and the one date #388's gate could not reach —
52
+ * because it is TypeScript rather than a `wrangler.jsonc`, and the gate reads manifests.
53
+ *
54
+ * Moving it to the floor was the obvious answer and it is the wrong one. **A compatibility date is a
55
+ * behavior contract, not a version number** — it is the date workerd pretends it is — and this one
56
+ * lands on Workers in accounts that are not ours. Re-picking the number changes what an existing
57
+ * caller's Workers run, silently, for somebody who never asked; and the new number is stale on
58
+ * exactly the schedule the old one was, with the same gate unable to see it. `compatibility.ts` makes
59
+ * that argument about `2026-03-03` in as many words: *the minimum that fixes the last bug is exactly
60
+ * the number `2025-01-01` once was.*
61
+ *
62
+ * Requiring the date removes the class instead of re-picking the number, which is the move #377, #366
63
+ * and #394 each took. It is also the cheaper break: a caller who wanted `2026-04-07` writes
64
+ * `2026-04-07` and gets precisely what they had, and everyone else finds out at compile time rather
65
+ * than from a behavior change in production. `WorkersProvisioner` already promised this — *"it
66
+ * carries no environment- or product-specific defaults — every name, command, and env var is supplied
67
+ * by the caller"* — and the manager under it was the one place that was untrue.
68
+ *
69
+ * `metadata` may **not** also carry `compatibility_date`. Two ways to state one contract is a
70
+ * precedence rule to remember, and this method exists to have one statement rather than two.
71
+ *
72
+ * **The multipart request is built here rather than through `workers.scripts.update`, and that is
73
+ * a fix rather than a preference (#373).** The typed SDK's `update` pins
74
+ * `Content-Type: application/javascript` on the request and *then* lets its uploader turn the body
75
+ * into `FormData`. Cloudflare believes the header, parses the multipart envelope as a classic
76
+ * service-worker script, and rejects every upload with `10021 Uncaught SyntaxError: Invalid
77
+ * left-hand side expression in prefix operation at worker.js:1:4` — the leading `------WebKit…`
78
+ * boundary read as prefix `--` operators. Its form is wrong twice over besides: metadata is
79
+ * flattened to `metadata[main_module]` fields instead of one JSON part, and the module is appended
80
+ * as `files[]` rather than under the filename `main_module` names. So the form is assembled here
81
+ * and handed to the SDK's own `put`, which keeps auth, retries, timeout and error mapping intact.
82
+ */
83
+ createWorker(scriptName: string, compatibilityDate: string, metadata?: Record<string, unknown>, module?: WorkerModule): Promise<Script>;
84
+ /**
85
+ * Configure the workers.dev subdomain and preview URLs for a script. Both are controlled by the
86
+ * same endpoint — `previews_enabled` is always sent explicitly so CF does not default it to true.
87
+ */
88
+ setSubdomainSettings(scriptName: string, enabled: boolean, previewsEnabled?: boolean): Promise<void>;
89
+ /** Edit a Worker's settings (observability, logpush, tags, …). */
90
+ updateSettings(scriptName: string, settings: WorkerSettings): Promise<void>;
91
+ /** Delete a Worker script. */
92
+ deleteWorker(scriptName: string): Promise<void>;
93
+ /** List every version of a Worker script. */
94
+ listVersions(scriptName: string): Promise<VersionListResponse[]>;
95
+ /** Get one version of a Worker script. */
96
+ getVersion(scriptName: string, versionId: string): Promise<VersionGetResponse>;
97
+ /** List a Worker script's deployments. Empty when none exist. */
98
+ listDeployments(scriptName: string): Promise<Deployment[]>;
99
+ /** Get one deployment of a Worker script. */
100
+ getDeployment(scriptName: string, deploymentId: string): Promise<Deployment>;
101
+ /** Deploy a version to 100% of traffic for a Worker script. */
102
+ createDeployment(scriptName: string, versionId: string): Promise<Deployment>;
103
+ /** Set a secret on a Worker script. */
104
+ addSecret(scriptName: string, name: string, value: string): Promise<void>;
105
+ /** Delete a secret from a Worker script. */
106
+ deleteSecret(scriptName: string, secretName: string): Promise<void>;
107
+ /** List a Worker script's secrets. */
108
+ listSecrets(scriptName: string): Promise<SecretListResponse[]>;
109
+ /**
110
+ * Create a Workers Route on a zone, mapping a hostname pattern to a script. Idempotent: returns the
111
+ * existing route when one with the same pattern is already present on the zone.
112
+ */
113
+ addRoute(zoneId: string, pattern: string, scriptName: string): Promise<RouteCreateResponse | RouteListResponse>;
114
+ /** Find a Workers Route on a zone by its pattern. Returns null when none matches. */
115
+ getRoute(zoneId: string, pattern: string): Promise<RouteListResponse | null>;
116
+ /** Delete a Workers Route from a zone. */
117
+ removeRoute(zoneId: string, routeId: string): Promise<void>;
118
+ /** Resolve a queue's id (UUID) from its name. Returns null when no queue on the account matches. */
119
+ findQueueIdByName(queueName: string): Promise<string | null>;
120
+ /**
121
+ * Subscribe a queue to a Worker's Builds lifecycle events (started/succeeded/failed/canceled).
122
+ * Idempotent: a CF "already exists" conflict (405 "multiple subscriptions", or 409 "already
123
+ * exists") is treated as success rather than re-thrown.
124
+ */
125
+ subscribeBuildEvents(subscriptionName: string, queueId: string, workerName: string): Promise<void>;
126
+ /**
127
+ * The account's `workers.dev` subdomain, or `null` if none is registered. Deploying a Worker that
128
+ * hosts Workflows requires the account to have one (a one-time account bootstrap), so provisioning
129
+ * checks this up front. The CF API returns a 404-style error when absent; that maps to `null`.
130
+ */
131
+ accountSubdomain(): Promise<string | null>;
132
+ getServiceType(): string;
133
+ /** Prove access by listing the account's Workers. Never throws. */
134
+ validateServiceAccess(): Promise<boolean>;
135
+ }
136
+ //# sourceMappingURL=workersManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workersManager.d.ts","sourceRoot":"","sources":["../../src/workers/workersManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,312 @@
1
+ import { CloudflareInvalidResponseError, cloudflareRequest, messageOf } from "../client/errors.js";
2
+ import { CloudflareManager } from "../client/manager.js";
3
+ import { NotFoundError, ValidationError } from "@pithy-sh/core/src/error/pithyError";
4
+ //#region src/workers/workersManager.ts
5
+ /** Per-call SDK timeout + retry budget for Worker management operations. */
6
+ const requestOptions = {
7
+ timeout: 1e4,
8
+ maxRetries: 3
9
+ };
10
+ /**
11
+ * The placeholder module uploaded when a Worker script is first created. A Worker upload requires
12
+ * at least one module file plus `main_module` pointing at it; the real build output replaces this
13
+ * via a later version upload. This stub returns 503 while the worker is being provisioned.
14
+ */
15
+ const PLACEHOLDER_MODULE = "index.js";
16
+ const PLACEHOLDER_BODY = "export default { async fetch() { return new Response('Provisioning...', { status: 503 }); } };";
17
+ /**
18
+ * An ISO date, the only spelling a compatibility date has. Refused here so a typo is a `ValidationError`
19
+ * naming the argument rather than a 400 from Cloudflare naming the request.
20
+ */
21
+ const ISO_DATE = /^\d{4}-\d{2}-\d{2}$/;
22
+ /** The content type every module part carries. ES modules only — see {@link WorkerModule}. */
23
+ const MODULE_CONTENT_TYPE = "application/javascript+module";
24
+ /** The placeholder module `createWorker` uploads when the caller supplies none. */
25
+ const PLACEHOLDER = {
26
+ name: PLACEHOLDER_MODULE,
27
+ body: PLACEHOLDER_BODY
28
+ };
29
+ /**
30
+ * Out-of-Worker Workers access over the REST API: script create/list/delete, subdomain + settings,
31
+ * versions, deployments, secrets, and routes from a CLI/CI/provisioning context. Inside a Worker you
32
+ * manage scripts through wrangler/bindings; this manager is the REST counterpart, addressed by
33
+ * account (and zone, for routes).
34
+ */
35
+ var CloudflareWorkersManager = class extends CloudflareManager {
36
+ /** List every Worker script on the account. */
37
+ async listWorkers() {
38
+ return cloudflareRequest("list workers", async () => {
39
+ const scripts = [];
40
+ for await (const script of this.getClient().workers.scripts.list({ account_id: this.accountId })) scripts.push(script);
41
+ return scripts;
42
+ });
43
+ }
44
+ /** Find a Worker script by name. Returns null when none matches. */
45
+ async getWorker(scriptName) {
46
+ return (await this.listWorkers()).find((script) => script.id === scriptName) ?? null;
47
+ }
48
+ /**
49
+ * Resolve a Worker's immutable `id` (the hex UUID) from the beta `/workers/workers` endpoint. CF
50
+ * Builds' `external_script_id` uses this immutable id, not the worker name. This is an explicit
51
+ * get: it throws `core/not_found` when no worker on the account carries the given name.
52
+ */
53
+ async getWorkerInternalId(workerName) {
54
+ return cloudflareRequest(`get worker internal id for '${workerName}'`, async () => {
55
+ for await (const worker of this.getClient().workers.beta.workers.list({ account_id: this.accountId })) if (worker.name === workerName) return worker.id;
56
+ throw new NotFoundError({
57
+ message: `No Worker named '${workerName}' exists on the account.`,
58
+ detail: `Beta workers list returned no entry with name '${workerName}'.`
59
+ });
60
+ });
61
+ }
62
+ /**
63
+ * Create (upload) a Worker script. With no `module` the placeholder above is uploaded and the real
64
+ * build output replaces it via a later version upload; pass one to upload real source. `metadata`
65
+ * is merged into the upload's metadata — bindings, compatibility flags, tags — and this method
66
+ * fixes `main_module`.
67
+ *
68
+ * **`compatibilityDate` is required, and there is no default (#396).** This method used to supply
69
+ * `2026-04-07` when the caller named none, which is one date below the floor `compatibility.ts`
70
+ * holds every other Worker in this repository to, and the one date #388's gate could not reach —
71
+ * because it is TypeScript rather than a `wrangler.jsonc`, and the gate reads manifests.
72
+ *
73
+ * Moving it to the floor was the obvious answer and it is the wrong one. **A compatibility date is a
74
+ * behavior contract, not a version number** — it is the date workerd pretends it is — and this one
75
+ * lands on Workers in accounts that are not ours. Re-picking the number changes what an existing
76
+ * caller's Workers run, silently, for somebody who never asked; and the new number is stale on
77
+ * exactly the schedule the old one was, with the same gate unable to see it. `compatibility.ts` makes
78
+ * that argument about `2026-03-03` in as many words: *the minimum that fixes the last bug is exactly
79
+ * the number `2025-01-01` once was.*
80
+ *
81
+ * Requiring the date removes the class instead of re-picking the number, which is the move #377, #366
82
+ * and #394 each took. It is also the cheaper break: a caller who wanted `2026-04-07` writes
83
+ * `2026-04-07` and gets precisely what they had, and everyone else finds out at compile time rather
84
+ * than from a behavior change in production. `WorkersProvisioner` already promised this — *"it
85
+ * carries no environment- or product-specific defaults — every name, command, and env var is supplied
86
+ * by the caller"* — and the manager under it was the one place that was untrue.
87
+ *
88
+ * `metadata` may **not** also carry `compatibility_date`. Two ways to state one contract is a
89
+ * precedence rule to remember, and this method exists to have one statement rather than two.
90
+ *
91
+ * **The multipart request is built here rather than through `workers.scripts.update`, and that is
92
+ * a fix rather than a preference (#373).** The typed SDK's `update` pins
93
+ * `Content-Type: application/javascript` on the request and *then* lets its uploader turn the body
94
+ * into `FormData`. Cloudflare believes the header, parses the multipart envelope as a classic
95
+ * service-worker script, and rejects every upload with `10021 Uncaught SyntaxError: Invalid
96
+ * left-hand side expression in prefix operation at worker.js:1:4` — the leading `------WebKit…`
97
+ * boundary read as prefix `--` operators. Its form is wrong twice over besides: metadata is
98
+ * flattened to `metadata[main_module]` fields instead of one JSON part, and the module is appended
99
+ * as `files[]` rather than under the filename `main_module` names. So the form is assembled here
100
+ * and handed to the SDK's own `put`, which keeps auth, retries, timeout and error mapping intact.
101
+ */
102
+ async createWorker(scriptName, compatibilityDate, metadata = {}, module = PLACEHOLDER) {
103
+ if ("body_part" in metadata) throw new ValidationError({
104
+ message: "This client uploads ES-module Workers only.",
105
+ action: "Remove `body_part` from the metadata and pass the script as a module.",
106
+ detail: `createWorker('${scriptName}') was given a 'body_part', the classic service-worker shape. Every upload sets 'main_module'.`
107
+ });
108
+ if ("compatibility_date" in metadata) throw new ValidationError({
109
+ message: "A Worker's compatibility date is named once, as an argument.",
110
+ action: "Remove `compatibility_date` from the metadata and pass it as the second argument.",
111
+ detail: `createWorker('${scriptName}') was given a 'compatibility_date' in metadata as well as an argument. Two statements of one behavior contract is a precedence rule nobody should have to know.`
112
+ });
113
+ if (!ISO_DATE.test(compatibilityDate)) throw new ValidationError({
114
+ message: "A compatibility date is an ISO date, like 2026-06-01.",
115
+ action: "Pass the date as YYYY-MM-DD.",
116
+ detail: `createWorker('${scriptName}') was given the compatibility date '${compatibilityDate}'.`
117
+ });
118
+ const form = new FormData();
119
+ form.append("metadata", new Blob([JSON.stringify({
120
+ ...metadata,
121
+ compatibility_date: compatibilityDate,
122
+ main_module: module.name
123
+ })], { type: "application/json" }));
124
+ form.append(module.name, new Blob([module.body], { type: MODULE_CONTENT_TYPE }), module.name);
125
+ return cloudflareRequest(`create worker '${scriptName}'`, async () => {
126
+ const envelope = await this.getClient().put(`/accounts/${this.accountId}/workers/scripts/${scriptName}`, {
127
+ body: form,
128
+ ...requestOptions
129
+ });
130
+ if (!envelope.result) throw new CloudflareInvalidResponseError({
131
+ message: "Cloudflare accepted the Worker upload but returned no script.",
132
+ detail: `Upload of '${scriptName}' returned a success envelope with a null result.`
133
+ });
134
+ return envelope.result;
135
+ });
136
+ }
137
+ /**
138
+ * Configure the workers.dev subdomain and preview URLs for a script. Both are controlled by the
139
+ * same endpoint — `previews_enabled` is always sent explicitly so CF does not default it to true.
140
+ */
141
+ async setSubdomainSettings(scriptName, enabled, previewsEnabled = false) {
142
+ await cloudflareRequest(`set subdomain settings for '${scriptName}'`, () => this.getClient().workers.scripts.subdomain.create(scriptName, {
143
+ account_id: this.accountId,
144
+ enabled,
145
+ previews_enabled: previewsEnabled
146
+ }));
147
+ }
148
+ /** Edit a Worker's settings (observability, logpush, tags, …). */
149
+ async updateSettings(scriptName, settings) {
150
+ await cloudflareRequest(`update settings for '${scriptName}'`, () => this.getClient().workers.scripts.settings.edit(scriptName, {
151
+ account_id: this.accountId,
152
+ ...settings
153
+ }));
154
+ }
155
+ /** Delete a Worker script. */
156
+ async deleteWorker(scriptName) {
157
+ await cloudflareRequest(`delete worker '${scriptName}'`, () => this.getClient().workers.scripts.delete(scriptName, { account_id: this.accountId }, requestOptions));
158
+ }
159
+ /** List every version of a Worker script. */
160
+ async listVersions(scriptName) {
161
+ return cloudflareRequest(`list versions for '${scriptName}'`, async () => {
162
+ const versions = [];
163
+ for await (const version of this.getClient().workers.scripts.versions.list(scriptName, { account_id: this.accountId })) versions.push(version);
164
+ return versions;
165
+ });
166
+ }
167
+ /** Get one version of a Worker script. */
168
+ async getVersion(scriptName, versionId) {
169
+ return cloudflareRequest(`get version '${versionId}' for '${scriptName}'`, () => this.getClient().workers.scripts.versions.get(versionId, {
170
+ account_id: this.accountId,
171
+ script_name: scriptName
172
+ }, requestOptions));
173
+ }
174
+ /** List a Worker script's deployments. Empty when none exist. */
175
+ async listDeployments(scriptName) {
176
+ return cloudflareRequest(`list deployments for '${scriptName}'`, async () => {
177
+ return (await this.getClient().workers.scripts.deployments.list(scriptName, { account_id: this.accountId }, requestOptions)).deployments ?? [];
178
+ });
179
+ }
180
+ /** Get one deployment of a Worker script. */
181
+ async getDeployment(scriptName, deploymentId) {
182
+ return cloudflareRequest(`get deployment '${deploymentId}' for '${scriptName}'`, () => this.getClient().workers.scripts.deployments.get(deploymentId, {
183
+ account_id: this.accountId,
184
+ script_name: scriptName
185
+ }, requestOptions));
186
+ }
187
+ /** Deploy a version to 100% of traffic for a Worker script. */
188
+ async createDeployment(scriptName, versionId) {
189
+ return cloudflareRequest(`create deployment for '${scriptName}'`, () => this.getClient().workers.scripts.deployments.create(scriptName, {
190
+ account_id: this.accountId,
191
+ strategy: "percentage",
192
+ versions: [{
193
+ percentage: 100,
194
+ version_id: versionId
195
+ }]
196
+ }, requestOptions));
197
+ }
198
+ /** Set a secret on a Worker script. */
199
+ async addSecret(scriptName, name, value) {
200
+ await cloudflareRequest(`add secret '${name}' to '${scriptName}'`, () => this.getClient().workers.scripts.secrets.update(scriptName, {
201
+ account_id: this.accountId,
202
+ name,
203
+ text: value,
204
+ type: "secret_text"
205
+ }, requestOptions));
206
+ }
207
+ /** Delete a secret from a Worker script. */
208
+ async deleteSecret(scriptName, secretName) {
209
+ await cloudflareRequest(`delete secret '${secretName}' from '${scriptName}'`, () => this.getClient().workers.scripts.secrets.delete(secretName, {
210
+ account_id: this.accountId,
211
+ script_name: scriptName
212
+ }, requestOptions));
213
+ }
214
+ /** List a Worker script's secrets. */
215
+ async listSecrets(scriptName) {
216
+ return cloudflareRequest(`list secrets for '${scriptName}'`, async () => {
217
+ const secrets = [];
218
+ for await (const secret of this.getClient().workers.scripts.secrets.list(scriptName, { account_id: this.accountId })) secrets.push(secret);
219
+ return secrets;
220
+ });
221
+ }
222
+ /**
223
+ * Create a Workers Route on a zone, mapping a hostname pattern to a script. Idempotent: returns the
224
+ * existing route when one with the same pattern is already present on the zone.
225
+ */
226
+ async addRoute(zoneId, pattern, scriptName) {
227
+ const existing = await this.getRoute(zoneId, pattern);
228
+ if (existing) return existing;
229
+ return cloudflareRequest(`add worker route '${pattern}'`, () => this.getClient().workers.routes.create({
230
+ zone_id: zoneId,
231
+ pattern,
232
+ script: scriptName
233
+ }, requestOptions));
234
+ }
235
+ /** Find a Workers Route on a zone by its pattern. Returns null when none matches. */
236
+ async getRoute(zoneId, pattern) {
237
+ return cloudflareRequest(`get worker route '${pattern}'`, async () => {
238
+ for await (const route of this.getClient().workers.routes.list({ zone_id: zoneId })) if (route.pattern === pattern) return route;
239
+ return null;
240
+ });
241
+ }
242
+ /** Delete a Workers Route from a zone. */
243
+ async removeRoute(zoneId, routeId) {
244
+ await cloudflareRequest(`remove worker route '${routeId}'`, () => this.getClient().workers.routes.delete(routeId, { zone_id: zoneId }, requestOptions));
245
+ }
246
+ /** Resolve a queue's id (UUID) from its name. Returns null when no queue on the account matches. */
247
+ async findQueueIdByName(queueName) {
248
+ return cloudflareRequest(`find queue '${queueName}'`, async () => {
249
+ for await (const queue of this.getClient().queues.list({ account_id: this.accountId })) if (queue.queue_name === queueName) return queue.queue_id ?? null;
250
+ return null;
251
+ });
252
+ }
253
+ /**
254
+ * Subscribe a queue to a Worker's Builds lifecycle events (started/succeeded/failed/canceled).
255
+ * Idempotent: a CF "already exists" conflict (405 "multiple subscriptions", or 409 "already
256
+ * exists") is treated as success rather than re-thrown.
257
+ */
258
+ async subscribeBuildEvents(subscriptionName, queueId, workerName) {
259
+ await cloudflareRequest(`subscribe build events for '${workerName}'`, async () => {
260
+ try {
261
+ await this.getClient().queues.subscriptions.create({
262
+ account_id: this.accountId,
263
+ name: subscriptionName,
264
+ destination: {
265
+ type: "queues.queue",
266
+ queue_id: queueId
267
+ },
268
+ source: {
269
+ type: "workersBuilds.worker",
270
+ worker_name: workerName
271
+ },
272
+ events: [
273
+ "build.started",
274
+ "build.succeeded",
275
+ "build.failed",
276
+ "build.canceled"
277
+ ]
278
+ });
279
+ } catch (error) {
280
+ const message = messageOf(error);
281
+ if (/\b409\b/.test(message) || /already exists/i.test(message) || /multiple subscriptions/i.test(message)) return;
282
+ throw error;
283
+ }
284
+ });
285
+ }
286
+ /**
287
+ * The account's `workers.dev` subdomain, or `null` if none is registered. Deploying a Worker that
288
+ * hosts Workflows requires the account to have one (a one-time account bootstrap), so provisioning
289
+ * checks this up front. The CF API returns a 404-style error when absent; that maps to `null`.
290
+ */
291
+ async accountSubdomain() {
292
+ try {
293
+ return (await this.getClient().workers.subdomains.get({ account_id: this.accountId })).subdomain ?? null;
294
+ } catch {
295
+ return null;
296
+ }
297
+ }
298
+ getServiceType() {
299
+ return "Cloudflare Workers";
300
+ }
301
+ /** Prove access by listing the account's Workers. Never throws. */
302
+ async validateServiceAccess() {
303
+ try {
304
+ await this.getClient().workers.scripts.list({ account_id: this.accountId });
305
+ return true;
306
+ } catch {
307
+ return false;
308
+ }
309
+ }
310
+ };
311
+ //#endregion
312
+ export { CloudflareWorkersManager };
@@ -0,0 +1,80 @@
1
+ import type { CloudflareManagerConfig } from "../client/manager";
2
+ import type { CfRepoConnection, CfTriggerEnvVar } from "./buildsTypes";
3
+ /** Describes the git repo a build trigger should clone, in provider-neutral terms. */
4
+ export interface BuildRepo {
5
+ /** The git provider hosting the repo. */
6
+ providerType: "gitlab" | "github";
7
+ /** The repository's id in the git provider. */
8
+ repoId: string;
9
+ /** The repo path relative to the provider account. */
10
+ repoName: string;
11
+ /** The provider account identifier (e.g. 'group:15366484'). */
12
+ providerAccountId: string;
13
+ /** The provider account display name. */
14
+ providerAccountName: string;
15
+ }
16
+ /** Everything `setupBuildTrigger` needs, all caller-supplied — no environment-specific defaults. */
17
+ export interface BuildTriggerSetup {
18
+ /** The Worker the trigger builds, by name (resolved to its immutable id internally). */
19
+ workerName: string;
20
+ /** The repo to clone. */
21
+ repo: BuildRepo;
22
+ /** The build token UUID the trigger authenticates with. */
23
+ buildTokenUuid: string;
24
+ /** The trigger's human-readable name. */
25
+ triggerName: string;
26
+ /** Branch patterns that auto-fire the trigger (must be non-empty). */
27
+ branchIncludes: string[];
28
+ /** The shell command that builds the Worker. */
29
+ buildCommand: string;
30
+ /** The shell command CF Builds runs to deploy after a build. */
31
+ deployCommand: string;
32
+ /** Environment variables to set on the trigger. */
33
+ envVars?: CfTriggerEnvVar[];
34
+ }
35
+ /**
36
+ * Provisions Cloudflare Workers infrastructure over the REST API: create a Worker, set its secrets,
37
+ * wire a CF Builds trigger to a repo, register a Workers Route, and subscribe a queue to build
38
+ * events. A thin orchestrator over `CloudflareWorkersManager` + `CloudflareBuildsManager`.
39
+ *
40
+ * Each method is a discrete, idempotent step so a caller (e.g. a Workflow) can resume from the point
41
+ * of failure rather than from scratch. It carries no environment- or product-specific defaults —
42
+ * every name, command, and env var is supplied by the caller.
43
+ */
44
+ export declare class WorkersProvisioner {
45
+ private readonly workers;
46
+ private readonly builds;
47
+ constructor(config: CloudflareManagerConfig);
48
+ /**
49
+ * Create the Worker script, enable its workers.dev subdomain, and turn on observability. Returns
50
+ * the created script's id. workers.dev must be enabled via a separate call after script creation.
51
+ *
52
+ * `compatibilityDate` is passed through and not defaulted, which is this class's standing promise
53
+ * one level down: a compatibility date is a behavior contract in the caller's own account, and the
54
+ * manager stopped inventing one in #396.
55
+ */
56
+ createWorker(workerName: string, compatibilityDate: string, metadata?: Record<string, unknown>): Promise<string>;
57
+ /** Resolve the immutable hex id ("external_script_id") for a worker, stable across renames. */
58
+ getWorkerInternalId(workerName: string): Promise<string>;
59
+ /** Set a secret on a worker. */
60
+ addWorkerSecret(workerName: string, key: string, value: string): Promise<void>;
61
+ /**
62
+ * Create the CF Builds repo connection + trigger and set its env vars, returning the trigger UUID.
63
+ * Idempotent — `createRepoConnection` is CF's upsert and `upsertTrigger` reconciles an existing
64
+ * trigger. The trigger is keyed on the worker's immutable internal id (resolved here), not its name.
65
+ */
66
+ setupBuildTrigger(setup: BuildTriggerSetup): Promise<string>;
67
+ /** Create (or upsert) only the repo connection. Useful when a caller manages the trigger itself. */
68
+ setupRepoConnection(repo: BuildRepo): Promise<CfRepoConnection>;
69
+ /**
70
+ * Register a Workers Route on a zone mapping `${hostname}/*` to the worker. Idempotent. Returns the
71
+ * route id (empty string when CF returns a route without one).
72
+ */
73
+ setupWorkerRoute(zoneId: string, workerName: string, hostname: string): Promise<string>;
74
+ /**
75
+ * Subscribe a named queue to the worker's Builds lifecycle events. Resolves the queue's id from its
76
+ * name first; throws `cloudflare/not_configured` when the queue does not exist. Idempotent.
77
+ */
78
+ setupBuildEventSubscription(workerName: string, queueName: string): Promise<void>;
79
+ }
80
+ //# sourceMappingURL=workersProvisioner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workersProvisioner.d.ts","sourceRoot":"","sources":["../../src/workers/workersProvisioner.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAEjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGvE,sFAAsF;AACtF,MAAM,WAAW,SAAS;IACxB,yCAAyC;IACzC,YAAY,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAClC,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,QAAQ,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,iBAAiB,EAAE,MAAM,CAAC;IAC1B,yCAAyC;IACzC,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,oGAAoG;AACpG,MAAM,WAAW,iBAAiB;IAChC,wFAAwF;IACxF,UAAU,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,IAAI,EAAE,SAAS,CAAC;IAChB,2DAA2D;IAC3D,cAAc,EAAE,MAAM,CAAC;IACvB,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,gDAAgD;IAChD,YAAY,EAAE,MAAM,CAAC;IACrB,gEAAgE;IAChE,aAAa,EAAE,MAAM,CAAC;IACtB,mDAAmD;IACnD,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED;;;;;;;;GAQG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IAEnD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;IAEjD,YAAY,MAAM,EAAE,uBAAuB,EAG1C;IAED;;;;;;;OAOG;IACG,YAAY,CAChB,UAAU,EAAE,MAAM,EAClB,iBAAiB,EAAE,MAAM,EACzB,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACrC,OAAO,CAAC,MAAM,CAAC,CAWjB;IAED,+FAA+F;IACzF,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE7D;IAED,gCAAgC;IAC1B,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEnF;IAED;;;;OAIG;IACG,iBAAiB,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CA2BjE;IAED,oGAAoG;IAC9F,mBAAmB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAQpE;IAED;;;OAGG;IACG,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAG5F;IAED;;;OAGG;IACG,2BAA2B,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUtF;CACF"}
@@ -0,0 +1,106 @@
1
+ import { CloudflareNotConfiguredError } from "../client/errors.js";
2
+ import { CloudflareBuildsManager } from "./buildsManager.js";
3
+ import { CloudflareWorkersManager } from "./workersManager.js";
4
+ //#region src/workers/workersProvisioner.ts
5
+ /**
6
+ * Provisions Cloudflare Workers infrastructure over the REST API: create a Worker, set its secrets,
7
+ * wire a CF Builds trigger to a repo, register a Workers Route, and subscribe a queue to build
8
+ * events. A thin orchestrator over `CloudflareWorkersManager` + `CloudflareBuildsManager`.
9
+ *
10
+ * Each method is a discrete, idempotent step so a caller (e.g. a Workflow) can resume from the point
11
+ * of failure rather than from scratch. It carries no environment- or product-specific defaults —
12
+ * every name, command, and env var is supplied by the caller.
13
+ */
14
+ var WorkersProvisioner = class {
15
+ workers;
16
+ builds;
17
+ constructor(config) {
18
+ this.workers = new CloudflareWorkersManager(config);
19
+ this.builds = new CloudflareBuildsManager(config);
20
+ }
21
+ /**
22
+ * Create the Worker script, enable its workers.dev subdomain, and turn on observability. Returns
23
+ * the created script's id. workers.dev must be enabled via a separate call after script creation.
24
+ *
25
+ * `compatibilityDate` is passed through and not defaulted, which is this class's standing promise
26
+ * one level down: a compatibility date is a behavior contract in the caller's own account, and the
27
+ * manager stopped inventing one in #396.
28
+ */
29
+ async createWorker(workerName, compatibilityDate, metadata = {}) {
30
+ const script = await this.workers.createWorker(workerName, compatibilityDate, metadata);
31
+ if (!script.id) throw new CloudflareNotConfiguredError({
32
+ message: `Worker '${workerName}' was created but returned no script id.`,
33
+ detail: "The Worker upload returned a script with no id."
34
+ });
35
+ await this.workers.setSubdomainSettings(workerName, true, false);
36
+ await this.workers.updateSettings(workerName, { observability: { enabled: true } });
37
+ return script.id;
38
+ }
39
+ /** Resolve the immutable hex id ("external_script_id") for a worker, stable across renames. */
40
+ async getWorkerInternalId(workerName) {
41
+ return this.workers.getWorkerInternalId(workerName);
42
+ }
43
+ /** Set a secret on a worker. */
44
+ async addWorkerSecret(workerName, key, value) {
45
+ await this.workers.addSecret(workerName, key, value);
46
+ }
47
+ /**
48
+ * Create the CF Builds repo connection + trigger and set its env vars, returning the trigger UUID.
49
+ * Idempotent — `createRepoConnection` is CF's upsert and `upsertTrigger` reconciles an existing
50
+ * trigger. The trigger is keyed on the worker's immutable internal id (resolved here), not its name.
51
+ */
52
+ async setupBuildTrigger(setup) {
53
+ const repoConnection = await this.builds.createRepoConnection({
54
+ providerType: setup.repo.providerType,
55
+ repoId: setup.repo.repoId,
56
+ repoName: setup.repo.repoName,
57
+ providerAccountId: setup.repo.providerAccountId,
58
+ providerAccountName: setup.repo.providerAccountName
59
+ });
60
+ const externalScriptId = await this.workers.getWorkerInternalId(setup.workerName);
61
+ const trigger = await this.builds.upsertTrigger({
62
+ scriptName: externalScriptId,
63
+ repoConnectionId: repoConnection.repo_connection_uuid,
64
+ buildTokenUuid: setup.buildTokenUuid,
65
+ triggerName: setup.triggerName,
66
+ branchIncludes: setup.branchIncludes,
67
+ pathIncludes: ["*"],
68
+ buildCommand: setup.buildCommand,
69
+ deployCommand: setup.deployCommand
70
+ });
71
+ if (setup.envVars && setup.envVars.length > 0) await this.builds.upsertTriggerEnvVars(trigger.trigger_uuid, setup.envVars);
72
+ return trigger.trigger_uuid;
73
+ }
74
+ /** Create (or upsert) only the repo connection. Useful when a caller manages the trigger itself. */
75
+ async setupRepoConnection(repo) {
76
+ return this.builds.createRepoConnection({
77
+ providerType: repo.providerType,
78
+ repoId: repo.repoId,
79
+ repoName: repo.repoName,
80
+ providerAccountId: repo.providerAccountId,
81
+ providerAccountName: repo.providerAccountName
82
+ });
83
+ }
84
+ /**
85
+ * Register a Workers Route on a zone mapping `${hostname}/*` to the worker. Idempotent. Returns the
86
+ * route id (empty string when CF returns a route without one).
87
+ */
88
+ async setupWorkerRoute(zoneId, workerName, hostname) {
89
+ return (await this.workers.addRoute(zoneId, `${hostname}/*`, workerName)).id ?? "";
90
+ }
91
+ /**
92
+ * Subscribe a named queue to the worker's Builds lifecycle events. Resolves the queue's id from its
93
+ * name first; throws `cloudflare/not_configured` when the queue does not exist. Idempotent.
94
+ */
95
+ async setupBuildEventSubscription(workerName, queueName) {
96
+ const queueId = await this.workers.findQueueIdByName(queueName);
97
+ if (!queueId) throw new CloudflareNotConfiguredError({
98
+ message: `Queue '${queueName}' was not found on the account.`,
99
+ action: "Create the queue before provisioning build event subscriptions.",
100
+ detail: `No queue named '${queueName}' on the account.`
101
+ });
102
+ await this.workers.subscribeBuildEvents(`build-events-${workerName}`, queueId, workerName);
103
+ }
104
+ };
105
+ //#endregion
106
+ export { WorkersProvisioner };