@donotdev/cli 0.0.19 → 0.0.21

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 (128) hide show
  1. package/README.md +31 -0
  2. package/dependencies-matrix.json +205 -50
  3. package/dist/bin/commands/agent-setup.js +2 -2
  4. package/dist/bin/commands/build.js +6 -6
  5. package/dist/bin/commands/bump.js +495 -70
  6. package/dist/bin/commands/cacheout.js +6 -6
  7. package/dist/bin/commands/coach.js +6 -6
  8. package/dist/bin/commands/create-app.js +24 -16
  9. package/dist/bin/commands/create-project.js +114 -18
  10. package/dist/bin/commands/db.js +142136 -0
  11. package/dist/bin/commands/deploy.js +354 -126
  12. package/dist/bin/commands/dev.js +6 -6
  13. package/dist/bin/commands/doctor.js +140 -33
  14. package/dist/bin/commands/emu.js +6 -6
  15. package/dist/bin/commands/format.js +6 -6
  16. package/dist/bin/commands/get-demo.js +11 -6
  17. package/dist/bin/commands/make-admin.js +14210 -13770
  18. package/dist/bin/commands/preview.js +6 -6
  19. package/dist/bin/commands/seed.js +142426 -0
  20. package/dist/bin/commands/setup-cicd.js +8904 -0
  21. package/dist/bin/commands/setup.js +259 -212
  22. package/dist/bin/commands/staging.js +361 -127
  23. package/dist/bin/commands/sync-secrets.js +55 -33
  24. package/dist/bin/commands/type-check.js +16 -10
  25. package/dist/bin/commands/wai.js +6 -6
  26. package/dist/bin/dndev.js +194 -188
  27. package/dist/bin/donotdev.js +139 -189
  28. package/dist/index.js +468 -144
  29. package/package.json +1 -1
  30. package/templates/app-demo/.env.example +1 -0
  31. package/templates/{root-consumer → app-demo}/entities/ExampleEntity.ts.example +15 -9
  32. package/templates/app-demo/index.html.example +1 -1
  33. package/templates/app-demo/public/apple-touch-icon.png.example +0 -0
  34. package/templates/app-demo/public/favicon.svg.example +1 -0
  35. package/templates/app-demo/public/icon-192x192.png.example +0 -0
  36. package/templates/app-demo/public/icon-512x512.png.example +0 -0
  37. package/templates/app-demo/src/App.tsx.example +3 -1
  38. package/templates/app-demo/src/config/app.ts.example +1 -0
  39. package/templates/app-demo/src/entities/booking.ts.example +75 -0
  40. package/templates/app-demo/src/entities/onboarding.ts.example +160 -0
  41. package/templates/app-demo/src/entities/product.ts.example +12 -0
  42. package/templates/app-demo/src/entities/quote.ts.example +70 -0
  43. package/templates/app-demo/src/pages/ChangelogPage.tsx.example +28 -1
  44. package/templates/app-demo/src/pages/ConditionalFormPage.tsx.example +88 -0
  45. package/templates/app-demo/src/pages/DashboardPage.tsx.example +2 -0
  46. package/templates/app-demo/src/pages/HomePage.tsx.example +355 -2
  47. package/templates/app-demo/src/pages/OnboardingPage.tsx.example +47 -0
  48. package/templates/app-demo/src/pages/PricingPage.tsx.example +28 -1
  49. package/templates/app-demo/src/pages/ProductsPage.tsx.example +2 -0
  50. package/templates/app-demo/src/pages/ProfilePage.tsx.example +2 -0
  51. package/templates/app-demo/src/pages/SettingsPage.tsx.example +2 -0
  52. package/templates/app-demo/src/pages/ShowcaseDetailPage.tsx.example +22 -16
  53. package/templates/app-demo/src/pages/ShowcasePage.tsx.example +3 -1
  54. package/templates/app-demo/src/pages/components/ComponentRenderer.tsx.example +147 -51
  55. package/templates/app-demo/src/pages/components/ComponentsData.tsx.example +103 -21
  56. package/templates/app-demo/src/pages/components/componentConfig.ts.example +139 -59
  57. package/templates/app-demo/src/pages/legal/LegalPage.tsx.example +12 -1
  58. package/templates/app-demo/src/pages/legal/PrivacyPage.tsx.example +10 -1
  59. package/templates/app-demo/src/pages/legal/TermsPage.tsx.example +10 -1
  60. package/templates/app-demo/src/themes.css.example +289 -77
  61. package/templates/app-demo/stats.html.example +4949 -0
  62. package/templates/app-dndev/index.html.example +164 -0
  63. package/templates/app-dndev/public/logo.svg.example +1 -0
  64. package/templates/app-dndev/public/manifest.json.example +10 -0
  65. package/templates/app-dndev/src/App.tsx.example +35 -0
  66. package/templates/app-dndev/src/components/CockpitLayout.css.example +181 -0
  67. package/templates/app-dndev/src/components/CockpitLayout.tsx.example +209 -0
  68. package/templates/app-dndev/src/components/Kanban.css.example +385 -0
  69. package/templates/app-dndev/src/components/ModeToggle.tsx.example +32 -0
  70. package/templates/app-dndev/src/components/OverlaySlot.tsx.example +68 -0
  71. package/templates/app-dndev/src/components/TerminalPanel.css.example +228 -0
  72. package/templates/app-dndev/src/components/TerminalPanel.tsx.example +714 -0
  73. package/templates/app-dndev/src/components/markdown-prose.css.example +49 -0
  74. package/templates/app-dndev/src/components/phases/CaptainLog.tsx.example +107 -0
  75. package/templates/app-dndev/src/components/phases/ContextTabs.tsx.example +352 -0
  76. package/templates/app-dndev/src/components/phases/PhaseCard.tsx.example +126 -0
  77. package/templates/app-dndev/src/components/phases/PhaseDetail.tsx.example +147 -0
  78. package/templates/app-dndev/src/components/phases/ReviewPanel.tsx.example +115 -0
  79. package/templates/app-dndev/src/components/phases/phaseData.ts.example +366 -0
  80. package/templates/app-dndev/src/config/app.ts.example +103 -0
  81. package/templates/app-dndev/src/config/commands.ts.example +171 -0
  82. package/templates/app-dndev/src/config/legal.ts.example +170 -0
  83. package/templates/app-dndev/src/config/providers.ts.example +7 -0
  84. package/templates/app-dndev/src/globals.css.example +10 -0
  85. package/templates/app-dndev/src/hooks/useDndevFile.ts.example +144 -0
  86. package/templates/app-dndev/src/main.tsx.example +21 -0
  87. package/templates/app-dndev/src/pages/BoardPage.tsx.example +640 -0
  88. package/templates/app-dndev/src/pages/GrillPage.tsx.example +658 -0
  89. package/templates/app-dndev/src/pages/HomePage.tsx.example +347 -0
  90. package/templates/app-dndev/src/pages/NotFoundPage.tsx.example +33 -0
  91. package/templates/app-dndev/src/pages/PhasesPage.tsx.example +137 -0
  92. package/templates/app-dndev/src/pages/SettingsPage.tsx.example +64 -0
  93. package/templates/app-dndev/src/pages/legal/LegalNoticePage.tsx.example +75 -0
  94. package/templates/app-dndev/src/pages/legal/PrivacyPage.tsx.example +69 -0
  95. package/templates/app-dndev/src/pages/legal/TermsPage.tsx.example +71 -0
  96. package/templates/app-dndev/src/stores/dndevStore.ts.example +386 -0
  97. package/templates/app-dndev/src/themes.css.example +161 -0
  98. package/templates/app-dndev/terminal-sidecar.cjs.example +341 -0
  99. package/templates/app-dndev/tsconfig.json.example +9 -0
  100. package/templates/app-dndev/vite.config.ts.example +24 -0
  101. package/templates/app-vite/index.html.example +1 -1
  102. package/templates/functions-supabase/supabase/functions/.env.example +0 -2
  103. package/templates/root-consumer/.claude/commands/grill.md.example +86 -8
  104. package/templates/root-consumer/.dndev.secrets.example +32 -0
  105. package/templates/root-consumer/.gitignore.example +3 -0
  106. package/templates/root-consumer/AI.md.example +4 -0
  107. package/templates/root-consumer/entities/index.ts.example +2 -5
  108. package/templates/root-consumer/guides/dndev/COMPONENTS_ATOMIC.md.example +4 -0
  109. package/templates/root-consumer/guides/dndev/ENV_SETUP.md.example +23 -20
  110. package/templates/root-consumer/guides/dndev/INDEX.md.example +1 -0
  111. package/templates/root-consumer/guides/dndev/SETUP_BILLING.md.example +3 -7
  112. package/templates/root-consumer/guides/dndev/SETUP_CICD.md.example +115 -0
  113. package/templates/root-consumer/guides/dndev/SETUP_CRUD.md.example +41 -0
  114. package/templates/root-consumer/guides/dndev/SETUP_SUPABASE.md.example +13 -18
  115. package/templates/root-consumer/guides/dndev/SETUP_VERCEL.md.example +17 -12
  116. package/templates/root-consumer/guides/wai-way/WAI_WAY_CLI.md.example +185 -251
  117. package/templates/root-consumer/guides/wai-way/agents/extractor.md.example +26 -8
  118. package/templates/root-consumer/guides/wai-way/blueprints/0_brainstorm.md.example +66 -49
  119. package/templates/root-consumer/guides/wai-way/blueprints/1_scaffold.md.example +6 -5
  120. package/templates/root-consumer/guides/wai-way/blueprints/2_entities.md.example +9 -9
  121. package/templates/root-consumer/guides/wai-way/blueprints/3_compose.md.example +1 -1
  122. package/templates/root-consumer/guides/wai-way/blueprints/4_configure.md.example +7 -6
  123. package/templates/root-consumer/guides/wai-way/context_map.json.example +51 -20
  124. package/templates/root-consumer/guides/wai-way/hld_template.md.example +138 -0
  125. package/templates/root-consumer/guides/wai-way/lld_template.md.example +103 -0
  126. package/templates/root-consumer/guides/wai-way/prd_template.md.example +140 -0
  127. /package/templates/{root-consumer → app-demo}/entities/Contact.ts.example +0 -0
  128. /package/templates/{root-consumer → app-demo}/entities/demo.ts.example +0 -0
@@ -3209,9 +3209,9 @@ var require_parse2 = __commonJS({
3209
3209
  const idx = prev.value.lastIndexOf("[");
3210
3210
  const pre = prev.value.slice(0, idx);
3211
3211
  const rest2 = prev.value.slice(idx + 2);
3212
- const posix = POSIX_REGEX_SOURCE[rest2];
3213
- if (posix) {
3214
- prev.value = pre + posix;
3212
+ const posix2 = POSIX_REGEX_SOURCE[rest2];
3213
+ if (posix2) {
3214
+ prev.value = pre + posix2;
3215
3215
  state.backtrack = true;
3216
3216
  advance();
3217
3217
  if (!bos.output && tokens.indexOf(prev) === 1) {
@@ -3733,7 +3733,7 @@ var require_picomatch = __commonJS({
3733
3733
  throw new TypeError("Expected pattern to be a non-empty string");
3734
3734
  }
3735
3735
  const opts = options || {};
3736
- const posix = utils.isWindows(options);
3736
+ const posix2 = utils.isWindows(options);
3737
3737
  const regex = isState ? picomatch.compileRe(glob, options) : picomatch.makeRe(glob, options, false, true);
3738
3738
  const state = regex.state;
3739
3739
  delete regex.state;
@@ -3743,8 +3743,8 @@ var require_picomatch = __commonJS({
3743
3743
  isIgnored = picomatch(opts.ignore, ignoreOpts, returnState);
3744
3744
  }
3745
3745
  const matcher = (input, returnObject = false) => {
3746
- const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix });
3747
- const result = { glob, state, regex, posix, input, output, match, isMatch };
3746
+ const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix: posix2 });
3747
+ const result = { glob, state, regex, posix: posix2, input, output, match, isMatch };
3748
3748
  if (typeof opts.onResult === "function") {
3749
3749
  opts.onResult(result);
3750
3750
  }
@@ -3769,7 +3769,7 @@ var require_picomatch = __commonJS({
3769
3769
  }
3770
3770
  return matcher;
3771
3771
  };
3772
- picomatch.test = (input, regex, options, { glob, posix } = {}) => {
3772
+ picomatch.test = (input, regex, options, { glob, posix: posix2 } = {}) => {
3773
3773
  if (typeof input !== "string") {
3774
3774
  throw new TypeError("Expected input to be a string");
3775
3775
  }
@@ -3777,7 +3777,7 @@ var require_picomatch = __commonJS({
3777
3777
  return { isMatch: false, output: "" };
3778
3778
  }
3779
3779
  const opts = options || {};
3780
- const format = opts.format || (posix ? utils.toPosixSlashes : null);
3780
+ const format = opts.format || (posix2 ? utils.toPosixSlashes : null);
3781
3781
  let match = input === glob;
3782
3782
  let output = match && format ? format(input) : input;
3783
3783
  if (match === false) {
@@ -3786,14 +3786,14 @@ var require_picomatch = __commonJS({
3786
3786
  }
3787
3787
  if (match === false || opts.capture === true) {
3788
3788
  if (opts.matchBase === true || opts.basename === true) {
3789
- match = picomatch.matchBase(input, regex, options, posix);
3789
+ match = picomatch.matchBase(input, regex, options, posix2);
3790
3790
  } else {
3791
3791
  match = regex.exec(output);
3792
3792
  }
3793
3793
  }
3794
3794
  return { isMatch: Boolean(match), match, output };
3795
3795
  };
3796
- picomatch.matchBase = (input, glob, options, posix = utils.isWindows(options)) => {
3796
+ picomatch.matchBase = (input, glob, options, posix2 = utils.isWindows(options)) => {
3797
3797
  const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options);
3798
3798
  return regex.test(path.basename(input));
3799
3799
  };
@@ -3984,9 +3984,9 @@ var require_micromatch = __commonJS({
3984
3984
  return [].concat(patterns).every((p2) => picomatch(p2, options)(str));
3985
3985
  };
3986
3986
  micromatch.capture = (glob, input, options) => {
3987
- let posix = utils.isWindows(options);
3987
+ let posix2 = utils.isWindows(options);
3988
3988
  let regex = picomatch.makeRe(String(glob), { ...options, capture: true });
3989
- let match = regex.exec(posix ? utils.toPosixSlashes(input) : input);
3989
+ let match = regex.exec(posix2 ? utils.toPosixSlashes(input) : input);
3990
3990
  if (match) {
3991
3991
  return match.slice(1).map((v2) => v2 === void 0 ? "" : v2);
3992
3992
  }
@@ -4166,15 +4166,15 @@ var require_pattern = __commonJS({
4166
4166
  exports.removeDuplicateSlashes = removeDuplicateSlashes;
4167
4167
  function partitionAbsoluteAndRelative(patterns) {
4168
4168
  const absolute = [];
4169
- const relative3 = [];
4169
+ const relative4 = [];
4170
4170
  for (const pattern of patterns) {
4171
4171
  if (isAbsolute(pattern)) {
4172
4172
  absolute.push(pattern);
4173
4173
  } else {
4174
- relative3.push(pattern);
4174
+ relative4.push(pattern);
4175
4175
  }
4176
4176
  }
4177
- return [absolute, relative3];
4177
+ return [absolute, relative4];
4178
4178
  }
4179
4179
  exports.partitionAbsoluteAndRelative = partitionAbsoluteAndRelative;
4180
4180
  function isAbsolute(pattern) {
@@ -4484,7 +4484,7 @@ var require_async = __commonJS({
4484
4484
  callSuccessCallback(callback, lstat);
4485
4485
  return;
4486
4486
  }
4487
- settings.fs.stat(path, (statError, stat) => {
4487
+ settings.fs.stat(path, (statError, stat2) => {
4488
4488
  if (statError !== null) {
4489
4489
  if (settings.throwErrorOnBrokenSymbolicLink) {
4490
4490
  callFailureCallback(callback, statError);
@@ -4494,9 +4494,9 @@ var require_async = __commonJS({
4494
4494
  return;
4495
4495
  }
4496
4496
  if (settings.markSymbolicLink) {
4497
- stat.isSymbolicLink = () => true;
4497
+ stat2.isSymbolicLink = () => true;
4498
4498
  }
4499
- callSuccessCallback(callback, stat);
4499
+ callSuccessCallback(callback, stat2);
4500
4500
  });
4501
4501
  });
4502
4502
  }
@@ -4523,11 +4523,11 @@ var require_sync = __commonJS({
4523
4523
  return lstat;
4524
4524
  }
4525
4525
  try {
4526
- const stat = settings.fs.statSync(path);
4526
+ const stat2 = settings.fs.statSync(path);
4527
4527
  if (settings.markSymbolicLink) {
4528
- stat.isSymbolicLink = () => true;
4528
+ stat2.isSymbolicLink = () => true;
4529
4529
  }
4530
- return stat;
4530
+ return stat2;
4531
4531
  } catch (error2) {
4532
4532
  if (!settings.throwErrorOnBrokenSymbolicLink) {
4533
4533
  return lstat;
@@ -4597,14 +4597,14 @@ var require_out = __commonJS({
4597
4597
  var sync = require_sync();
4598
4598
  var settings_1 = require_settings();
4599
4599
  exports.Settings = settings_1.default;
4600
- function stat(path, optionsOrSettingsOrCallback, callback) {
4600
+ function stat2(path, optionsOrSettingsOrCallback, callback) {
4601
4601
  if (typeof optionsOrSettingsOrCallback === "function") {
4602
4602
  async.read(path, getSettings(), optionsOrSettingsOrCallback);
4603
4603
  return;
4604
4604
  }
4605
4605
  async.read(path, getSettings(optionsOrSettingsOrCallback), callback);
4606
4606
  }
4607
- exports.stat = stat;
4607
+ exports.stat = stat2;
4608
4608
  function statSync3(path, optionsOrSettings) {
4609
4609
  const settings = getSettings(optionsOrSettings);
4610
4610
  return sync.read(path, settings);
@@ -4774,7 +4774,7 @@ var require_async2 = __commonJS({
4774
4774
  readdirWithFileTypes(directory, settings, callback);
4775
4775
  return;
4776
4776
  }
4777
- readdir(directory, settings, callback);
4777
+ readdir2(directory, settings, callback);
4778
4778
  }
4779
4779
  exports.read = read;
4780
4780
  function readdirWithFileTypes(directory, settings, callback) {
@@ -4823,7 +4823,7 @@ var require_async2 = __commonJS({
4823
4823
  });
4824
4824
  };
4825
4825
  }
4826
- function readdir(directory, settings, callback) {
4826
+ function readdir2(directory, settings, callback) {
4827
4827
  settings.fs.readdir(directory, (readdirError, names) => {
4828
4828
  if (readdirError !== null) {
4829
4829
  callFailureCallback(callback, readdirError);
@@ -4858,7 +4858,7 @@ var require_async2 = __commonJS({
4858
4858
  });
4859
4859
  });
4860
4860
  }
4861
- exports.readdir = readdir;
4861
+ exports.readdir = readdir2;
4862
4862
  function callFailureCallback(callback, error2) {
4863
4863
  callback(error2);
4864
4864
  }
@@ -4883,7 +4883,7 @@ var require_sync2 = __commonJS({
4883
4883
  if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) {
4884
4884
  return readdirWithFileTypes(directory, settings);
4885
4885
  }
4886
- return readdir(directory, settings);
4886
+ return readdir2(directory, settings);
4887
4887
  }
4888
4888
  exports.read = read;
4889
4889
  function readdirWithFileTypes(directory, settings) {
@@ -4908,7 +4908,7 @@ var require_sync2 = __commonJS({
4908
4908
  });
4909
4909
  }
4910
4910
  exports.readdirWithFileTypes = readdirWithFileTypes;
4911
- function readdir(directory, settings) {
4911
+ function readdir2(directory, settings) {
4912
4912
  const names = settings.fs.readdirSync(directory);
4913
4913
  return names.map((name) => {
4914
4914
  const entryPath = common.joinPathSegments(directory, name, settings.pathSegmentSeparator);
@@ -4924,7 +4924,7 @@ var require_sync2 = __commonJS({
4924
4924
  return entry;
4925
4925
  });
4926
4926
  }
4927
- exports.readdir = readdir;
4927
+ exports.readdir = readdir2;
4928
4928
  }
4929
4929
  });
4930
4930
 
@@ -6486,19 +6486,19 @@ var require_out4 = __commonJS({
6486
6486
  return utils.path.convertPathToPattern(source);
6487
6487
  }
6488
6488
  FastGlob2.convertPathToPattern = convertPathToPattern;
6489
- let posix;
6490
- (function(posix2) {
6489
+ let posix2;
6490
+ (function(posix3) {
6491
6491
  function escapePath2(source) {
6492
6492
  assertPatternsInput(source);
6493
6493
  return utils.path.escapePosixPath(source);
6494
6494
  }
6495
- posix2.escapePath = escapePath2;
6495
+ posix3.escapePath = escapePath2;
6496
6496
  function convertPathToPattern2(source) {
6497
6497
  assertPatternsInput(source);
6498
6498
  return utils.path.convertPosixPathToPattern(source);
6499
6499
  }
6500
- posix2.convertPathToPattern = convertPathToPattern2;
6501
- })(posix = FastGlob2.posix || (FastGlob2.posix = {}));
6500
+ posix3.convertPathToPattern = convertPathToPattern2;
6501
+ })(posix2 = FastGlob2.posix || (FastGlob2.posix = {}));
6502
6502
  let win32;
6503
6503
  (function(win322) {
6504
6504
  function escapePath2(source) {
@@ -7077,7 +7077,7 @@ var init_PathResolver = __esm({
7077
7077
  }
7078
7078
  const detectedFormat = this._detectFormat(filePath, format);
7079
7079
  let writeContent;
7080
- if (Buffer2.isBuffer(content)) {
7080
+ if (Buffer.isBuffer(content)) {
7081
7081
  writeContent = content;
7082
7082
  } else if (detectedFormat === "json" && typeof content === "object") {
7083
7083
  writeContent = JSON.stringify(content, null, 2);
@@ -7086,7 +7086,7 @@ var init_PathResolver = __esm({
7086
7086
  }
7087
7087
  try {
7088
7088
  return await safeExecuteAsync(async () => {
7089
- if (Buffer2.isBuffer(writeContent)) {
7089
+ if (Buffer.isBuffer(writeContent)) {
7090
7090
  await fs.promises.writeFile(normalizedPath, writeContent);
7091
7091
  } else {
7092
7092
  await fs.promises.writeFile(normalizedPath, writeContent, "utf8");
@@ -7138,7 +7138,7 @@ var init_PathResolver = __esm({
7138
7138
  }
7139
7139
  const detectedFormat = this._detectFormat(filePath, format);
7140
7140
  let writeContent;
7141
- if (Buffer2.isBuffer(content)) {
7141
+ if (Buffer.isBuffer(content)) {
7142
7142
  writeContent = content;
7143
7143
  } else if (detectedFormat === "json" && typeof content === "object") {
7144
7144
  writeContent = JSON.stringify(content, null, 2);
@@ -7146,7 +7146,7 @@ var init_PathResolver = __esm({
7146
7146
  writeContent = String(content);
7147
7147
  }
7148
7148
  try {
7149
- if (Buffer2.isBuffer(writeContent)) {
7149
+ if (Buffer.isBuffer(writeContent)) {
7150
7150
  fs.writeFileSync(normalizedPath, writeContent);
7151
7151
  } else {
7152
7152
  fs.writeFileSync(normalizedPath, writeContent, "utf8");
@@ -7970,7 +7970,7 @@ var init_typed_file_operations = __esm({
7970
7970
  });
7971
7971
 
7972
7972
  // packages/tooling/src/bundler/utils.ts
7973
- import { Buffer as Buffer2 } from "node:buffer";
7973
+ import { Buffer } from "node:buffer";
7974
7974
  import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "node:fs";
7975
7975
  import { createRequire as createRequire3 } from "node:module";
7976
7976
  import { dirname as dirname3, resolve as resolve3 } from "node:path";
@@ -7987,7 +7987,7 @@ var init_utils = __esm({
7987
7987
  globalThis.require = require2;
7988
7988
  globalThis.__filename = __filename;
7989
7989
  globalThis.__dirname = __dirname;
7990
- globalThis.Buffer = Buffer2;
7990
+ globalThis.Buffer = Buffer;
7991
7991
  globalThis.process = process;
7992
7992
  if (typeof global === "undefined") {
7993
7993
  globalThis.global = globalThis;
@@ -8335,7 +8335,28 @@ var init_cli_tools = __esm({
8335
8335
  }
8336
8336
  });
8337
8337
 
8338
- // packages/tooling/src/cli/setup/vercel-token.ts
8338
+ // packages/tooling/src/utils/secrets-resolver.ts
8339
+ function parseEnvFile(filePath) {
8340
+ if (!pathExists(filePath)) return {};
8341
+ const content = readSync(filePath, { format: "text" });
8342
+ if (typeof content !== "string" || !content) return {};
8343
+ const result = {};
8344
+ for (const line of content.split(/\r?\n/)) {
8345
+ const trimmed = line.trim();
8346
+ if (!trimmed || trimmed.startsWith("#")) continue;
8347
+ const eqIdx = trimmed.indexOf("=");
8348
+ if (eqIdx === -1) continue;
8349
+ const key = trimmed.slice(0, eqIdx).trim();
8350
+ let value = trimmed.slice(eqIdx + 1).trim();
8351
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
8352
+ value = value.slice(1, -1);
8353
+ }
8354
+ if (key && value) {
8355
+ result[key] = value;
8356
+ }
8357
+ }
8358
+ return result;
8359
+ }
8339
8360
  function readEnvVar(filePath, varName) {
8340
8361
  if (!pathExists(filePath)) return null;
8341
8362
  const content = readSync(filePath, { format: "text" });
@@ -8344,16 +8365,93 @@ function readEnvVar(filePath, varName) {
8344
8365
  const trimmed = line.trim();
8345
8366
  if (!trimmed || trimmed.startsWith("#")) continue;
8346
8367
  if (trimmed.startsWith(`${varName}=`)) {
8347
- const val = trimmed.substring(`${varName}=`.length).trim();
8368
+ let val = trimmed.substring(`${varName}=`.length).trim();
8348
8369
  if (val.startsWith('"') && val.endsWith('"') || val.startsWith("'") && val.endsWith("'")) {
8349
- return val.slice(1, -1);
8370
+ val = val.slice(1, -1);
8350
8371
  }
8351
8372
  return val || null;
8352
8373
  }
8353
8374
  }
8354
8375
  return null;
8355
8376
  }
8356
- function resolveVercelVar(appDir, varName) {
8377
+ function loadDndevSecrets(projectRoot) {
8378
+ const secretsPath = joinPath(projectRoot, ".dndev.secrets");
8379
+ if (cachedSecretsPath === secretsPath && cachedSecrets) {
8380
+ return cachedSecrets;
8381
+ }
8382
+ cachedSecrets = parseEnvFile(secretsPath);
8383
+ cachedSecretsPath = secretsPath;
8384
+ return cachedSecrets;
8385
+ }
8386
+ function resolveSecret(name, projectRoot, opts) {
8387
+ const appDir = opts?.appDir ?? projectRoot;
8388
+ const envValue = process.env[name];
8389
+ if (envValue) {
8390
+ return { value: envValue, source: "process.env" };
8391
+ }
8392
+ const secrets = loadDndevSecrets(projectRoot);
8393
+ if (secrets[name]) {
8394
+ return { value: secrets[name], source: ".dndev.secrets" };
8395
+ }
8396
+ if (name === "SUPABASE_SECRET_KEY" && secrets["SUPABASE_SERVICE_ROLE_KEY"]) {
8397
+ return {
8398
+ value: secrets["SUPABASE_SERVICE_ROLE_KEY"],
8399
+ source: ".dndev.secrets"
8400
+ };
8401
+ }
8402
+ const legacyPaths = LEGACY_PATHS[name];
8403
+ if (legacyPaths) {
8404
+ for (const relPath of legacyPaths) {
8405
+ const fullPath = joinPath(appDir, relPath);
8406
+ const value = readEnvVar(fullPath, name);
8407
+ if (value) {
8408
+ if (!opts?.silent && !warnedLegacy.has(name)) {
8409
+ warnedLegacy.add(name);
8410
+ log.warn(
8411
+ `${name} found in ${relPath} (legacy). Move it to .dndev.secrets at project root.`
8412
+ );
8413
+ }
8414
+ return { value, source: "legacy", legacyPath: relPath };
8415
+ }
8416
+ if (name === "SUPABASE_SECRET_KEY") {
8417
+ const aliasValue = readEnvVar(fullPath, "SUPABASE_SERVICE_ROLE_KEY");
8418
+ if (aliasValue) {
8419
+ if (!opts?.silent && !warnedLegacy.has(name)) {
8420
+ warnedLegacy.add(name);
8421
+ log.warn(
8422
+ `${name} found in ${relPath} (legacy). Move it to .dndev.secrets at project root.`
8423
+ );
8424
+ }
8425
+ return { value: aliasValue, source: "legacy", legacyPath: relPath };
8426
+ }
8427
+ }
8428
+ }
8429
+ }
8430
+ return null;
8431
+ }
8432
+ var LEGACY_PATHS, warnedLegacy, cachedSecretsPath, cachedSecrets;
8433
+ var init_secrets_resolver = __esm({
8434
+ "packages/tooling/src/utils/secrets-resolver.ts"() {
8435
+ "use strict";
8436
+ init_utils();
8437
+ init_pathResolver();
8438
+ init_cli_output();
8439
+ LEGACY_PATHS = {
8440
+ VERCEL_TOKEN: [".env.local"],
8441
+ SUPABASE_SECRET_KEY: ["supabase/functions/.env", "functions/.env"],
8442
+ SUPABASE_DB_URL: ["supabase/functions/.env", "functions/.env"],
8443
+ SUPABASE_ACCESS_TOKEN: ["supabase/functions/.env", "functions/.env"],
8444
+ STRIPE_SECRET_KEY: ["supabase/functions/.env", "functions/.env"],
8445
+ STRIPE_WEBHOOK_SECRET: ["supabase/functions/.env", "functions/.env"]
8446
+ };
8447
+ warnedLegacy = /* @__PURE__ */ new Set();
8448
+ cachedSecretsPath = null;
8449
+ cachedSecrets = null;
8450
+ }
8451
+ });
8452
+
8453
+ // packages/tooling/src/cli/setup/vercel-token.ts
8454
+ function resolvePerAppVar(appDir, varName) {
8357
8455
  if (process.env[varName]) return process.env[varName];
8358
8456
  const fromLocal = readEnvVar(joinPath(appDir, ".env.local"), varName);
8359
8457
  if (fromLocal) return fromLocal;
@@ -8361,10 +8459,11 @@ function resolveVercelVar(appDir, varName) {
8361
8459
  if (fromEnv) return fromEnv;
8362
8460
  return null;
8363
8461
  }
8364
- function resolveVercelCredentials(appDir) {
8365
- const token = resolveVercelVar(appDir, "VERCEL_TOKEN");
8366
- const orgId = resolveVercelVar(appDir, "VERCEL_ORG_ID");
8367
- const projectId = resolveVercelVar(appDir, "VERCEL_PROJECT_ID");
8462
+ function resolveVercelCredentials(appDir, projectRoot) {
8463
+ const root = projectRoot ?? process.cwd();
8464
+ const token = resolveSecret("VERCEL_TOKEN", root, { appDir })?.value ?? null;
8465
+ const orgId = resolvePerAppVar(appDir, "VERCEL_ORG_ID");
8466
+ const projectId = resolvePerAppVar(appDir, "VERCEL_PROJECT_ID");
8368
8467
  const missing = [];
8369
8468
  if (!token) missing.push("VERCEL_TOKEN");
8370
8469
  if (!orgId) missing.push("VERCEL_ORG_ID");
@@ -8378,6 +8477,7 @@ var init_vercel_token = __esm({
8378
8477
  "packages/tooling/src/cli/setup/vercel-token.ts"() {
8379
8478
  "use strict";
8380
8479
  init_utils();
8480
+ init_secrets_resolver();
8381
8481
  init_pathResolver();
8382
8482
  }
8383
8483
  });
@@ -15770,10 +15870,14 @@ var init_error_handling = __esm({
15770
15870
  var sync_secrets_exports = {};
15771
15871
  __export(sync_secrets_exports, {
15772
15872
  default: () => sync_secrets_default,
15773
- main: () => main
15873
+ detectGitHubRepo: () => detectGitHubRepo,
15874
+ main: () => main,
15875
+ parseSecretsWithFallback: () => parseSecretsWithFallback,
15876
+ setGitHubSecret: () => setGitHubSecret,
15877
+ uploadServiceAccountToGitHub: () => uploadServiceAccountToGitHub
15774
15878
  });
15775
- import { spawnSync as spawnSync6 } from "node:child_process";
15776
- function parseEnvFile(filePath) {
15879
+ import { spawnSync as spawnSync5 } from "node:child_process";
15880
+ function parseEnvFile2(filePath) {
15777
15881
  if (!pathExists(filePath)) {
15778
15882
  throw new DoNotDevError(
15779
15883
  `Environment file not found: ${filePath}`,
@@ -15781,30 +15885,22 @@ function parseEnvFile(filePath) {
15781
15885
  { context: { filePath } }
15782
15886
  );
15783
15887
  }
15784
- const contentRaw = readSync(filePath, { format: "text" });
15785
- const content = typeof contentRaw === "string" ? contentRaw : null;
15786
- if (!content) {
15787
- throw new Error(`Failed to read secrets file: ${filePath}`);
15888
+ const result = parseEnvFile(filePath);
15889
+ if (Object.keys(result).length === 0) {
15890
+ log.debug(`No key-value pairs found in ${filePath}`);
15788
15891
  }
15789
- const secrets = {};
15790
- content.split("\n").forEach((line, index) => {
15791
- const trimmedLine = line.trim();
15792
- if (!trimmedLine || trimmedLine.startsWith("#")) {
15793
- return;
15794
- }
15795
- const equalIndex = trimmedLine.indexOf("=");
15796
- if (equalIndex === -1) {
15797
- log.warn(`Invalid line format at line ${index + 1}: ${trimmedLine}`);
15798
- return;
15799
- }
15800
- const key = trimmedLine.substring(0, equalIndex).trim();
15801
- const value = trimmedLine.substring(equalIndex + 1).trim();
15802
- const cleanValue = value.replace(/^["']|["']$/g, "");
15803
- if (key && cleanValue) {
15804
- secrets[key] = cleanValue;
15892
+ return result;
15893
+ }
15894
+ function parseSecretsWithFallback(envFilePath, projectRoot) {
15895
+ const dndevSecretsPath = joinPath(projectRoot, ".dndev.secrets");
15896
+ if (pathExists(dndevSecretsPath)) {
15897
+ const secrets = parseEnvFile(dndevSecretsPath);
15898
+ if (Object.keys(secrets).length > 0) {
15899
+ log.info(`Reading secrets from: ${dndevSecretsPath}`);
15900
+ return secrets;
15805
15901
  }
15806
- });
15807
- return secrets;
15902
+ }
15903
+ return parseEnvFile2(envFilePath);
15808
15904
  }
15809
15905
  function detectPlatform() {
15810
15906
  const currentDir = process.cwd();
@@ -15895,8 +15991,8 @@ function detectAppsWithFunctions() {
15895
15991
  try {
15896
15992
  const appsList = readdirSync2(appsDir).filter((item) => {
15897
15993
  const itemPath = joinPath(appsDir, item);
15898
- const stat = statSync2(itemPath);
15899
- return stat?.isDirectory() === true;
15994
+ const stat2 = statSync2(itemPath);
15995
+ return stat2?.isDirectory() === true;
15900
15996
  });
15901
15997
  for (const app of appsList) {
15902
15998
  const functionsEnvFile = joinPath(appsDir, app, "functions", ".env");
@@ -15962,7 +16058,7 @@ async function setFirebaseSecret(key, value, projectId, dryRun = false, cwd) {
15962
16058
  NODE_OPTIONS: ""
15963
16059
  // Clear to avoid conflicts
15964
16060
  };
15965
- const result = spawnSync6(firebaseCmd, args, {
16061
+ const result = spawnSync5(firebaseCmd, args, {
15966
16062
  input: value,
15967
16063
  encoding: "utf8",
15968
16064
  stdio: ["pipe", "pipe", "pipe"],
@@ -16055,7 +16151,7 @@ function setVercelSecret(key, value, projectId, dryRun = false) {
16055
16151
  if (projectId) {
16056
16152
  args.push("--project", projectId);
16057
16153
  }
16058
- const result = spawnSync6("vercel", args, {
16154
+ const result = spawnSync5("vercel", args, {
16059
16155
  input: value,
16060
16156
  encoding: "utf8",
16061
16157
  stdio: ["pipe", "inherit", "inherit"]
@@ -16084,7 +16180,7 @@ function setVercelSecret(key, value, projectId, dryRun = false) {
16084
16180
  }
16085
16181
  function detectGitHubRepo() {
16086
16182
  try {
16087
- const result = spawnSync6("git", ["remote", "get-url", "origin"], {
16183
+ const result = spawnSync5("git", ["remote", "get-url", "origin"], {
16088
16184
  encoding: "utf8",
16089
16185
  stdio: ["pipe", "pipe", "pipe"]
16090
16186
  });
@@ -16112,7 +16208,7 @@ function setGitHubSecret(key, value, repo, dryRun = false) {
16112
16208
  if (repo) {
16113
16209
  args.push("--repo", repo);
16114
16210
  }
16115
- const result = spawnSync6("gh", args, {
16211
+ const result = spawnSync5("gh", args, {
16116
16212
  input: value,
16117
16213
  encoding: "utf8",
16118
16214
  stdio: ["pipe", "pipe", "pipe"]
@@ -16164,7 +16260,7 @@ function uploadServiceAccountToGitHub(appDir, repo, dryRun = false, staging = fa
16164
16260
  const contentRaw = readSync(filePath, { format: "text" });
16165
16261
  const content = typeof contentRaw === "string" ? contentRaw : null;
16166
16262
  if (!content) return;
16167
- const encoded = Buffer2.from(content).toString("base64");
16263
+ const encoded = Buffer.from(content).toString("base64");
16168
16264
  setGitHubSecret(secretName, encoded, repo, dryRun);
16169
16265
  }
16170
16266
  async function main(options = {}) {
@@ -16251,7 +16347,7 @@ Examples:
16251
16347
  return 1;
16252
16348
  }
16253
16349
  log.info(`Syncing secrets to GitHub repository: ${repo}`);
16254
- const secrets2 = parseEnvFile(envFilePath);
16350
+ const secrets2 = parseSecretsWithFallback(envFilePath, currentDir);
16255
16351
  const secretKeys2 = Object.keys(secrets2);
16256
16352
  if (secretKeys2.length === 0) {
16257
16353
  log.info("No secrets found in .env file");
@@ -16287,14 +16383,13 @@ Examples:
16287
16383
  return 0;
16288
16384
  }
16289
16385
  const platform = config.platform || detectPlatform();
16290
- log.info(`Reading secrets from: ${envFilePath}`);
16291
16386
  if (config.verbose) {
16292
16387
  log.debug(`Working directory: ${currentDir}`);
16293
16388
  log.debug(`Environment file: ${envFilePath}`);
16294
16389
  log.debug(`Platform: ${platform}`);
16295
16390
  log.debug(`Dry run mode: ${config.dryRun}`);
16296
16391
  }
16297
- const secrets = parseEnvFile(envFilePath);
16392
+ const secrets = parseSecretsWithFallback(envFilePath, currentDir);
16298
16393
  const secretKeys = Object.keys(secrets);
16299
16394
  if (secretKeys.length === 0) {
16300
16395
  log.info("No secrets found in .env file");
@@ -16355,6 +16450,7 @@ var init_sync_secrets = __esm({
16355
16450
  init_cli_output();
16356
16451
  init_errors();
16357
16452
  init_pathResolver();
16453
+ init_secrets_resolver();
16358
16454
  sync_secrets_default = main;
16359
16455
  }
16360
16456
  });
@@ -16380,8 +16476,8 @@ async function deploySupabaseFunctions(appDir, config) {
16380
16476
  );
16381
16477
  const functionDirs = readdirSync2(functionsDir).filter((item) => {
16382
16478
  const itemPath = joinPath(functionsDir, item);
16383
- const stat = statSync2(itemPath);
16384
- return stat?.isDirectory() === true;
16479
+ const stat2 = statSync2(itemPath);
16480
+ return stat2?.isDirectory() === true;
16385
16481
  }).filter((dir) => {
16386
16482
  const indexPath = joinPath(functionsDir, dir, "index.ts");
16387
16483
  return pathExists(indexPath);
@@ -16603,48 +16699,168 @@ async function deployFrontend(appDir, serviceAccountPath, projectId, config) {
16603
16699
  init_utils();
16604
16700
  init_cli_output();
16605
16701
  init_vercel_token();
16606
- import { spawnSync as spawnSync3 } from "node:child_process";
16702
+ init_pathResolver();
16703
+ import { createHash } from "node:crypto";
16704
+ import { readFile, readdir } from "node:fs/promises";
16705
+ import { join as join3, relative as relative3 } from "node:path";
16706
+ var VERCEL_API = "https://api.vercel.com";
16707
+ var UPLOAD_BATCH_SIZE = 10;
16708
+ var POLL_INTERVAL_MS = 3e3;
16709
+ var POLL_MAX_ATTEMPTS = 100;
16710
+ function apiHeaders(token, extra) {
16711
+ return { Authorization: `Bearer ${token}`, ...extra };
16712
+ }
16713
+ function teamQuery(orgId) {
16714
+ return `?teamId=${encodeURIComponent(orgId)}`;
16715
+ }
16716
+ async function collectDistFiles(distDir) {
16717
+ const files = [];
16718
+ async function walk(dir) {
16719
+ const entries = await readdir(dir, { withFileTypes: true });
16720
+ for (const entry of entries) {
16721
+ const fullPath = join3(dir, entry.name);
16722
+ if (entry.isDirectory()) {
16723
+ await walk(fullPath);
16724
+ } else {
16725
+ const content = await readFile(fullPath);
16726
+ const sha = createHash("sha1").update(content).digest("hex");
16727
+ const rel = relative3(distDir, fullPath).split("\\").join("/");
16728
+ files.push({
16729
+ relativePath: rel,
16730
+ content,
16731
+ sha,
16732
+ size: content.byteLength
16733
+ });
16734
+ }
16735
+ }
16736
+ }
16737
+ await walk(distDir);
16738
+ return files;
16739
+ }
16740
+ async function uploadFiles(files, token, orgId) {
16741
+ const q2 = teamQuery(orgId);
16742
+ for (let i = 0; i < files.length; i += UPLOAD_BATCH_SIZE) {
16743
+ const batch = files.slice(i, i + UPLOAD_BATCH_SIZE);
16744
+ await Promise.all(
16745
+ batch.map(async (file) => {
16746
+ const res = await fetch(`${VERCEL_API}/v2/files${q2}`, {
16747
+ method: "POST",
16748
+ headers: apiHeaders(token, {
16749
+ "Content-Type": "application/octet-stream",
16750
+ "x-vercel-digest": file.sha,
16751
+ "Content-Length": String(file.size)
16752
+ }),
16753
+ body: new Uint8Array(file.content)
16754
+ });
16755
+ if (!res.ok) {
16756
+ const body = await res.text();
16757
+ throw new Error(
16758
+ `File upload failed for ${file.relativePath} (${res.status}): ${body}`
16759
+ );
16760
+ }
16761
+ })
16762
+ );
16763
+ }
16764
+ }
16765
+ async function createDeployment(files, token, orgId, projectId) {
16766
+ const q2 = teamQuery(orgId);
16767
+ const body = {
16768
+ project: projectId,
16769
+ target: "production",
16770
+ files: files.map((f) => ({
16771
+ file: f.relativePath,
16772
+ sha: f.sha,
16773
+ size: f.size
16774
+ })),
16775
+ projectSettings: {
16776
+ buildCommand: "",
16777
+ installCommand: "",
16778
+ outputDirectory: "."
16779
+ }
16780
+ };
16781
+ const res = await fetch(`${VERCEL_API}/v13/deployments${q2}`, {
16782
+ method: "POST",
16783
+ headers: apiHeaders(token, { "Content-Type": "application/json" }),
16784
+ body: JSON.stringify(body)
16785
+ });
16786
+ if (!res.ok) {
16787
+ const text = await res.text();
16788
+ throw new Error(`Create deployment failed (${res.status}): ${text}`);
16789
+ }
16790
+ return await res.json();
16791
+ }
16792
+ async function waitForReady(deploymentId, token, orgId) {
16793
+ const q2 = teamQuery(orgId);
16794
+ for (let attempt = 0; attempt < POLL_MAX_ATTEMPTS; attempt++) {
16795
+ const res = await fetch(
16796
+ `${VERCEL_API}/v13/deployments/${deploymentId}${q2}`,
16797
+ { headers: apiHeaders(token) }
16798
+ );
16799
+ if (!res.ok) {
16800
+ const text = await res.text();
16801
+ throw new Error(
16802
+ `Deployment status check failed (${res.status}): ${text}`
16803
+ );
16804
+ }
16805
+ const data = await res.json();
16806
+ if (data.readyState === "READY") return data;
16807
+ if (data.readyState === "ERROR") {
16808
+ throw new Error(
16809
+ `Deployment failed: ${data.errorMessage || "Unknown error"}`
16810
+ );
16811
+ }
16812
+ if (data.readyState === "CANCELED") {
16813
+ throw new Error("Deployment was canceled");
16814
+ }
16815
+ await new Promise((r2) => setTimeout(r2, POLL_INTERVAL_MS));
16816
+ }
16817
+ throw new Error("Deployment timed out (5+ minutes)");
16818
+ }
16607
16819
  async function deployVercelFrontend(appDir, _config) {
16608
16820
  const result = resolveVercelCredentials(appDir);
16609
16821
  if (result.missing) {
16822
+ const secretVars = result.missing.filter((v2) => v2 === "VERCEL_TOKEN");
16823
+ const appVars = result.missing.filter((v2) => v2 !== "VERCEL_TOKEN");
16824
+ const hints = [];
16825
+ if (secretVars.length > 0)
16826
+ hints.push("Add VERCEL_TOKEN to .dndev.secrets at project root.");
16827
+ if (appVars.length > 0)
16828
+ hints.push(`Add ${appVars.join(", ")} to apps/<app>/.env`);
16610
16829
  throw new Error(
16611
- `Missing Vercel credentials in .env.local: ${result.missing.join(", ")}
16612
- Add them to apps/<app>/.env.local \u2014 see guides/dndev/SETUP_VERCEL.md`
16830
+ `Missing Vercel credentials: ${result.missing.join(", ")}
16831
+ ` + hints.join("\n") + "\nSee guides/dndev/SETUP_VERCEL.md"
16613
16832
  );
16614
16833
  }
16615
16834
  const { token, orgId, projectId } = result.credentials;
16616
- log.debug("Using Vercel credentials from .env (token-based auth)");
16617
- log.info("Deploying to Vercel...");
16618
- const deployResult = spawnSync3(
16619
- "bunx",
16620
- ["vercel", "deploy", "--prod", "--yes", "--token", token],
16621
- {
16622
- cwd: appDir,
16623
- // stdout piped to capture deployment URL, stderr inherits for progress
16624
- stdio: ["inherit", "pipe", "inherit"],
16625
- encoding: "utf-8",
16626
- env: {
16627
- ...process.env,
16628
- VERCEL_ORG_ID: orgId,
16629
- VERCEL_PROJECT_ID: projectId
16630
- }
16631
- }
16632
- );
16633
- if (deployResult.status !== 0) {
16634
- throw new Error(`vercel deploy exited with code ${deployResult.status}`);
16635
- }
16636
- const deployUrl = deployResult.stdout?.trim();
16637
- if (deployUrl) {
16638
- log.success(`Production: ${deployUrl}`);
16639
- } else {
16640
- log.success("Frontend deployed to Vercel");
16835
+ const distDir = joinPath(appDir, "dist");
16836
+ if (!pathExists(distDir)) {
16837
+ throw new Error(`dist/ not found at ${distDir}. Run build first.`);
16838
+ }
16839
+ log.debug("Using Vercel REST API (token-based, no CLI)");
16840
+ log.info("Collecting dist/ files...");
16841
+ const files = await collectDistFiles(distDir);
16842
+ if (files.length === 0) {
16843
+ throw new Error("dist/ is empty \u2014 nothing to deploy.");
16844
+ }
16845
+ log.info(`Found ${files.length} files`);
16846
+ log.info("Uploading files to Vercel...");
16847
+ await uploadFiles(files, token, orgId);
16848
+ log.success(`${files.length} files uploaded`);
16849
+ log.info("Creating production deployment...");
16850
+ const deployment = await createDeployment(files, token, orgId, projectId);
16851
+ log.info(`Deployment ${deployment.id} created, waiting...`);
16852
+ const ready = await waitForReady(deployment.id, token, orgId);
16853
+ const prodUrl = `https://${ready.url}`;
16854
+ log.success(`Production: ${prodUrl}`);
16855
+ if (ready.alias?.length) {
16856
+ log.info(`Aliases: ${ready.alias.join(", ")}`);
16641
16857
  }
16642
16858
  }
16643
16859
 
16644
16860
  // packages/tooling/src/apps/deploy-functions.ts
16645
16861
  init_utils();
16646
16862
  var import_yaml = __toESM(require_dist(), 1);
16647
- import { execSync as execSync2, spawnSync as spawnSync4 } from "node:child_process";
16863
+ import { execSync as execSync2, spawnSync as spawnSync3 } from "node:child_process";
16648
16864
  init_pathResolver();
16649
16865
  init_cli_tools();
16650
16866
  init_typed_file_operations();
@@ -16701,6 +16917,14 @@ function generateCleanPackageJson(functionsDir) {
16701
16917
  }
16702
16918
  const cleanPackageJson = { ...packageJson };
16703
16919
  if (cleanPackageJson.dependencies) {
16920
+ const removedDeps = Object.entries(cleanPackageJson.dependencies).filter(
16921
+ ([, version]) => String(version).startsWith("file:") || String(version).startsWith("workspace:")
16922
+ );
16923
+ if (removedDeps.length > 0) {
16924
+ log.warn(
16925
+ `Filtering out ${removedDeps.length} workspace/file dep(s) from dependencies: ${removedDeps.map(([name]) => name).join(", ")}`
16926
+ );
16927
+ }
16704
16928
  cleanPackageJson.dependencies = Object.fromEntries(
16705
16929
  Object.entries(cleanPackageJson.dependencies).filter(
16706
16930
  ([, version]) => !String(version).startsWith("file:") && !String(version).startsWith("workspace:")
@@ -16708,6 +16932,16 @@ function generateCleanPackageJson(functionsDir) {
16708
16932
  );
16709
16933
  }
16710
16934
  if (cleanPackageJson.devDependencies) {
16935
+ const removedDevDeps = Object.entries(
16936
+ cleanPackageJson.devDependencies
16937
+ ).filter(
16938
+ ([, version]) => String(version).startsWith("file:") || String(version).startsWith("workspace:")
16939
+ );
16940
+ if (removedDevDeps.length > 0) {
16941
+ log.warn(
16942
+ `Filtering out ${removedDevDeps.length} workspace/file dep(s) from devDependencies: ${removedDevDeps.map(([name]) => name).join(", ")}`
16943
+ );
16944
+ }
16711
16945
  cleanPackageJson.devDependencies = Object.fromEntries(
16712
16946
  Object.entries(cleanPackageJson.devDependencies).filter(
16713
16947
  ([, version]) => !String(version).startsWith("file:") && !String(version).startsWith("workspace:")
@@ -16813,7 +17047,7 @@ function updateCloudRunIAM(functionNames, projectId, region, serviceAccountPath,
16813
17047
  let failCount = 0;
16814
17048
  for (const funcName of functionNames) {
16815
17049
  try {
16816
- const result = spawnSync4(
17050
+ const result = spawnSync3(
16817
17051
  "gcloud",
16818
17052
  [
16819
17053
  "run",
@@ -16931,7 +17165,7 @@ async function autoSyncSecrets(functionsDir, projectId, config) {
16931
17165
  let failCount = 0;
16932
17166
  for (const { key, value } of secrets) {
16933
17167
  try {
16934
- const result = spawnSync4(
17168
+ const result = spawnSync3(
16935
17169
  firebaseCmd,
16936
17170
  ["functions:secrets:set", key, "--project", projectId],
16937
17171
  {
@@ -17118,7 +17352,7 @@ async function deployRules(appDir, serviceAccountPath, projectId, config, option
17118
17352
 
17119
17353
  // packages/tooling/src/apps/deploy-utils.ts
17120
17354
  init_utils();
17121
- import { spawnSync as spawnSync5 } from "node:child_process";
17355
+ import { spawnSync as spawnSync4 } from "node:child_process";
17122
17356
  init_pathResolver();
17123
17357
  init_typed_file_operations();
17124
17358
  init_error_handling();
@@ -17130,8 +17364,8 @@ function detectAvailableApps() {
17130
17364
  }
17131
17365
  return readdirSync2(appsDir).filter((item) => {
17132
17366
  const itemPath = joinPath(appsDir, item);
17133
- const stat = statSync2(itemPath);
17134
- return stat?.isDirectory() === true;
17367
+ const stat2 = statSync2(itemPath);
17368
+ return stat2?.isDirectory() === true;
17135
17369
  }).filter((app) => {
17136
17370
  const appDir = joinPath(appsDir, app);
17137
17371
  const firebaseJsonPath = joinPath(appDir, "firebase.json");
@@ -17306,7 +17540,7 @@ How to fix:
17306
17540
  if (shouldOpen) {
17307
17541
  try {
17308
17542
  const openCommand = process.platform === "win32" ? "start" : process.platform === "darwin" ? "open" : "xdg-open";
17309
- spawnSync5(openCommand, [consoleUrl], { shell: true });
17543
+ spawnSync4(openCommand, [consoleUrl], { shell: true });
17310
17544
  log.success("Opening Firebase Console...");
17311
17545
  } catch {
17312
17546
  log.warn("Could not open browser. Please open the URL manually.");
@@ -17737,12 +17971,6 @@ async function main2(options = {}) {
17737
17971
  ...serviceAccountPath ? [`Service Account: ${serviceAccountPath}`] : []
17738
17972
  ].join("\n");
17739
17973
  Me(configNote, "Deployment Configuration");
17740
- if (shouldDeployVercelFrontend) {
17741
- requireCLI(
17742
- CLI_TOOLS.VERCEL,
17743
- "Vercel CLI is required to deploy the frontend.\nInstall: bun install -g vercel"
17744
- );
17745
- }
17746
17974
  if (shouldDeployFirebaseFrontend && serviceAccountPath && config.project) {
17747
17975
  await deployFrontend(appDir, serviceAccountPath, config.project, config);
17748
17976
  }