@smoothbricks/cli 0.10.7 โ†’ 0.10.9

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 (58) hide show
  1. package/dist/cli.d.ts.map +1 -1
  2. package/dist/cli.js +24 -1
  3. package/dist/github-ci/index.d.ts +44 -4
  4. package/dist/github-ci/index.d.ts.map +1 -1
  5. package/dist/github-ci/index.js +220 -34
  6. package/dist/monorepo/ci-workflow.js +16 -6
  7. package/dist/monorepo/managed-files.d.ts.map +1 -1
  8. package/dist/monorepo/managed-files.js +19 -1
  9. package/dist/monorepo/pr-preview-cleanup-workflow.d.ts +5 -0
  10. package/dist/monorepo/pr-preview-cleanup-workflow.d.ts.map +1 -0
  11. package/dist/monorepo/pr-preview-cleanup-workflow.js +38 -0
  12. package/dist/monorepo/publish-workflow.js +3 -3
  13. package/dist/monorepo/tool-validation.d.ts.map +1 -1
  14. package/dist/monorepo/tool-validation.js +85 -5
  15. package/dist/playwright/index.d.ts +22 -0
  16. package/dist/playwright/index.d.ts.map +1 -0
  17. package/dist/playwright/index.js +44 -0
  18. package/dist/release/bootstrap-npm-packages.d.ts +3 -0
  19. package/dist/release/bootstrap-npm-packages.d.ts.map +1 -1
  20. package/dist/release/bootstrap-npm-packages.js +21 -0
  21. package/dist/release/index.d.ts +1 -0
  22. package/dist/release/index.d.ts.map +1 -1
  23. package/dist/release/index.js +31 -6
  24. package/dist/wrangler/cloudflare.d.ts +87 -0
  25. package/dist/wrangler/cloudflare.d.ts.map +1 -0
  26. package/dist/wrangler/cloudflare.js +238 -0
  27. package/dist/wrangler/deploy-environment.d.ts +48 -0
  28. package/dist/wrangler/deploy-environment.d.ts.map +1 -0
  29. package/dist/wrangler/deploy-environment.js +383 -0
  30. package/dist/wrangler/environment.d.ts +58 -0
  31. package/dist/wrangler/environment.d.ts.map +1 -0
  32. package/dist/wrangler/environment.js +297 -0
  33. package/managed/raw/tooling/direnv/github-actions-bootstrap.sh +3 -4
  34. package/package.json +9 -2
  35. package/src/cli.ts +27 -3
  36. package/src/github-ci/index.test.ts +175 -2
  37. package/src/github-ci/index.ts +274 -31
  38. package/src/monorepo/__tests__/ci-workflow.test.ts +10 -4
  39. package/src/monorepo/__tests__/pr-preview-cleanup-workflow.test.ts +23 -0
  40. package/src/monorepo/__tests__/publish-workflow.test.ts +7 -5
  41. package/src/monorepo/ci-workflow.ts +16 -6
  42. package/src/monorepo/managed-files.test.ts +56 -1
  43. package/src/monorepo/managed-files.ts +20 -1
  44. package/src/monorepo/pr-preview-cleanup-workflow.ts +44 -0
  45. package/src/monorepo/publish-workflow.ts +8 -5
  46. package/src/monorepo/tool-validation.test.ts +85 -0
  47. package/src/monorepo/tool-validation.ts +94 -5
  48. package/src/playwright/index.test.ts +90 -0
  49. package/src/playwright/index.ts +73 -0
  50. package/src/release/__tests__/bootstrap-npm-packages.test.ts +63 -2
  51. package/src/release/bootstrap-npm-packages.ts +34 -0
  52. package/src/release/index.ts +30 -4
  53. package/src/wrangler/cloudflare.test.ts +76 -0
  54. package/src/wrangler/cloudflare.ts +292 -0
  55. package/src/wrangler/deploy-environment.test.ts +354 -0
  56. package/src/wrangler/deploy-environment.ts +445 -0
  57. package/src/wrangler/environment.test.ts +173 -0
  58. package/src/wrangler/environment.ts +366 -0
@@ -380,7 +380,7 @@ function deployProductionStep(step, options) {
380
380
  " ${{ steps.version.outputs.mode != 'none' && inputs.deploy_environment == 'production' && inputs.dry_run !=",
381
381
  " 'true' }}",
382
382
  ...deployEnvLines(options),
383
- ' run: smoo github-ci nx-deploy --configuration production --mode run-many --verify --name "Deploy Production"',
383
+ ' run: smoo github-ci nx-deploy --environment production --mode run-many --verify --name "Deploy Production"',
384
384
  ];
385
385
  }
386
386
  function deployEnvLines(options) {
@@ -557,7 +557,7 @@ function renderMacosPlatformSteps(options) {
557
557
  if (isSmoothBricksCodebasePackageName(options.repoName)) {
558
558
  lines.push('', ` # Step ${stepNumber++}`, ' - name: ๐Ÿ—๏ธ Build self-hosted smoo', ' # SmoothBricks self-hosts smoo from source for release commands.', ' run: nx build cli');
559
559
  }
560
- lines.push('', ` # Step ${stepNumber++}`, ' - name: ๐ŸŽ Build selected macOS and iOS release outputs', ' run:', ` smoo release build-platform-outputs --bump "${githubExpression('inputs.bump')}" --ref "${githubExpression('github.sha')}" --targets "${MACOS_PLATFORM_TARGET_GLOBS.join(',')}" --output`, ` "${githubExpression('runner.temp')}/macos-platform-outputs"`, '', ` # Step ${stepNumber++}`, ' - name: ๐Ÿงช Unit test macOS and iOS packages', ' run:', ` smoo github-ci nx-run-many --targets test --projects-with-targets "${MACOS_PLATFORM_TARGET_GLOBS.join(',')}"`, '', ` # Step ${stepNumber++}`, ' - name: ๐Ÿ“ค Upload macOS platform outputs', ' uses: actions/upload-artifact@v7.0.1', ' with:', ` name: publish-macos-outputs-${githubExpression('github.run_id')}`, ` path: ${githubExpression('runner.temp')}/macos-platform-outputs`, ' if-no-files-found: error', ' retention-days: 1', ' include-hidden-files: true', '', ' # --- Cleanup ------------------------------------------------------------', '', ` # Step ${stepNumber}`, ' - name: ๐Ÿงน Cleanup and cache Nix/devenv', ' # success() is default; always() still saves GH Nix cache after a red job.', ' if: always()', ' uses: ./.github/actions/save-nix-devenv', ' with:', ` nix-cache-hit: ${githubExpression('steps.setup.outputs.nix-cache-hit')}`, ` devenv-cache-hit: ${githubExpression('steps.setup.outputs.devenv-cache-hit')}`);
560
+ lines.push('', ` # Step ${stepNumber++}`, ' - name: ๐ŸŽ Build selected macOS and iOS release outputs', ' id: platform-outputs', ' run:', ` smoo release build-platform-outputs --bump "${githubExpression('inputs.bump')}" --ref "${githubExpression('github.sha')}" --targets "${MACOS_PLATFORM_TARGET_GLOBS.join(',')}" --output`, ` "${githubExpression('runner.temp')}/macos-platform-outputs" --github-output "$GITHUB_OUTPUT"`, '', ` # Step ${stepNumber++}`, ' - name: ๐Ÿงช Unit test selected macOS and iOS packages', ` if: steps.platform-outputs.outputs.projects != ''`, ' run:', ' smoo github-ci nx-run-many --targets test --projects', ` "${githubExpression('steps.platform-outputs.outputs.projects')}"`, '', ` # Step ${stepNumber++}`, ' - name: ๐Ÿ“ค Upload macOS platform outputs', ' uses: actions/upload-artifact@v7.0.1', ' with:', ` name: publish-macos-outputs-${githubExpression('github.run_id')}`, ` path: ${githubExpression('runner.temp')}/macos-platform-outputs`, ' if-no-files-found: error', ' retention-days: 1', ' include-hidden-files: true', '', ' # --- Cleanup ------------------------------------------------------------', '', ` # Step ${stepNumber}`, ' - name: ๐Ÿงน Cleanup and cache Nix/devenv', ' # success() is default; always() still saves GH Nix cache after a red job.', ' if: always()', ' uses: ./.github/actions/save-nix-devenv', ' with:', ` nix-cache-hit: ${githubExpression('steps.setup.outputs.nix-cache-hit')}`, ` devenv-cache-hit: ${githubExpression('steps.setup.outputs.devenv-cache-hit')}`);
561
561
  return lines.join('\n').trimEnd();
562
562
  }
563
563
  function renderFinalLinuxPublishSteps(options) {
@@ -606,7 +606,7 @@ function renderFinalLinuxPublishSteps(options) {
606
606
  }
607
607
  lines.push('', ` # Step ${stepNumber++}`, ' - name: ๐ŸŽ Apply verified macOS outputs', ` if: ${mode} != 'none'`, ' run:', ` smoo github-ci apply-outputs --source-sha "${githubExpression('github.sha')}"`, ` "${githubExpression('runner.temp')}/publish-artifacts/publish-macos-outputs-${githubExpression('github.run_id')}/current"`, '', ` # Step ${stepNumber++}`, ` - name: โœ… Validate restored release (${githubExpression(mode)})`, ` if: ${mode} != 'none'`, ' run: smoo monorepo validate', '', ' # --- Release ------------------------------------------------------------', '', ` # Step ${stepNumber++}`, ` - name: ๐Ÿ“ฆ Publish release (${githubExpression(mode)})`, ' # smoo packs with Bun, then publishes tarballs with npm. Existing', ' # packages must already exist on npm and use trusted publishing/OIDC.', ' # Missing package names are bootstrapped locally before trust setup.', ` run: smoo release publish --bump "${githubExpression('inputs.bump')}" --dry-run "${githubExpression('inputs.dry_run')}"`);
608
608
  if (options.deploy === true) {
609
- lines.push('', ` # Step ${stepNumber++}`, ' - name: ๐Ÿš€ Deploy production', ' if:', " ${{ needs.linux-release-candidate.outputs.mode != 'none' && inputs.deploy_environment == 'production' &&", " inputs.dry_run != 'true' }}", ...deployEnvLines(options), ' run: smoo github-ci nx-deploy --configuration production --mode run-many --verify --name "Deploy Production"');
609
+ lines.push('', ` # Step ${stepNumber++}`, ' - name: ๐Ÿš€ Deploy production', ' if:', " ${{ needs.linux-release-candidate.outputs.mode != 'none' && inputs.deploy_environment == 'production' &&", " inputs.dry_run != 'true' }}", ...deployEnvLines(options), ' run: smoo github-ci nx-deploy --environment production --mode run-many --verify --name "Deploy Production"');
610
610
  }
611
611
  lines.push('', ' # --- Cleanup ------------------------------------------------------------', '', ` # Step ${stepNumber}`, ' - name: ๐Ÿงน Cleanup and cache Nix/devenv', ' # success() is default; always() still saves GH Nix cache after a red job.', ' if: always()', ' uses: ./.github/actions/save-nix-devenv', ' with:', ` nix-cache-hit: ${githubExpression('steps.setup.outputs.nix-cache-hit')}`, ` devenv-cache-hit: ${githubExpression('steps.setup.outputs.devenv-cache-hit')}`);
612
612
  return lines.join('\n').trimEnd();
@@ -1 +1 @@
1
- {"version":3,"file":"tool-validation.d.ts","sourceRoot":"","sources":["../../src/monorepo/tool-validation.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,KAAK,WAAW,EAAyB,MAAM,qBAAqB,CAAC;AAU9E,MAAM,WAAW,UAAU;IACzB,sBAAsB,EAAE,OAAO,CAAC;IAChC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,MAAM,EAAE,UAAU,CAAC;CACpB;AAgDD,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKzE;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAStE;AAED,wBAAsB,8BAA8B,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAwBtG;AAqCD,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CAkBlF;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAY/D;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CA0B7D;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,GAAG,IAAI,GAAG,MAAM,CAyBvG;AAyBD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAoB/E;AAED,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI,GAAG,MAAM,CAWhF;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAqB3D;AAsED,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAQxE"}
1
+ {"version":3,"file":"tool-validation.d.ts","sourceRoot":"","sources":["../../src/monorepo/tool-validation.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,KAAK,WAAW,EAAyB,MAAM,qBAAqB,CAAC;AAU9E,MAAM,WAAW,UAAU;IACzB,sBAAsB,EAAE,OAAO,CAAC;IAChC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,MAAM,EAAE,UAAU,CAAC;CACpB;AA4DD,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKzE;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAStE;AAED,wBAAsB,8BAA8B,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAwBtG;AAqCD,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CAkBlF;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAY/D;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAiC7D;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,GAAG,IAAI,GAAG,MAAM,CAyBvG;AAyBD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAoB/E;AAED,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI,GAAG,MAAM,CAWhF;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA6B3D;AAoID,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAQxE"}
@@ -1,4 +1,4 @@
1
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
1
+ import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';
2
2
  import { dirname, join } from 'node:path';
3
3
  import typia from 'typia';
4
4
  import { cliPackageVersion, isSmoothBricksCodebasePackageName } from '../lib/cli-package.js';
@@ -49,12 +49,24 @@ const rootDevDependencies = [
49
49
  { name: '@typescript/native', fallbackVersion: 'npm:typescript@^7.0.2' },
50
50
  ];
51
51
  const cliPackageName = '@smoothbricks/cli';
52
- const requiredDevenvPackages = ['bun', 'git', 'git-format-staged', 'jq', 'alejandra', 'coreutils', 'gnutar'];
52
+ const requiredDevenvPackages = ['bun', 'git', 'git-format-staged', 'jq', 'alejandra', 'coreutils', 'gnutar', 'go'];
53
53
  // Any explicit nodejs provider is fine โ€” the pinned major is the repo's choice
54
54
  // (Lambda parity, org convergence, โ€ฆ). Whether the pins in package.json agree
55
55
  // with the runtime is validated against the live PATH (validateRootRuntimeVersions),
56
56
  // never against a version template here.
57
57
  const nodePackagePattern = /(^|\s)nodejs(_\d+|_latest)?(\s|#|$)/m;
58
+ const requiredRustDevenvPackages = ['sccache'];
59
+ const linuxCompilerPackage = 'pkgs.stdenv.cc';
60
+ const ignoredNativeManifestDirectories = new Set([
61
+ '.devenv',
62
+ '.direnv',
63
+ '.git',
64
+ '.nx',
65
+ 'dist',
66
+ 'node_modules',
67
+ 'target',
68
+ 'vendor',
69
+ ]);
58
70
  const obsoleteTtscPatchedDependencyKey = 'ttsc@0.19.3';
59
71
  export async function applyToolConfigDefaults(root) {
60
72
  const context = await readToolContext(root);
@@ -172,7 +184,9 @@ export function applyDevenvPackageDefaults(root) {
172
184
  changed = next !== content || changed;
173
185
  content = next;
174
186
  }
175
- for (const name of requiredDevenvPackages) {
187
+ const compilesRust = workspaceCompilesRust(root);
188
+ const requiredPackages = [...requiredDevenvPackages, ...(compilesRust ? requiredRustDevenvPackages : [])];
189
+ for (const name of requiredPackages) {
176
190
  if (hasNixPackage(content, name)) {
177
191
  continue;
178
192
  }
@@ -180,6 +194,11 @@ export function applyDevenvPackageDefaults(root) {
180
194
  changed = next !== content || changed;
181
195
  content = next;
182
196
  }
197
+ if (compilesRust && !hasLinuxCompilerPackage(content)) {
198
+ const next = addLinuxCompilerPackage(content);
199
+ changed = next !== content || changed;
200
+ content = next;
201
+ }
183
202
  if (changed) {
184
203
  writeFileSync(path, content);
185
204
  console.log('updated tooling/direnv/devenv.nix packages');
@@ -277,12 +296,18 @@ export function validateDevenvPackages(root) {
277
296
  console.error('tooling/direnv/devenv.nix packages must include a nodejs provider (nodejs_<major> or nodejs_latest)');
278
297
  failures++;
279
298
  }
280
- for (const name of requiredDevenvPackages) {
299
+ const compilesRust = workspaceCompilesRust(root);
300
+ const requiredPackages = [...requiredDevenvPackages, ...(compilesRust ? requiredRustDevenvPackages : [])];
301
+ for (const name of requiredPackages) {
281
302
  if (!hasNixPackage(content, name)) {
282
303
  console.error(`tooling/direnv/devenv.nix packages must include ${name}`);
283
304
  failures++;
284
305
  }
285
306
  }
307
+ if (compilesRust && !hasLinuxCompilerPackage(content)) {
308
+ console.error('tooling/direnv/devenv.nix packages must include pkgs.stdenv.cc in a Linux-only package block for Rust builds');
309
+ failures++;
310
+ }
286
311
  return failures;
287
312
  }
288
313
  function addNixPackage(content, name, comment) {
@@ -290,7 +315,9 @@ function addNixPackage(content, name, comment) {
290
315
  if (hasNixPackage(content, name)) {
291
316
  return content;
292
317
  }
293
- const packagesStart = content.indexOf(' packages = with pkgs; [');
318
+ const directPackagesStart = content.indexOf(' packages = with pkgs; [');
319
+ const groupedPackagesStart = content.indexOf(' (with pkgs; [');
320
+ const packagesStart = directPackagesStart === -1 ? groupedPackagesStart : directPackagesStart;
294
321
  if (packagesStart === -1) {
295
322
  return content;
296
323
  }
@@ -300,6 +327,53 @@ function addNixPackage(content, name, comment) {
300
327
  function hasNixPackage(content, name) {
301
328
  return new RegExp(`(^|\\s)${escapeRegex(name)}(\\s|#|$)`, 'm').test(content);
302
329
  }
330
+ function workspaceCompilesRust(root) {
331
+ return containsCargoManifest(root);
332
+ }
333
+ function containsCargoManifest(directory) {
334
+ for (const entry of readdirSync(directory, { withFileTypes: true })) {
335
+ if (entry.isFile() && entry.name === 'Cargo.toml') {
336
+ return true;
337
+ }
338
+ if (entry.isDirectory() &&
339
+ entry.name.startsWith('.') === false &&
340
+ ignoredNativeManifestDirectories.has(entry.name) === false &&
341
+ containsCargoManifest(join(directory, entry.name))) {
342
+ return true;
343
+ }
344
+ }
345
+ return false;
346
+ }
347
+ function hasLinuxCompilerPackage(content) {
348
+ const linuxPackages = /\+\+\s+lib\.optionals\s+pkgs\.stdenv\.isLinux\s+\[([\s\S]*?)\]/g;
349
+ return [...content.matchAll(linuxPackages)].some((match) => hasNixPackage(match[1] ?? '', linuxCompilerPackage));
350
+ }
351
+ function addLinuxCompilerPackage(content) {
352
+ if (hasLinuxCompilerPackage(content)) {
353
+ return content;
354
+ }
355
+ const directStart = content.indexOf(' packages = with pkgs; [');
356
+ if (directStart !== -1) {
357
+ const listEnd = content.indexOf('\n ];', directStart);
358
+ if (listEnd === -1) {
359
+ return content;
360
+ }
361
+ const listBody = content.slice(directStart + ' packages = with pkgs; ['.length, listEnd);
362
+ const replacement = ` packages =\n (with pkgs; [${listBody}\n ])\n ++ lib.optionals pkgs.stdenv.isLinux [\n ${linuxCompilerPackage}\n ];`;
363
+ return `${content.slice(0, directStart)}${replacement}${content.slice(listEnd + '\n ];'.length)}`;
364
+ }
365
+ const packagesStart = content.indexOf(' packages =');
366
+ const nextOption = content.indexOf('\n\n ', packagesStart);
367
+ if (packagesStart === -1 || nextOption === -1) {
368
+ return content;
369
+ }
370
+ const terminator = content.lastIndexOf(';', nextOption);
371
+ if (terminator < packagesStart) {
372
+ return content;
373
+ }
374
+ const linuxPackages = `\n ++ lib.optionals pkgs.stdenv.isLinux [\n ${linuxCompilerPackage}\n ]`;
375
+ return `${content.slice(0, terminator)}${linuxPackages}${content.slice(terminator)}`;
376
+ }
303
377
  function nixPackageComment(name) {
304
378
  if (name === 'coreutils') {
305
379
  return '# Provides fmt for commit message wrapping';
@@ -310,6 +384,12 @@ function nixPackageComment(name) {
310
384
  if (name === 'git') {
311
385
  return '# Git hooks and repository inspection';
312
386
  }
387
+ if (name === 'go') {
388
+ return '# Builds ttsc source plugins';
389
+ }
390
+ if (name === 'sccache') {
391
+ return '# Rust compiler wrapper and cache';
392
+ }
313
393
  return '';
314
394
  }
315
395
  function escapeRegex(value) {
@@ -0,0 +1,22 @@
1
+ export interface ChromiumSetupDependencies {
2
+ readonly env: Readonly<Record<string, string | undefined>>;
3
+ readonly exists: (path: string) => boolean;
4
+ readonly run: (command: string, args: string[], cwd: string, env?: Record<string, string>) => Promise<void>;
5
+ }
6
+ export type ChromiumSetupResult = {
7
+ readonly mode: 'persistent-cache';
8
+ readonly browserCachePath: string;
9
+ } | {
10
+ readonly mode: 'system';
11
+ readonly executablePath: string;
12
+ } | {
13
+ readonly mode: 'developer-cache';
14
+ readonly browserCachePath?: string;
15
+ };
16
+ /**
17
+ * Ensure Chromium is available without polluting ephemeral GitHub runners.
18
+ * Persistent host runners and developer machines may install into their
19
+ * respective caches; ephemeral GitHub runners must use their image's browser.
20
+ */
21
+ export declare function ensureChromium(cwd?: string, dependencies?: ChromiumSetupDependencies): Promise<ChromiumSetupResult>;
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/playwright/index.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IAC3D,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAC3C,QAAQ,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7G;AAED,MAAM,MAAM,mBAAmB,GAC3B;IAAE,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAAC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;CAAE,GACxE;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;CAAE,GAC5D;IAAE,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAQ7E;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,GAAG,SAAgB,EACnB,YAAY,GAAE,yBAA+C,GAC5D,OAAO,CAAC,mBAAmB,CAAC,CAmC9B"}
@@ -0,0 +1,44 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { run } from '../lib/run.js';
3
+ const HOST_CACHE_ROOT = '/var/cache/ci';
4
+ const HOST_BROWSER_CACHE = `${HOST_CACHE_ROOT}/ms-playwright`;
5
+ const SYSTEM_CHROME_PATHS = [
6
+ '/usr/bin/google-chrome',
7
+ '/usr/bin/chromium-browser',
8
+ '/usr/bin/chromium',
9
+ '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
10
+ ];
11
+ const defaultDependencies = {
12
+ env: process.env,
13
+ exists: existsSync,
14
+ run,
15
+ };
16
+ /**
17
+ * Ensure Chromium is available without polluting ephemeral GitHub runners.
18
+ * Persistent host runners and developer machines may install into their
19
+ * respective caches; ephemeral GitHub runners must use their image's browser.
20
+ */
21
+ export async function ensureChromium(cwd = process.cwd(), dependencies = defaultDependencies) {
22
+ const { env, exists, run: runCommand } = dependencies;
23
+ const githubActions = env.GITHUB_ACTIONS === 'true';
24
+ if (githubActions && exists(HOST_CACHE_ROOT)) {
25
+ await runCommand('playwright', ['install', 'chromium', '--only-shell'], cwd, {
26
+ PLAYWRIGHT_BROWSERS_PATH: HOST_BROWSER_CACHE,
27
+ });
28
+ console.log(`Chromium ready in persistent cache: ${HOST_BROWSER_CACHE}`);
29
+ return { mode: 'persistent-cache', browserCachePath: HOST_BROWSER_CACHE };
30
+ }
31
+ if (githubActions) {
32
+ const candidates = [env.PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH, ...SYSTEM_CHROME_PATHS].filter((path) => typeof path === 'string' && path.length > 0);
33
+ const executablePath = candidates.find(exists);
34
+ if (!executablePath) {
35
+ throw new Error(`GitHub-hosted runner has no preinstalled Chromium. Refusing to download; searched: ${candidates.join(', ')}`);
36
+ }
37
+ console.log(`Using preinstalled Chromium: ${executablePath}`);
38
+ return { mode: 'system', executablePath };
39
+ }
40
+ const browserCachePath = env.PLAYWRIGHT_BROWSERS_PATH;
41
+ await runCommand('playwright', ['install', 'chromium', '--only-shell'], cwd, browserCachePath ? { PLAYWRIGHT_BROWSERS_PATH: browserCachePath } : undefined);
42
+ console.log(browserCachePath ? `Chromium ready in configured cache: ${browserCachePath}` : 'Chromium ready.');
43
+ return browserCachePath ? { mode: 'developer-cache', browserCachePath } : { mode: 'developer-cache' };
44
+ }
@@ -1,6 +1,7 @@
1
1
  import type { ReleasePackageInfo } from './core.js';
2
2
  export declare const NPM_BOOTSTRAP_VERSION = "0.0.0-bootstrap.0";
3
3
  export declare const NPM_BOOTSTRAP_DIST_TAG = "bootstrap";
4
+ export declare const NPM_BOOTSTRAP_VISIBILITY_TIMEOUT_MS = 120000;
4
5
  export interface BootstrapNpmPackagesOptions {
5
6
  dryRun: boolean;
6
7
  skipLogin: boolean;
@@ -10,9 +11,11 @@ export interface BootstrapNpmPackagesOptions {
10
11
  export interface BootstrapNpmPackagesShell<Package extends ReleasePackageInfo = ReleasePackageInfo> {
11
12
  listReleasePackages(): Package[];
12
13
  packageExists(name: string): Promise<boolean>;
14
+ packageVersionExists(name: string, version: string): Promise<boolean>;
13
15
  login(): Promise<void>;
14
16
  publishPlaceholder(pkg: Package, env?: Record<string, string>): Promise<void>;
15
17
  promptOtp(packageName: string): Promise<string>;
18
+ wait(milliseconds: number): Promise<void>;
16
19
  log(message: string): void;
17
20
  }
18
21
  export declare function bootstrapNpmPackages<Package extends ReleasePackageInfo>(shell: BootstrapNpmPackagesShell<Package>, options: BootstrapNpmPackagesOptions): Promise<Package[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap-npm-packages.d.ts","sourceRoot":"","sources":["../../src/release/bootstrap-npm-packages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAEpD,eAAO,MAAM,qBAAqB,sBAAsB,CAAC;AACzD,eAAO,MAAM,sBAAsB,cAAc,CAAC;AAElD,MAAM,WAAW,2BAA2B;IAC1C,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,yBAAyB,CAAC,OAAO,SAAS,kBAAkB,GAAG,kBAAkB;IAChG,mBAAmB,IAAI,OAAO,EAAE,CAAC;IACjC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,kBAAkB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAChD,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,wBAAsB,oBAAoB,CAAC,OAAO,SAAS,kBAAkB,EAC3E,KAAK,EAAE,yBAAyB,CAAC,OAAO,CAAC,EACzC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,OAAO,EAAE,CAAC,CAuCpB"}
1
+ {"version":3,"file":"bootstrap-npm-packages.d.ts","sourceRoot":"","sources":["../../src/release/bootstrap-npm-packages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAEpD,eAAO,MAAM,qBAAqB,sBAAsB,CAAC;AACzD,eAAO,MAAM,sBAAsB,cAAc,CAAC;AAClD,eAAO,MAAM,mCAAmC,SAAU,CAAC;AAI3D,MAAM,WAAW,2BAA2B;IAC1C,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,yBAAyB,CAAC,OAAO,SAAS,kBAAkB,GAAG,kBAAkB;IAChG,mBAAmB,IAAI,OAAO,EAAE,CAAC;IACjC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9C,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACtE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,kBAAkB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAChD,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,wBAAsB,oBAAoB,CAAC,OAAO,SAAS,kBAAkB,EAC3E,KAAK,EAAE,yBAAyB,CAAC,OAAO,CAAC,EACzC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,OAAO,EAAE,CAAC,CA2CpB"}
@@ -1,5 +1,7 @@
1
1
  export const NPM_BOOTSTRAP_VERSION = '0.0.0-bootstrap.0';
2
2
  export const NPM_BOOTSTRAP_DIST_TAG = 'bootstrap';
3
+ export const NPM_BOOTSTRAP_VISIBILITY_TIMEOUT_MS = 120000;
4
+ const NPM_BOOTSTRAP_POLL_DELAYS_MS = [0, 1000, 2000, 4000, 8000, 15000, 30000, 30000, 30000];
3
5
  export async function bootstrapNpmPackages(shell, options) {
4
6
  const packages = selectedReleasePackages(shell.listReleasePackages(), options.packages);
5
7
  if (packages.length === 0) {
@@ -27,14 +29,33 @@ export async function bootstrapNpmPackages(shell, options) {
27
29
  if (!options.skipLogin) {
28
30
  await shell.login();
29
31
  }
32
+ // Upload every placeholder before waiting for npm registry propagation. Keeping the
33
+ // phases separate prevents one slow package from blocking the remaining uploads.
30
34
  for (const pkg of missing) {
31
35
  shell.log(`${pkg.name}: publishing npm placeholder.`);
32
36
  const otp = options.otp ?? (await shell.promptOtp(pkg.name));
33
37
  await shell.publishPlaceholder(pkg, { NPM_CONFIG_OTP: otp });
34
38
  }
39
+ await waitForPublishedPackages(shell, missing);
35
40
  shell.log('Bootstrap complete. Run smoo release trust-publisher before the first CI publish.');
36
41
  return missing;
37
42
  }
43
+ async function waitForPublishedPackages(shell, packages) {
44
+ let pending = [...packages];
45
+ for (const delayMs of NPM_BOOTSTRAP_POLL_DELAYS_MS) {
46
+ if (delayMs > 0) {
47
+ await shell.wait(delayMs);
48
+ }
49
+ const visible = await Promise.all(pending.map((pkg) => shell.packageVersionExists(pkg.name, NPM_BOOTSTRAP_VERSION)));
50
+ pending = pending.filter((_, index) => !visible[index]);
51
+ if (pending.length === 0) {
52
+ return;
53
+ }
54
+ }
55
+ throw new Error(`Bootstrap uploads succeeded, but npm did not expose these packages after ${NPM_BOOTSTRAP_VISIBILITY_TIMEOUT_MS / 1000} seconds: ${pending
56
+ .map((pkg) => pkg.name)
57
+ .join(', ')}. Retry smoo release trust-publisher later; do not bootstrap again.`);
58
+ }
38
59
  function selectedReleasePackages(packages, selections) {
39
60
  if (selections.length === 0) {
40
61
  return packages;
@@ -16,6 +16,7 @@ export interface ReleaseRepairPendingOptions {
16
16
  }
17
17
  export interface ReleasePlatformOutputsOptions {
18
18
  bump: string;
19
+ githubOutput?: string;
19
20
  output: string;
20
21
  ref?: string;
21
22
  targets: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/release/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/release/index.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,7 @@ import { tmpdir } from 'node:os';
4
4
  import { join, resolve } from 'node:path';
5
5
  import { createInterface } from 'node:readline/promises';
6
6
  import { Writable } from 'node:stream';
7
+ import { setTimeout as delay } from 'node:timers/promises';
7
8
  import { $ } from 'bun';
8
9
  import typia from 'typia';
9
10
  import { githubCiApplyOutputs, githubCiNxRunMany } from '../github-ci/index.js';
@@ -103,7 +104,7 @@ export async function releaseCollectPlatformOutputs(root, options) {
103
104
  ? 'Release platform outputs: no current release packages selected.'
104
105
  : `Release platform outputs: building current outputs for ${packageSummary(currentPackages)}.`);
105
106
  const outputRoot = resolve(root, options.output);
106
- await githubCiNxRunMany(root, {
107
+ const currentRuns = await githubCiNxRunMany(root, {
107
108
  targets: options.targets,
108
109
  projects: releasePackageProjects(currentPackages),
109
110
  collectOutputs: join(outputRoot, 'current'),
@@ -113,6 +114,12 @@ export async function releaseCollectPlatformOutputs(root, options) {
113
114
  const targets = await listPendingReleaseTargets(root, releaseRef);
114
115
  logPendingReleaseTargets(targets);
115
116
  await collectRepairPlatformOutputs(releaseRepairOutputsShell(root, options.targets, join(outputRoot, 'repairs')), targets, restoreRef);
117
+ if (options.githubOutput) {
118
+ const projects = [
119
+ ...new Set(currentRuns.runs.flatMap((run) => run.projects.map((project) => project.project))),
120
+ ].sort((left, right) => left.localeCompare(right));
121
+ await appendFile(options.githubOutput, `projects=${projects.join(',')}\n`);
122
+ }
116
123
  }
117
124
  export async function releaseTrustPublisher(root, options) {
118
125
  const repository = githubRepositoryFromRootPackage(root);
@@ -125,9 +132,11 @@ export async function releaseTrustPublisher(root, options) {
125
132
  bootstrapNpmPackages: (bootstrapOptions) => bootstrapNpmPackages({
126
133
  listReleasePackages: () => listReleasePackages(root),
127
134
  packageExists: (name) => npmPackageExists(root, name),
135
+ packageVersionExists: (name, version) => npmPublishedVersionExists(root, name, version),
128
136
  login: () => runLatestNpm(root, ['login', '--auth-type=web']),
129
137
  publishPlaceholder: (pkg, env) => publishPlaceholderPackage(root, pkg, env),
130
138
  promptOtp: (packageName) => promptForNpmOtp(packageName),
139
+ wait: delay,
131
140
  log: (message) => console.log(message),
132
141
  }, bootstrapOptions),
133
142
  trustPublisher: (pkg, dryRun, env) => runLatestNpmTrust(root, npmTrustGithubArgs(pkg.name, repository, workflow, dryRun), env),
@@ -254,9 +263,11 @@ export async function releaseBootstrapNpmPackages(root, options) {
254
263
  await bootstrapNpmPackages({
255
264
  listReleasePackages: () => listReleasePackages(root),
256
265
  packageExists: (name) => npmPackageExists(root, name),
266
+ packageVersionExists: (name, version) => npmPublishedVersionExists(root, name, version),
257
267
  login: () => runLatestNpm(root, ['login', '--auth-type=web']),
258
268
  publishPlaceholder: (pkg, env) => publishPlaceholderPackage(root, pkg, env),
259
269
  promptOtp: (packageName) => promptForNpmOtp(packageName),
270
+ wait: delay,
260
271
  log: (message) => console.log(message),
261
272
  }, {
262
273
  dryRun: options.dryRun === true,
@@ -648,11 +659,13 @@ function releaseRepairShell(root, platformOutputs) {
648
659
  function releaseRepairOutputsShell(root, targetGlobs, outputRoot) {
649
660
  return {
650
661
  ...releaseTargetCheckoutShell(root),
651
- collectRepairTargetOutputs: (target) => githubCiNxRunMany(root, {
652
- targets: targetGlobs,
653
- projects: releasePackageProjects(target.npmPackages),
654
- collectOutputs: join(outputRoot, target.sha),
655
- }),
662
+ collectRepairTargetOutputs: async (target) => {
663
+ await githubCiNxRunMany(root, {
664
+ targets: targetGlobs,
665
+ projects: releasePackageProjects(target.npmPackages),
666
+ collectOutputs: join(outputRoot, target.sha),
667
+ });
668
+ },
656
669
  };
657
670
  }
658
671
  function releaseRetagShell(root, remote) {
@@ -1126,6 +1139,18 @@ async function npmPackageExists(root, name) {
1126
1139
  const result = await $ `bun pm view ${name} name`.cwd(root).quiet().nothrow();
1127
1140
  return result.exitCode === 0;
1128
1141
  }
1142
+ async function npmPublishedVersionExists(root, name, version) {
1143
+ const spec = `${name}@${version}`;
1144
+ const args = ['view', spec, 'version', '--json'];
1145
+ const result = await runResult('nix', ['shell', 'nixpkgs#nodejs_latest', '-c', 'npm', ...args], root);
1146
+ if (result.exitCode === 0) {
1147
+ return true;
1148
+ }
1149
+ if (/\bE404\b|404 Not Found/i.test(`${result.stdout}\n${result.stderr}`)) {
1150
+ return false;
1151
+ }
1152
+ throw new Error(npmCommandFailedMessage(args, result.exitCode, result.stdout, result.stderr));
1153
+ }
1129
1154
  async function assertCleanGitTree(root) {
1130
1155
  const result = await $ `git status --porcelain --untracked-files=no`.cwd(root).quiet().nothrow();
1131
1156
  if (result.exitCode !== 0) {
@@ -0,0 +1,87 @@
1
+ import type { LiveKvNamespace } from './environment.js';
2
+ export interface R2Bucket {
3
+ name: string;
4
+ }
5
+ export interface WorkerScript {
6
+ id: string;
7
+ }
8
+ export interface WorkerRoute {
9
+ id: string;
10
+ pattern: string;
11
+ script?: string;
12
+ }
13
+ export interface WorkerDomain {
14
+ id: string;
15
+ hostname: string;
16
+ service?: string;
17
+ }
18
+ export interface CloudflareZone {
19
+ id: string;
20
+ name: string;
21
+ }
22
+ export interface DnsRecord {
23
+ id: string;
24
+ name: string;
25
+ type: string;
26
+ content: string;
27
+ proxied?: boolean;
28
+ }
29
+ export interface CloudflareClient {
30
+ listKvNamespaces(): Promise<LiveKvNamespace[]>;
31
+ createKvNamespace(title: string): Promise<LiveKvNamespace>;
32
+ deleteKvNamespace(id: string): Promise<void>;
33
+ listR2Buckets(): Promise<R2Bucket[]>;
34
+ createR2Bucket(name: string): Promise<void>;
35
+ listR2Objects(bucket: string): Promise<string[]>;
36
+ deleteR2Object(bucket: string, key: string): Promise<void>;
37
+ deleteR2Bucket(name: string): Promise<void>;
38
+ listWorkerScripts(): Promise<WorkerScript[]>;
39
+ deleteWorkerScript(name: string): Promise<void>;
40
+ listWorkerDomains(): Promise<WorkerDomain[]>;
41
+ createWorkerDomain(hostname: string, workerName: string, zoneId: string): Promise<void>;
42
+ deleteWorkerDomain(id: string): Promise<void>;
43
+ listZones(): Promise<CloudflareZone[]>;
44
+ listWorkerRoutes(zoneId: string): Promise<WorkerRoute[]>;
45
+ createWorkerRoute(zoneId: string, pattern: string, workerName: string): Promise<void>;
46
+ deleteWorkerRoute(zoneId: string, routeId: string): Promise<void>;
47
+ listDnsRecords(zoneId: string): Promise<DnsRecord[]>;
48
+ createDnsRecord(zoneId: string, name: string, content: string): Promise<void>;
49
+ deleteDnsRecord(zoneId: string, recordId: string): Promise<void>;
50
+ }
51
+ export declare class CloudflareApiError extends Error {
52
+ readonly status: number;
53
+ readonly codes: number[];
54
+ constructor(message: string, status: number, codes: number[]);
55
+ }
56
+ type CloudflareFetcher = (input: string, init?: RequestInit) => Promise<Response>;
57
+ export declare class CloudflareRestClient implements CloudflareClient {
58
+ private readonly apiToken;
59
+ private readonly fetcher;
60
+ private readonly accountPath;
61
+ constructor(accountId: string, apiToken: string, fetcher?: CloudflareFetcher);
62
+ listKvNamespaces(): Promise<LiveKvNamespace[]>;
63
+ createKvNamespace(title: string): Promise<LiveKvNamespace>;
64
+ deleteKvNamespace(id: string): Promise<void>;
65
+ listR2Buckets(): Promise<R2Bucket[]>;
66
+ createR2Bucket(name: string): Promise<void>;
67
+ listR2Objects(bucket: string): Promise<string[]>;
68
+ deleteR2Object(bucket: string, key: string): Promise<void>;
69
+ deleteR2Bucket(name: string): Promise<void>;
70
+ listWorkerScripts(): Promise<WorkerScript[]>;
71
+ deleteWorkerScript(name: string): Promise<void>;
72
+ listWorkerDomains(): Promise<WorkerDomain[]>;
73
+ createWorkerDomain(hostname: string, workerName: string, zoneId: string): Promise<void>;
74
+ deleteWorkerDomain(id: string): Promise<void>;
75
+ listZones(): Promise<CloudflareZone[]>;
76
+ listWorkerRoutes(zoneId: string): Promise<WorkerRoute[]>;
77
+ createWorkerRoute(zoneId: string, pattern: string, workerName: string): Promise<void>;
78
+ deleteWorkerRoute(zoneId: string, routeId: string): Promise<void>;
79
+ listDnsRecords(zoneId: string): Promise<DnsRecord[]>;
80
+ createDnsRecord(zoneId: string, name: string, content: string): Promise<void>;
81
+ deleteDnsRecord(zoneId: string, recordId: string): Promise<void>;
82
+ private listPageItems;
83
+ private result;
84
+ private request;
85
+ }
86
+ export {};
87
+ //# sourceMappingURL=cloudflare.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloudflare.d.ts","sourceRoot":"","sources":["../../src/wrangler/cloudflare.ts"],"names":[],"mappings":"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"}