hatchkit 0.1.23 → 0.1.25

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.
@@ -0,0 +1,428 @@
1
+ /*
2
+ * S3/R2 bucket provisioning for adopted projects.
3
+ *
4
+ * Closes the gap between `hatchkit config add s3 r2` (which only stores
5
+ * credentials in the global config + keychain) and a project that
6
+ * actually needs working buckets + env wiring at runtime. Splits the
7
+ * provisioning into two clear roles:
8
+ *
9
+ * · "assets" — public, hot path. Fronts large pre-built media
10
+ * (AVIF/WebP/originals). Public URL goes into a
11
+ * NEXT_PUBLIC_ASSETS_BASE_URL-style env var so the
12
+ * client can fetch directly.
13
+ * · "state" — private, cold. Used for small server-side files
14
+ * (cron state, audit logs). Never publicly reachable.
15
+ *
16
+ * Public URL strategy for the assets bucket, in order:
17
+ * 1. Custom domain on a Cloudflare zone the user owns
18
+ * (`assets.<project-domain>` or a caller-provided override) —
19
+ * preferred long-term, no `r2.dev` rate limits.
20
+ * 2. Managed `pub-<hash>.r2.dev` domain — fallback when no zone
21
+ * matches the project's domain.
22
+ *
23
+ * Env var names are project-specific. Some projects standardised on
24
+ * R2_*; others on the generic S3_* / AWS_* set the starter ships. We
25
+ * sniff the project's `.env.example` for whichever prefix the runtime
26
+ * already reads, so the seeded values match. Without this the env
27
+ * lands under names the app's `process.env.X` calls won't pick up.
28
+ *
29
+ * Idempotent on every step: existing buckets are reused (409 →
30
+ * success), existing managed/custom domains are re-fetched, and env
31
+ * vars overwrite in place (so re-runs after a failure don't duplicate
32
+ * lines or leave the file half-written).
33
+ */
34
+ import { existsSync, readFileSync } from "node:fs";
35
+ import { join } from "node:path";
36
+ import { set as dotenvxSet } from "@dotenvx/dotenvx";
37
+ import chalk from "chalk";
38
+ import ora from "ora";
39
+ import { getDnsConfig } from "../config.js";
40
+ import { MANIFEST_FILENAME, readManifest, writeManifest, } from "../scaffold/manifest.js";
41
+ import { CloudflareApi } from "../utils/cloudflare-api.js";
42
+ import { SECRET_KEYS, getSecret, setSecret } from "../utils/secrets.js";
43
+ /** Account ID = the subdomain in the S3 endpoint
44
+ * `https://<accountId>.r2.cloudflarestorage.com`. */
45
+ export function accountIdFromR2Endpoint(endpoint) {
46
+ const m = endpoint.match(/https?:\/\/([0-9a-f]{32})\.r2\.cloudflarestorage\.com/i);
47
+ if (!m)
48
+ throw new Error(`Endpoint ${endpoint} doesn't look like an R2 S3 endpoint.`);
49
+ return m[1];
50
+ }
51
+ /** Sniff the project's `.env.example` (and falling back to source files)
52
+ * to pick the env-var prefix the runtime already reads. Some projects
53
+ * use R2_*, others S3_*, others AWS_*. Picking the wrong prefix here
54
+ * is the difference between "deploys" and "deploys but every request
55
+ * throws Missing required env var". */
56
+ export function detectEnvPrefix(projectDir) {
57
+ const candidates = [
58
+ join(projectDir, ".env.example"),
59
+ join(projectDir, ".env.development"),
60
+ join(projectDir, ".env.production"),
61
+ ];
62
+ let r2 = 0;
63
+ let s3 = 0;
64
+ let aws = 0;
65
+ for (const p of candidates) {
66
+ if (!existsSync(p))
67
+ continue;
68
+ const text = readFileSync(p, "utf-8");
69
+ r2 += (text.match(/(^|\s)R2_[A-Z_]+\s*=/gm) ?? []).length;
70
+ s3 += (text.match(/(^|\s)S3_[A-Z_]+\s*=/gm) ?? []).length;
71
+ aws += (text.match(/(^|\s)AWS_(REGION|ACCESS_KEY_ID|SECRET_ACCESS_KEY)\s*=/gm) ?? []).length;
72
+ }
73
+ // Highest wins; ties prefer R2 (most explicit) > S3 > AWS.
74
+ const pairs = [
75
+ ["R2", r2],
76
+ ["S3", s3],
77
+ ["AWS", aws],
78
+ ];
79
+ pairs.sort((a, b) => b[1] - a[1]);
80
+ if (pairs[0][1] === 0)
81
+ return "S3"; // nothing detected — match starter default
82
+ return pairs[0][0];
83
+ }
84
+ /** Map the detected prefix to the full set of env var names. R2 and S3
85
+ * use distinct endpoint/bucket names but share the access-key shape;
86
+ * AWS uses the AWS_* triple instead of S3_*. */
87
+ export function envKeysForPrefix(prefix) {
88
+ if (prefix === "R2") {
89
+ return {
90
+ endpoint: "R2_ENDPOINT",
91
+ accessKey: "R2_ACCESS_KEY_ID",
92
+ secretKey: "R2_SECRET_ACCESS_KEY",
93
+ region: "R2_REGION",
94
+ bucket: "R2_STATE_BUCKET",
95
+ publicUrl: "NEXT_PUBLIC_ASSETS_BASE_URL",
96
+ };
97
+ }
98
+ if (prefix === "AWS") {
99
+ return {
100
+ endpoint: "S3_ENDPOINT",
101
+ accessKey: "AWS_ACCESS_KEY_ID",
102
+ secretKey: "AWS_SECRET_ACCESS_KEY",
103
+ region: "AWS_REGION",
104
+ bucket: "S3_BUCKET_NAME",
105
+ publicUrl: "S3_PUBLIC_URL",
106
+ };
107
+ }
108
+ return {
109
+ endpoint: "S3_ENDPOINT",
110
+ accessKey: "S3_ACCESS_KEY_ID",
111
+ secretKey: "S3_SECRET_ACCESS_KEY",
112
+ region: "S3_REGION",
113
+ bucket: "S3_BUCKET_NAME",
114
+ publicUrl: "S3_PUBLIC_URL",
115
+ };
116
+ }
117
+ /** Read existing keys in `.env.production` so re-runs don't clobber a
118
+ * value the user has since edited. Returns the set of plain or
119
+ * encrypted KEYs present (we don't try to decrypt — encrypted values
120
+ * always have a `KEY="encrypted:..."` shape). */
121
+ function existingEnvKeys(envPath) {
122
+ if (!existsSync(envPath))
123
+ return new Set();
124
+ const text = readFileSync(envPath, "utf-8");
125
+ const keys = new Set();
126
+ for (const line of text.split("\n")) {
127
+ const m = line.match(/^([A-Z][A-Z0-9_]*)=/);
128
+ if (m)
129
+ keys.add(m[1]);
130
+ }
131
+ return keys;
132
+ }
133
+ /** Build the rclone config snippet the user can paste into
134
+ * `~/.config/rclone/rclone.conf`. Keeps this OUT of the file system
135
+ * (the user's existing rclone config has other remotes — we don't
136
+ * want to mangle them). */
137
+ function buildRcloneSnippet(opts) {
138
+ return [
139
+ `[${opts.remoteName}]`,
140
+ `type = s3`,
141
+ `provider = Cloudflare`,
142
+ `access_key_id = ${opts.accessKey}`,
143
+ `secret_access_key = ${opts.secretKey}`,
144
+ `endpoint = ${opts.endpoint}`,
145
+ `acl = private`,
146
+ `no_check_bucket = true`,
147
+ "",
148
+ ].join("\n");
149
+ }
150
+ /** Provision the public+private bucket pair for an adopted project,
151
+ * wire the resulting credentials/URLs into its `.env.production`, and
152
+ * record the bucket names in `.hatchkit.json`. Idempotent on re-run. */
153
+ export async function provisionS3ForProject(opts) {
154
+ const provider = opts.provider ?? "r2";
155
+ const manifest = readManifest(opts.projectDir);
156
+ if (!manifest) {
157
+ throw new Error(`No ${MANIFEST_FILENAME} in ${opts.projectDir}. Run \`hatchkit adopt\` first.`);
158
+ }
159
+ // Provider metadata (endpoint + region). Read from the Conf JSON
160
+ // store directly so we don't require the legacy account-wide
161
+ // access/secret pair to exist — the new model issues per-project
162
+ // creds at provision-time, the global pair is no longer the source
163
+ // of truth for runtime S3 ops.
164
+ if (provider !== "r2") {
165
+ throw new Error(`Bucket auto-provisioning is only implemented for R2 today (got ${provider}). PRs welcome.`);
166
+ }
167
+ const { getStore } = await import("../config.js");
168
+ const meta = getStore().get(`providers.s3.${provider}`);
169
+ if (!meta || meta.status !== "configured" || !meta.endpoint) {
170
+ throw new Error(`S3 provider "${provider}" is not configured. Run \`hatchkit config add s3\` and pick ${provider}.`);
171
+ }
172
+ const accountId = accountIdFromR2Endpoint(meta.endpoint);
173
+ // DNS config — needed only when we're about to attempt a custom
174
+ // domain. Absence is fine; we fall back to the managed r2.dev URL.
175
+ const dns = await getDnsConfig();
176
+ // R2 admin token. Kept separate from the DNS token because the DNS
177
+ // token is typically scoped narrowly (Zone:DNS:Edit + Zone:Zone:Read)
178
+ // and the R2 admin endpoints need account-level perms. Caller
179
+ // (handleProvisionS3) is responsible for prompting + storing this
180
+ // when missing — this function fails fast so non-interactive callers
181
+ // (adopt's auto-step) get a clear hint instead of an opaque 10000.
182
+ const adminToken = await getSecret(SECRET_KEYS.r2AdminToken);
183
+ if (!adminToken) {
184
+ throw new Error("R2 admin token not configured. Run `hatchkit provision s3` interactively, " +
185
+ "or pre-set with: hatchkit config add s3 (TODO) — needs Account > Workers R2 Storage > Edit.");
186
+ }
187
+ // For the zone lookup (custom-domain attach) we need the DNS token's
188
+ // Zone:Zone:Read; the admin token may or may not have it. Use whichever
189
+ // we have available, preferring the DNS token because that's the one
190
+ // that's been verified for zone reads in `hatchkit doctor`.
191
+ const zoneToken = dns?.provider === "cloudflare" ? (dns.apiToken ?? adminToken) : adminToken;
192
+ const cf = new CloudflareApi({ token: adminToken });
193
+ const cfZone = new CloudflareApi({ token: zoneToken });
194
+ const projectName = manifest.name;
195
+ const domain = manifest.domain;
196
+ const assetsBucketName = opts.assetsBucketName ?? `${projectName}-assets`;
197
+ const stateBucketName = opts.stateBucketName ?? `${projectName}-state`;
198
+ const locationHint = opts.locationHint ?? "weur";
199
+ // 1. Create the two buckets (idempotent).
200
+ const spinner = ora(`Creating R2 buckets (${assetsBucketName}, ${stateBucketName})`).start();
201
+ let assetsBucket;
202
+ let stateBucket;
203
+ try {
204
+ assetsBucket = await cf.createR2Bucket(accountId, assetsBucketName, { locationHint });
205
+ stateBucket = await cf.createR2Bucket(accountId, stateBucketName, { locationHint });
206
+ spinner.succeed(`R2 buckets ready — ${assetsBucketName} (${assetsBucket.existed ? "exists" : "created"}), ${stateBucketName} (${stateBucket.existed ? "exists" : "created"})`);
207
+ }
208
+ catch (err) {
209
+ spinner.fail("R2 bucket creation failed");
210
+ const msg = err.message;
211
+ if (/403|10001|permission/i.test(msg)) {
212
+ throw new Error(`${msg}\n\n → Cloudflare token is missing the "Workers R2 Storage: Edit" permission.\n → Edit it at https://dash.cloudflare.com/profile/api-tokens, then re-run.`);
213
+ }
214
+ throw err;
215
+ }
216
+ // 2. Public URL for the assets bucket. Prefer a custom domain on a
217
+ // Cloudflare zone we own; fall back to the managed r2.dev URL.
218
+ let publicUrl;
219
+ let publicUrlSource;
220
+ // Pick the hostname. Default `assets.<domain>`; allow caller override.
221
+ const customHostname = opts.publicHostname ?? `assets.${domain}`;
222
+ // Find the closest matching zone (the registrable name — last
223
+ // two labels of the host, or the host itself if the user passed a
224
+ // bare apex).
225
+ const zoneName = pickClosestZoneName(customHostname);
226
+ try {
227
+ const zone = await cfZone.getZoneByName(zoneName);
228
+ if (zone) {
229
+ const customSpinner = ora(`Attaching custom domain ${customHostname}`).start();
230
+ try {
231
+ const cd = await cf.addR2CustomDomain(accountId, assetsBucketName, {
232
+ domain: customHostname,
233
+ zoneId: zone.id,
234
+ minTLS: "1.2",
235
+ });
236
+ publicUrl = `https://${cd.domain}`;
237
+ publicUrlSource = "custom-domain";
238
+ customSpinner.succeed(`Custom domain ${cd.existed ? "already attached" : "attached"} — ${publicUrl}`);
239
+ }
240
+ catch (err) {
241
+ customSpinner.warn(`Custom domain failed (${err.message.split("\n")[0]}) — falling back to r2.dev managed URL`);
242
+ }
243
+ }
244
+ }
245
+ catch (err) {
246
+ // Zone lookup is best-effort. Don't fail the whole flow on it.
247
+ console.log(chalk.dim(` · Zone lookup for ${zoneName} failed: ${err.message.split("\n")[0]}`));
248
+ }
249
+ if (!publicUrl) {
250
+ const managedSpinner = ora(`Enabling managed r2.dev URL on ${assetsBucketName}`).start();
251
+ try {
252
+ const md = await cf.enableR2ManagedDomain(accountId, assetsBucketName, true);
253
+ publicUrl = `https://${md.domain}`;
254
+ publicUrlSource = "managed-r2dev";
255
+ managedSpinner.succeed(`Managed r2.dev URL enabled — ${publicUrl}`);
256
+ }
257
+ catch (err) {
258
+ managedSpinner.fail("Could not enable a public URL on the assets bucket");
259
+ throw err;
260
+ }
261
+ }
262
+ // 3. Mint a per-project R2 API token scoped to just these two
263
+ // buckets. Returns the S3-style access/secret pair (access =
264
+ // token id, secret = sha256(token value)). Re-mint on every
265
+ // re-run — keychain holds the canonical copy and idempotency
266
+ // on the CF side is good enough that the worst case is a few
267
+ // orphaned old tokens (cleaned up by `hatchkit destroy`).
268
+ //
269
+ // If a token already exists in keychain for this project, REUSE
270
+ // it instead of re-minting. This keeps `hatchkit provision s3`
271
+ // idempotent w/r/t the user's CF account (no token churn) and
272
+ // means rotating credentials is an explicit `--rotate` step
273
+ // rather than a side effect.
274
+ const existingProjectAccess = await getSecret(SECRET_KEYS.s3ProjectAccessKey(provider, projectName));
275
+ const existingProjectSecret = await getSecret(SECRET_KEYS.s3ProjectSecretKey(provider, projectName));
276
+ let projectAccessKey;
277
+ let projectSecretKey;
278
+ let projectTokenId;
279
+ if (existingProjectAccess && existingProjectSecret) {
280
+ projectAccessKey = existingProjectAccess;
281
+ projectSecretKey = existingProjectSecret;
282
+ projectTokenId =
283
+ (await getSecret(SECRET_KEYS.s3ProjectTokenId(provider, projectName))) ?? undefined;
284
+ console.log(chalk.dim(` · Reusing existing per-project R2 credentials (keychain ${SECRET_KEYS.s3ProjectAccessKey(provider, projectName)})`));
285
+ }
286
+ else {
287
+ const tokenSpinner = ora(`Minting per-project R2 API token (scoped to those 2 buckets)`).start();
288
+ try {
289
+ const minted = await cf.createR2ApiToken({
290
+ accountId,
291
+ name: `hatchkit-${projectName}`,
292
+ bucketNames: [assetsBucketName, stateBucketName],
293
+ permissions: "read-write",
294
+ });
295
+ projectAccessKey = minted.accessKeyId;
296
+ projectSecretKey = minted.secretAccessKey;
297
+ projectTokenId = minted.tokenId;
298
+ await setSecret(SECRET_KEYS.s3ProjectAccessKey(provider, projectName), minted.accessKeyId);
299
+ await setSecret(SECRET_KEYS.s3ProjectSecretKey(provider, projectName), minted.secretAccessKey);
300
+ await setSecret(SECRET_KEYS.s3ProjectTokenId(provider, projectName), minted.tokenId);
301
+ tokenSpinner.succeed(`Minted scoped R2 API token (id ${minted.tokenId.slice(0, 8)}…, stored in keychain)`);
302
+ }
303
+ catch (err) {
304
+ tokenSpinner.fail("Failed to mint per-project R2 API token");
305
+ const msg = err.message;
306
+ if (/9109|10000|403|invalid api token/i.test(msg)) {
307
+ throw new Error(`${msg}\n\n → Your admin token (s3:r2:admin-token) needs BOTH:\n · Account > Workers R2 Storage > Edit\n · User > API Tokens > Edit (this is what's missing)\n → Edit at https://dash.cloudflare.com/profile/api-tokens, save, re-run.`);
308
+ }
309
+ throw err;
310
+ }
311
+ }
312
+ // 4. Seed `.env.production` with the credentials + URLs. Names are
313
+ // chosen by the prefix the project's runtime actually reads —
314
+ // detected from `.env.example` etc.
315
+ const envPrefix = opts.envPrefix ?? detectEnvPrefix(opts.projectDir);
316
+ const keys = envKeysForPrefix(envPrefix);
317
+ const envPath = join(opts.projectDir, ".env.production");
318
+ const existingKeys = existingEnvKeys(envPath);
319
+ const toWrite = [];
320
+ const skip = (key) => existingKeys.has(key);
321
+ // ENDPOINT, ACCESS_KEY, SECRET_KEY, REGION are credentials that
322
+ // the runtime always needs. Re-write on every run (cheap, and the
323
+ // user might've rotated keys). REGION is "auto" for R2 — the SDK
324
+ // ignores it anyway when an explicit endpoint is given, but
325
+ // setting it suppresses an `AWS_REGION` warning at runtime.
326
+ toWrite.push({ key: keys.endpoint, value: meta.endpoint });
327
+ toWrite.push({ key: keys.accessKey, value: projectAccessKey });
328
+ toWrite.push({ key: keys.secretKey, value: projectSecretKey });
329
+ toWrite.push({ key: keys.region, value: meta.region ?? "auto" });
330
+ // BUCKET name — keys.bucket is "<PREFIX>_STATE_BUCKET" for R2 (the
331
+ // private bucket is the only one a server lib reads through env;
332
+ // assets are URL-driven). For S3/AWS prefixes the canonical key is
333
+ // <PREFIX>_BUCKET_NAME pointing at the assets bucket. Match the
334
+ // semantics of each prefix.
335
+ if (envPrefix === "R2") {
336
+ toWrite.push({ key: keys.bucket, value: stateBucketName });
337
+ }
338
+ else {
339
+ toWrite.push({ key: keys.bucket, value: assetsBucketName });
340
+ }
341
+ // Public URL — only seed if the project's runtime reads the
342
+ // matching key. Detected via `.env.example` keys for both the
343
+ // primary (`NEXT_PUBLIC_ASSETS_BASE_URL`) and the prefixed fallback.
344
+ // Always write it under NEXT_PUBLIC_ASSETS_BASE_URL when present in
345
+ // .env.example since that's the next.js convention; under
346
+ // <PREFIX>_PUBLIC_URL for non-Next projects.
347
+ const examplePath = join(opts.projectDir, ".env.example");
348
+ const exampleText = existsSync(examplePath) ? readFileSync(examplePath, "utf-8") : "";
349
+ const usesNextPublicAssets = /NEXT_PUBLIC_ASSETS_BASE_URL/.test(exampleText);
350
+ if (usesNextPublicAssets) {
351
+ toWrite.push({ key: "NEXT_PUBLIC_ASSETS_BASE_URL", value: publicUrl });
352
+ }
353
+ else if (envPrefix === "S3" || envPrefix === "AWS") {
354
+ toWrite.push({ key: keys.publicUrl, value: publicUrl });
355
+ }
356
+ // CRON_SECRET — the project's .env.example documents one if it has
357
+ // a cron route. Generate fresh, encrypt. Skip if already set.
358
+ if (opts.generateCronSecret !== false &&
359
+ /CRON_SECRET/.test(exampleText) &&
360
+ !skip("CRON_SECRET")) {
361
+ const { randomBytes } = await import("node:crypto");
362
+ toWrite.push({ key: "CRON_SECRET", value: randomBytes(32).toString("hex") });
363
+ }
364
+ const envWritten = [];
365
+ const envKept = [];
366
+ const envSpinner = ora(`Writing ${toWrite.length} entries to .env.production`).start();
367
+ try {
368
+ for (const { key, value } of toWrite) {
369
+ // Idempotency: re-write everything except CRON_SECRET (treated
370
+ // above) on every run. dotenvx.set overwrites in place, so
371
+ // values stay singletons in the file.
372
+ if (key === "CRON_SECRET" && skip(key)) {
373
+ envKept.push(key);
374
+ continue;
375
+ }
376
+ dotenvxSet(key, value, { path: envPath, encrypt: true });
377
+ envWritten.push(key);
378
+ }
379
+ envSpinner.succeed(`Wrote ${envWritten.length} encrypted entries to .env.production`);
380
+ }
381
+ catch (err) {
382
+ envSpinner.fail("Could not write .env.production");
383
+ throw err;
384
+ }
385
+ // 4. Record bucket names + public URL in the manifest so re-runs
386
+ // don't have to re-derive them and a future `hatchkit destroy`
387
+ // knows what to clean up.
388
+ const updated = {
389
+ ...manifest,
390
+ s3Buckets: {
391
+ assets: { name: assetsBucketName, publicUrl },
392
+ state: { name: stateBucketName, publicUrl: null },
393
+ },
394
+ };
395
+ writeManifest(opts.projectDir, updated);
396
+ console.log(chalk.dim(` · Recorded bucket names in ${MANIFEST_FILENAME} (${publicUrlSource}).`));
397
+ // 5. rclone snippet (printed by caller, returned here so callers
398
+ // can capture it programmatically too). Uses the per-project
399
+ // scoped credentials we just minted — anyone running rclone
400
+ // against this remote can only touch this project's two buckets.
401
+ // Don't write the snippet to disk; the user's existing rclone
402
+ // config has unrelated remotes and we don't want to mangle them.
403
+ const rcloneSnippet = buildRcloneSnippet({
404
+ remoteName: `r2-${projectName}`,
405
+ endpoint: meta.endpoint,
406
+ accessKey: projectAccessKey,
407
+ secretKey: projectSecretKey,
408
+ });
409
+ return {
410
+ assets: { name: assetsBucketName, publicUrl, created: !assetsBucket.existed },
411
+ state: { name: stateBucketName, created: !stateBucket.existed },
412
+ envWritten,
413
+ envKept,
414
+ rcloneSnippet,
415
+ };
416
+ }
417
+ /** Pick the registrable zone name for a hostname. Cloudflare keeps
418
+ * zones at the registrable level (example.com), so to attach
419
+ * `assets.foo.example.com` we look up `example.com`. Two-label
420
+ * apex stays as-is. This is the same shape the existing DNS code
421
+ * uses; see `cli/src/deploy/coolify-app.ts` for parallels. */
422
+ function pickClosestZoneName(hostname) {
423
+ const parts = hostname.split(".");
424
+ if (parts.length <= 2)
425
+ return hostname;
426
+ return parts.slice(-2).join(".");
427
+ }
428
+ //# sourceMappingURL=s3-buckets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3-buckets.js","sourceRoot":"","sources":["../../src/provision/s3-buckets.ts"],"names":[],"mappings":"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"}
@@ -45,6 +45,30 @@ export interface ProjectManifest {
45
45
  * Optional for back-compat with manifests written before this
46
46
  * field existed; readers should fall back to detection. */
47
47
  surfaces?: "server-only" | "client-only" | "both";
48
+ /** S3 buckets provisioned by `hatchkit provision s3`. Names go in
49
+ * the manifest (so re-runs are idempotent and `hatchkit destroy`
50
+ * knows what to undo); credentials never do — those live in the
51
+ * global config / OS keychain.
52
+ *
53
+ * `assets` is the public bucket fronting NEXT_PUBLIC_ASSETS_BASE_URL
54
+ * or equivalent. Reachable over HTTPS via either an r2.dev
55
+ * managed domain or a custom domain on a zone the user owns.
56
+ * `state` is the private bucket — used for state files, logs, cron
57
+ * inputs. Never publicly readable.
58
+ *
59
+ * `publicUrl` is the canonical no-trailing-slash URL the runtime
60
+ * should serve assets from. Always present on `assets`; null on
61
+ * `state` (private buckets aren't publicly reachable). */
62
+ s3Buckets?: {
63
+ assets?: {
64
+ name: string;
65
+ publicUrl: string;
66
+ };
67
+ state?: {
68
+ name: string;
69
+ publicUrl: null;
70
+ };
71
+ };
48
72
  }
49
73
  /** Build a manifest from the internal ProjectConfig, explicitly
50
74
  * whitelisting only the safe fields. Any new field on ProjectConfig
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/scaffold/manifest.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,eAAO,MAAM,iBAAiB,mBAAmB,CAAC;AAClD,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC,MAAM,WAAW,eAAe;IAC9B,qEAAqE;IACrE,OAAO,EAAE,OAAO,gBAAgB,CAAC;IACjC,iEAAiE;IACjE,UAAU,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,YAAY,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,0CAA0C;IAC1C,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB;6DACyD;IACzD,UAAU,EAAE,UAAU,CAAC;IACvB;qDACiD;IACjD,YAAY,EAAE,UAAU,GAAG,KAAK,CAAC;IACjC;;mDAE+C;IAC/C,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC;IAC7B,oEAAoE;IACpE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,2DAA2D;IAC3D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;oEACgE;IAChE,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9D;;;;;gEAK4D;IAC5D,QAAQ,CAAC,EAAE,aAAa,GAAG,aAAa,GAAG,MAAM,CAAC;CACnD;AAED;;oEAEoE;AACpE,wBAAgB,UAAU,CACxB,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,YAAY,EACnB,UAAU,EAAE,MAAM,GACjB,eAAe,CAoBjB;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,GAAG,IAAI,CAGhF;AAED;;;gCAGgC;AAChC,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAiBvE"}
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/scaffold/manifest.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,eAAO,MAAM,iBAAiB,mBAAmB,CAAC;AAClD,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC,MAAM,WAAW,eAAe;IAC9B,qEAAqE;IACrE,OAAO,EAAE,OAAO,gBAAgB,CAAC;IACjC,iEAAiE;IACjE,UAAU,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,YAAY,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,0CAA0C;IAC1C,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB;6DACyD;IACzD,UAAU,EAAE,UAAU,CAAC;IACvB;qDACiD;IACjD,YAAY,EAAE,UAAU,GAAG,KAAK,CAAC;IACjC;;mDAE+C;IAC/C,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC;IAC7B,oEAAoE;IACpE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,2DAA2D;IAC3D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;oEACgE;IAChE,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9D;;;;;gEAK4D;IAC5D,QAAQ,CAAC,EAAE,aAAa,GAAG,aAAa,GAAG,MAAM,CAAC;IAClD;;;;;;;;;;;;;+DAa2D;IAC3D,SAAS,CAAC,EAAE;QACV,MAAM,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,CAAC;QAC7C,KAAK,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,IAAI,CAAA;SAAE,CAAC;KAC3C,CAAC;CACH;AAED;;oEAEoE;AACpE,wBAAgB,UAAU,CACxB,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,YAAY,EACnB,UAAU,EAAE,MAAM,GACjB,eAAe,CAoBjB;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,GAAG,IAAI,CAGhF;AAED;;;gCAGgC;AAChC,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAiBvE"}
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/scaffold/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAIjC,MAAM,CAAC,MAAM,iBAAiB,GAAG,gBAAgB,CAAC;AAClD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AA2ClC;;oEAEoE;AACpE,MAAM,UAAU,UAAU,CACxB,MAAqB,EACrB,KAAmB,EACnB,UAAkB;IAElB,OAAO;QACL,OAAO,EAAE,gBAAgB;QACzB,UAAU;QACV,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACtC,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,QAAQ,EAAE,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC;QAC9B,UAAU,EAAE,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC;QAClC,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,eAAe,EAAE,MAAM,CAAC,eAAe;QACvC,eAAe,EAAE,MAAM,CAAC,eAAe;QACvC,KAAK,EAAE;YACL,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,SAAS,EAAE,KAAK,CAAC,SAAS;SAC3B;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,SAAiB,EAAE,QAAyB;IACxE,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;IAChD,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;AACzE,CAAC;AAED;;;gCAGgC;AAChC,MAAM,UAAU,YAAY,CAAC,UAAkB;IAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC;IACjD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IACnD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,eAAe,IAAI,uBAAwB,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IACtF,CAAC;IACD,IACE,CAAC,MAAM;QACP,OAAO,MAAM,KAAK,QAAQ;QACzB,MAAgC,CAAC,OAAO,KAAK,gBAAgB,EAC9D,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,eAAe,IAAI,kCAAkC,gBAAgB,GAAG,CAAC,CAAC;IAC5F,CAAC;IACD,OAAO,MAAyB,CAAC;AACnC,CAAC"}
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/scaffold/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAIjC,MAAM,CAAC,MAAM,iBAAiB,GAAG,gBAAgB,CAAC;AAClD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AA6DlC;;oEAEoE;AACpE,MAAM,UAAU,UAAU,CACxB,MAAqB,EACrB,KAAmB,EACnB,UAAkB;IAElB,OAAO;QACL,OAAO,EAAE,gBAAgB;QACzB,UAAU;QACV,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACtC,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,QAAQ,EAAE,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC;QAC9B,UAAU,EAAE,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC;QAClC,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,eAAe,EAAE,MAAM,CAAC,eAAe;QACvC,eAAe,EAAE,MAAM,CAAC,eAAe;QACvC,KAAK,EAAE;YACL,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,SAAS,EAAE,KAAK,CAAC,SAAS;SAC3B;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,SAAiB,EAAE,QAAyB;IACxE,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;IAChD,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;AACzE,CAAC;AAED;;;gCAGgC;AAChC,MAAM,UAAU,YAAY,CAAC,UAAkB;IAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC;IACjD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IACnD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,eAAe,IAAI,uBAAwB,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IACtF,CAAC;IACD,IACE,CAAC,MAAM;QACP,OAAO,MAAM,KAAK,QAAQ;QACzB,MAAgC,CAAC,OAAO,KAAK,gBAAgB,EAC9D,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,eAAe,IAAI,kCAAkC,gBAAgB,GAAG,CAAC,CAAC;IAC5F,CAAC;IACD,OAAO,MAAyB,CAAC;AACnC,CAAC"}
@@ -80,6 +80,102 @@ export declare class CloudflareApi {
80
80
  * mixed-content warnings that bite static-export apps.
81
81
  *
82
82
  * Returns a per-setting summary for the caller to log. */
83
+ /** Create a bucket. Returns the metadata. If the bucket already
84
+ * exists (409), returns `{ existed: true }` plus a fresh GET. */
85
+ createR2Bucket(accountId: string, name: string, opts?: {
86
+ locationHint?: string;
87
+ storageClass?: "Standard" | "InfrequentAccess";
88
+ }): Promise<{
89
+ name: string;
90
+ location?: string;
91
+ creation_date?: string;
92
+ storage_class?: string;
93
+ existed: boolean;
94
+ }>;
95
+ /** Get bucket metadata. Returns null on 404. */
96
+ getR2Bucket(accountId: string, name: string): Promise<{
97
+ name: string;
98
+ location?: string;
99
+ creation_date?: string;
100
+ storage_class?: string;
101
+ } | null>;
102
+ /** Enable (or disable) the managed `pub-<hash>.r2.dev` public URL on
103
+ * a bucket. Returns the assigned `pub-<hash>.r2.dev` hostname. */
104
+ enableR2ManagedDomain(accountId: string, bucket: string, enabled?: boolean): Promise<{
105
+ bucketId: string;
106
+ domain: string;
107
+ enabled: boolean;
108
+ }>;
109
+ /** List custom domains attached to a bucket — used to short-circuit
110
+ * re-runs that already added the domain. */
111
+ listR2CustomDomains(accountId: string, bucket: string): Promise<Array<{
112
+ domain: string;
113
+ enabled: boolean;
114
+ status?: {
115
+ ownership?: string;
116
+ ssl?: string;
117
+ };
118
+ }>>;
119
+ /** Mint a per-bucket-scoped R2 API token. Returns the token's S3
120
+ * access/secret derivation alongside the raw token id+value (the
121
+ * caller can store the access/secret pair as the project's S3
122
+ * credentials, or hold the token value to use as a Bearer for R2
123
+ * admin calls scoped to those buckets).
124
+ *
125
+ * The token resource scope follows Cloudflare's R2 format:
126
+ * `com.cloudflare.edge.r2.bucket.<accountId>_<jurisdiction>_<bucketName>`
127
+ * with jurisdiction = "default" for buckets created without an
128
+ * explicit jurisdiction (which is what `createR2Bucket` does today).
129
+ *
130
+ * Permission groups are looked up dynamically by name — Cloudflare
131
+ * doesn't publish stable IDs, only stable names. We cache the result
132
+ * on the instance so subsequent calls in the same process re-use it.
133
+ *
134
+ * Note on the calling token: this hits `POST /user/tokens` which
135
+ * requires the calling token to have `User > API Tokens > Edit`.
136
+ * An R2-only admin token will 403 here. The caller should surface
137
+ * that as a "add API Tokens:Edit to your admin token" hint. */
138
+ createR2ApiToken(params: {
139
+ accountId: string;
140
+ /** Display name for the token in the CF dashboard. Project name is
141
+ * the natural choice. */
142
+ name: string;
143
+ /** Bucket names to scope the token to. Token can only access these. */
144
+ bucketNames: string[];
145
+ /** Bucket jurisdiction. Defaults to "default" — matches how
146
+ * `createR2Bucket` creates buckets without explicit jurisdiction. */
147
+ jurisdiction?: "default" | "eu" | "fedramp";
148
+ /** Permissions scope for the resulting S3 keys. Default: read+write. */
149
+ permissions?: "read" | "read-write";
150
+ }): Promise<{
151
+ /** API token id — the same thing as the S3 Access Key ID. */
152
+ tokenId: string;
153
+ /** API token value (raw bearer). Sensitive. */
154
+ tokenValue: string;
155
+ /** S3 Access Key ID, derived per Cloudflare's docs (same as tokenId). */
156
+ accessKeyId: string;
157
+ /** S3 Secret Access Key — sha256(tokenValue), hex. */
158
+ secretAccessKey: string;
159
+ }>;
160
+ /** Cached lookup of /user/tokens/permission_groups filtered to R2
161
+ * groups. Returns at minimum the entries hatchkit looks up by name
162
+ * in `createR2ApiToken`. */
163
+ private permissionGroupsCache?;
164
+ private getR2PermissionGroups;
165
+ /** Delete a Cloudflare API token by id. Idempotent: 404 → "not-found". */
166
+ deleteApiToken(tokenId: string): Promise<"deleted" | "not-found">;
167
+ /** Attach a custom domain (a hostname on a Cloudflare zone you own)
168
+ * to an R2 bucket. Idempotent — duplicates short-circuit via list. */
169
+ addR2CustomDomain(accountId: string, bucket: string, params: {
170
+ domain: string;
171
+ zoneId: string;
172
+ minTLS?: "1.0" | "1.1" | "1.2" | "1.3";
173
+ }): Promise<{
174
+ domain: string;
175
+ enabled: boolean;
176
+ zoneId: string;
177
+ existed: boolean;
178
+ }>;
83
179
  enableEdgeHardening(zoneId: string): Promise<{
84
180
  changed: Array<{
85
181
  id: string;
@@ -1 +1 @@
1
- {"version":3,"file":"cloudflare-api.d.ts","sourceRoot":"","sources":["../../src/utils/cloudflare-api.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAiBD,kCAAkC;AAClC,qBAAa,aAAa;IACxB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,SAAS,CAAC,CAAS;gBAEf,OAAO,EAAE,oBAAoB;YAK3B,OAAO;IAoBrB,iDAAiD;IAC3C,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC;IAKpC;;;;;OAKG;IACG,SAAS,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IA2B5C,gEAAgE;IAC1D,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAOjE,6DAA6D;IACvD,UAAU,CACd,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,GAAG,GAAG,MAAM,GAAG,OAAO,GAC3B,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IAQhG;;;qEAGiE;IAC3D,YAAY,CAChB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE;QACN,IAAI,EAAE,GAAG,GAAG,MAAM,GAAG,OAAO,CAAC;QAC7B,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,GACA,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IA8B9D;4EACwE;IAClE,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,WAAW,CAAC;IA0BtF;;;gEAG4D;IACtD,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQzE,0DAA0D;IACpD,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IASzF;;;;;;;;;;;;;;;;;;;;+DAoB2D;IACrD,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QACjD,OAAO,EAAE,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,OAAO,CAAC;YAAC,EAAE,EAAE,OAAO,CAAA;SAAE,CAAC,CAAC;QAC3D,IAAI,EAAE,MAAM,EAAE,CAAC;QACf,MAAM,EAAE,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KAC9C,CAAC;CAkDH"}
1
+ {"version":3,"file":"cloudflare-api.d.ts","sourceRoot":"","sources":["../../src/utils/cloudflare-api.ts"],"names":[],"mappings":"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"}