@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.
- package/README.md +31 -0
- package/dependencies-matrix.json +205 -50
- package/dist/bin/commands/agent-setup.js +2 -2
- package/dist/bin/commands/build.js +6 -6
- package/dist/bin/commands/bump.js +495 -70
- package/dist/bin/commands/cacheout.js +6 -6
- package/dist/bin/commands/coach.js +6 -6
- package/dist/bin/commands/create-app.js +24 -16
- package/dist/bin/commands/create-project.js +114 -18
- package/dist/bin/commands/db.js +142136 -0
- package/dist/bin/commands/deploy.js +354 -126
- package/dist/bin/commands/dev.js +6 -6
- package/dist/bin/commands/doctor.js +140 -33
- package/dist/bin/commands/emu.js +6 -6
- package/dist/bin/commands/format.js +6 -6
- package/dist/bin/commands/get-demo.js +11 -6
- package/dist/bin/commands/make-admin.js +14210 -13770
- package/dist/bin/commands/preview.js +6 -6
- package/dist/bin/commands/seed.js +142426 -0
- package/dist/bin/commands/setup-cicd.js +8904 -0
- package/dist/bin/commands/setup.js +259 -212
- package/dist/bin/commands/staging.js +361 -127
- package/dist/bin/commands/sync-secrets.js +55 -33
- package/dist/bin/commands/type-check.js +16 -10
- package/dist/bin/commands/wai.js +6 -6
- package/dist/bin/dndev.js +194 -188
- package/dist/bin/donotdev.js +139 -189
- package/dist/index.js +468 -144
- package/package.json +1 -1
- package/templates/app-demo/.env.example +1 -0
- package/templates/{root-consumer → app-demo}/entities/ExampleEntity.ts.example +15 -9
- package/templates/app-demo/index.html.example +1 -1
- package/templates/app-demo/public/apple-touch-icon.png.example +0 -0
- package/templates/app-demo/public/favicon.svg.example +1 -0
- package/templates/app-demo/public/icon-192x192.png.example +0 -0
- package/templates/app-demo/public/icon-512x512.png.example +0 -0
- package/templates/app-demo/src/App.tsx.example +3 -1
- package/templates/app-demo/src/config/app.ts.example +1 -0
- package/templates/app-demo/src/entities/booking.ts.example +75 -0
- package/templates/app-demo/src/entities/onboarding.ts.example +160 -0
- package/templates/app-demo/src/entities/product.ts.example +12 -0
- package/templates/app-demo/src/entities/quote.ts.example +70 -0
- package/templates/app-demo/src/pages/ChangelogPage.tsx.example +28 -1
- package/templates/app-demo/src/pages/ConditionalFormPage.tsx.example +88 -0
- package/templates/app-demo/src/pages/DashboardPage.tsx.example +2 -0
- package/templates/app-demo/src/pages/HomePage.tsx.example +355 -2
- package/templates/app-demo/src/pages/OnboardingPage.tsx.example +47 -0
- package/templates/app-demo/src/pages/PricingPage.tsx.example +28 -1
- package/templates/app-demo/src/pages/ProductsPage.tsx.example +2 -0
- package/templates/app-demo/src/pages/ProfilePage.tsx.example +2 -0
- package/templates/app-demo/src/pages/SettingsPage.tsx.example +2 -0
- package/templates/app-demo/src/pages/ShowcaseDetailPage.tsx.example +22 -16
- package/templates/app-demo/src/pages/ShowcasePage.tsx.example +3 -1
- package/templates/app-demo/src/pages/components/ComponentRenderer.tsx.example +147 -51
- package/templates/app-demo/src/pages/components/ComponentsData.tsx.example +103 -21
- package/templates/app-demo/src/pages/components/componentConfig.ts.example +139 -59
- package/templates/app-demo/src/pages/legal/LegalPage.tsx.example +12 -1
- package/templates/app-demo/src/pages/legal/PrivacyPage.tsx.example +10 -1
- package/templates/app-demo/src/pages/legal/TermsPage.tsx.example +10 -1
- package/templates/app-demo/src/themes.css.example +289 -77
- package/templates/app-demo/stats.html.example +4949 -0
- package/templates/app-dndev/index.html.example +164 -0
- package/templates/app-dndev/public/logo.svg.example +1 -0
- package/templates/app-dndev/public/manifest.json.example +10 -0
- package/templates/app-dndev/src/App.tsx.example +35 -0
- package/templates/app-dndev/src/components/CockpitLayout.css.example +181 -0
- package/templates/app-dndev/src/components/CockpitLayout.tsx.example +209 -0
- package/templates/app-dndev/src/components/Kanban.css.example +385 -0
- package/templates/app-dndev/src/components/ModeToggle.tsx.example +32 -0
- package/templates/app-dndev/src/components/OverlaySlot.tsx.example +68 -0
- package/templates/app-dndev/src/components/TerminalPanel.css.example +228 -0
- package/templates/app-dndev/src/components/TerminalPanel.tsx.example +714 -0
- package/templates/app-dndev/src/components/markdown-prose.css.example +49 -0
- package/templates/app-dndev/src/components/phases/CaptainLog.tsx.example +107 -0
- package/templates/app-dndev/src/components/phases/ContextTabs.tsx.example +352 -0
- package/templates/app-dndev/src/components/phases/PhaseCard.tsx.example +126 -0
- package/templates/app-dndev/src/components/phases/PhaseDetail.tsx.example +147 -0
- package/templates/app-dndev/src/components/phases/ReviewPanel.tsx.example +115 -0
- package/templates/app-dndev/src/components/phases/phaseData.ts.example +366 -0
- package/templates/app-dndev/src/config/app.ts.example +103 -0
- package/templates/app-dndev/src/config/commands.ts.example +171 -0
- package/templates/app-dndev/src/config/legal.ts.example +170 -0
- package/templates/app-dndev/src/config/providers.ts.example +7 -0
- package/templates/app-dndev/src/globals.css.example +10 -0
- package/templates/app-dndev/src/hooks/useDndevFile.ts.example +144 -0
- package/templates/app-dndev/src/main.tsx.example +21 -0
- package/templates/app-dndev/src/pages/BoardPage.tsx.example +640 -0
- package/templates/app-dndev/src/pages/GrillPage.tsx.example +658 -0
- package/templates/app-dndev/src/pages/HomePage.tsx.example +347 -0
- package/templates/app-dndev/src/pages/NotFoundPage.tsx.example +33 -0
- package/templates/app-dndev/src/pages/PhasesPage.tsx.example +137 -0
- package/templates/app-dndev/src/pages/SettingsPage.tsx.example +64 -0
- package/templates/app-dndev/src/pages/legal/LegalNoticePage.tsx.example +75 -0
- package/templates/app-dndev/src/pages/legal/PrivacyPage.tsx.example +69 -0
- package/templates/app-dndev/src/pages/legal/TermsPage.tsx.example +71 -0
- package/templates/app-dndev/src/stores/dndevStore.ts.example +386 -0
- package/templates/app-dndev/src/themes.css.example +161 -0
- package/templates/app-dndev/terminal-sidecar.cjs.example +341 -0
- package/templates/app-dndev/tsconfig.json.example +9 -0
- package/templates/app-dndev/vite.config.ts.example +24 -0
- package/templates/app-vite/index.html.example +1 -1
- package/templates/functions-supabase/supabase/functions/.env.example +0 -2
- package/templates/root-consumer/.claude/commands/grill.md.example +86 -8
- package/templates/root-consumer/.dndev.secrets.example +32 -0
- package/templates/root-consumer/.gitignore.example +3 -0
- package/templates/root-consumer/AI.md.example +4 -0
- package/templates/root-consumer/entities/index.ts.example +2 -5
- package/templates/root-consumer/guides/dndev/COMPONENTS_ATOMIC.md.example +4 -0
- package/templates/root-consumer/guides/dndev/ENV_SETUP.md.example +23 -20
- package/templates/root-consumer/guides/dndev/INDEX.md.example +1 -0
- package/templates/root-consumer/guides/dndev/SETUP_BILLING.md.example +3 -7
- package/templates/root-consumer/guides/dndev/SETUP_CICD.md.example +115 -0
- package/templates/root-consumer/guides/dndev/SETUP_CRUD.md.example +41 -0
- package/templates/root-consumer/guides/dndev/SETUP_SUPABASE.md.example +13 -18
- package/templates/root-consumer/guides/dndev/SETUP_VERCEL.md.example +17 -12
- package/templates/root-consumer/guides/wai-way/WAI_WAY_CLI.md.example +185 -251
- package/templates/root-consumer/guides/wai-way/agents/extractor.md.example +26 -8
- package/templates/root-consumer/guides/wai-way/blueprints/0_brainstorm.md.example +66 -49
- package/templates/root-consumer/guides/wai-way/blueprints/1_scaffold.md.example +6 -5
- package/templates/root-consumer/guides/wai-way/blueprints/2_entities.md.example +9 -9
- package/templates/root-consumer/guides/wai-way/blueprints/3_compose.md.example +1 -1
- package/templates/root-consumer/guides/wai-way/blueprints/4_configure.md.example +7 -6
- package/templates/root-consumer/guides/wai-way/context_map.json.example +51 -20
- package/templates/root-consumer/guides/wai-way/hld_template.md.example +138 -0
- package/templates/root-consumer/guides/wai-way/lld_template.md.example +103 -0
- package/templates/root-consumer/guides/wai-way/prd_template.md.example +140 -0
- /package/templates/{root-consumer → app-demo}/entities/Contact.ts.example +0 -0
- /package/templates/{root-consumer → app-demo}/entities/demo.ts.example +0 -0
package/dist/index.js
CHANGED
|
@@ -3351,9 +3351,9 @@ var require_parse2 = __commonJS({
|
|
|
3351
3351
|
const idx = prev.value.lastIndexOf("[");
|
|
3352
3352
|
const pre = prev.value.slice(0, idx);
|
|
3353
3353
|
const rest2 = prev.value.slice(idx + 2);
|
|
3354
|
-
const
|
|
3355
|
-
if (
|
|
3356
|
-
prev.value = pre +
|
|
3354
|
+
const posix2 = POSIX_REGEX_SOURCE[rest2];
|
|
3355
|
+
if (posix2) {
|
|
3356
|
+
prev.value = pre + posix2;
|
|
3357
3357
|
state.backtrack = true;
|
|
3358
3358
|
advance();
|
|
3359
3359
|
if (!bos.output && tokens.indexOf(prev) === 1) {
|
|
@@ -3875,7 +3875,7 @@ var require_picomatch = __commonJS({
|
|
|
3875
3875
|
throw new TypeError("Expected pattern to be a non-empty string");
|
|
3876
3876
|
}
|
|
3877
3877
|
const opts = options || {};
|
|
3878
|
-
const
|
|
3878
|
+
const posix2 = utils.isWindows(options);
|
|
3879
3879
|
const regex = isState ? picomatch.compileRe(glob2, options) : picomatch.makeRe(glob2, options, false, true);
|
|
3880
3880
|
const state = regex.state;
|
|
3881
3881
|
delete regex.state;
|
|
@@ -3885,8 +3885,8 @@ var require_picomatch = __commonJS({
|
|
|
3885
3885
|
isIgnored = picomatch(opts.ignore, ignoreOpts, returnState);
|
|
3886
3886
|
}
|
|
3887
3887
|
const matcher = (input, returnObject = false) => {
|
|
3888
|
-
const { isMatch, match, output } = picomatch.test(input, regex, options, { glob: glob2, posix });
|
|
3889
|
-
const result = { glob: glob2, state, regex, posix, input, output, match, isMatch };
|
|
3888
|
+
const { isMatch, match, output } = picomatch.test(input, regex, options, { glob: glob2, posix: posix2 });
|
|
3889
|
+
const result = { glob: glob2, state, regex, posix: posix2, input, output, match, isMatch };
|
|
3890
3890
|
if (typeof opts.onResult === "function") {
|
|
3891
3891
|
opts.onResult(result);
|
|
3892
3892
|
}
|
|
@@ -3911,7 +3911,7 @@ var require_picomatch = __commonJS({
|
|
|
3911
3911
|
}
|
|
3912
3912
|
return matcher;
|
|
3913
3913
|
};
|
|
3914
|
-
picomatch.test = (input, regex, options, { glob: glob2, posix } = {}) => {
|
|
3914
|
+
picomatch.test = (input, regex, options, { glob: glob2, posix: posix2 } = {}) => {
|
|
3915
3915
|
if (typeof input !== "string") {
|
|
3916
3916
|
throw new TypeError("Expected input to be a string");
|
|
3917
3917
|
}
|
|
@@ -3919,7 +3919,7 @@ var require_picomatch = __commonJS({
|
|
|
3919
3919
|
return { isMatch: false, output: "" };
|
|
3920
3920
|
}
|
|
3921
3921
|
const opts = options || {};
|
|
3922
|
-
const format = opts.format || (
|
|
3922
|
+
const format = opts.format || (posix2 ? utils.toPosixSlashes : null);
|
|
3923
3923
|
let match = input === glob2;
|
|
3924
3924
|
let output = match && format ? format(input) : input;
|
|
3925
3925
|
if (match === false) {
|
|
@@ -3928,14 +3928,14 @@ var require_picomatch = __commonJS({
|
|
|
3928
3928
|
}
|
|
3929
3929
|
if (match === false || opts.capture === true) {
|
|
3930
3930
|
if (opts.matchBase === true || opts.basename === true) {
|
|
3931
|
-
match = picomatch.matchBase(input, regex, options,
|
|
3931
|
+
match = picomatch.matchBase(input, regex, options, posix2);
|
|
3932
3932
|
} else {
|
|
3933
3933
|
match = regex.exec(output);
|
|
3934
3934
|
}
|
|
3935
3935
|
}
|
|
3936
3936
|
return { isMatch: Boolean(match), match, output };
|
|
3937
3937
|
};
|
|
3938
|
-
picomatch.matchBase = (input, glob2, options,
|
|
3938
|
+
picomatch.matchBase = (input, glob2, options, posix2 = utils.isWindows(options)) => {
|
|
3939
3939
|
const regex = glob2 instanceof RegExp ? glob2 : picomatch.makeRe(glob2, options);
|
|
3940
3940
|
return regex.test(path.basename(input));
|
|
3941
3941
|
};
|
|
@@ -4126,9 +4126,9 @@ var require_micromatch = __commonJS({
|
|
|
4126
4126
|
return [].concat(patterns).every((p2) => picomatch(p2, options)(str));
|
|
4127
4127
|
};
|
|
4128
4128
|
micromatch.capture = (glob2, input, options) => {
|
|
4129
|
-
let
|
|
4129
|
+
let posix2 = utils.isWindows(options);
|
|
4130
4130
|
let regex = picomatch.makeRe(String(glob2), { ...options, capture: true });
|
|
4131
|
-
let match = regex.exec(
|
|
4131
|
+
let match = regex.exec(posix2 ? utils.toPosixSlashes(input) : input);
|
|
4132
4132
|
if (match) {
|
|
4133
4133
|
return match.slice(1).map((v2) => v2 === void 0 ? "" : v2);
|
|
4134
4134
|
}
|
|
@@ -4308,15 +4308,15 @@ var require_pattern = __commonJS({
|
|
|
4308
4308
|
exports.removeDuplicateSlashes = removeDuplicateSlashes;
|
|
4309
4309
|
function partitionAbsoluteAndRelative(patterns) {
|
|
4310
4310
|
const absolute = [];
|
|
4311
|
-
const
|
|
4311
|
+
const relative4 = [];
|
|
4312
4312
|
for (const pattern of patterns) {
|
|
4313
4313
|
if (isAbsolute2(pattern)) {
|
|
4314
4314
|
absolute.push(pattern);
|
|
4315
4315
|
} else {
|
|
4316
|
-
|
|
4316
|
+
relative4.push(pattern);
|
|
4317
4317
|
}
|
|
4318
4318
|
}
|
|
4319
|
-
return [absolute,
|
|
4319
|
+
return [absolute, relative4];
|
|
4320
4320
|
}
|
|
4321
4321
|
exports.partitionAbsoluteAndRelative = partitionAbsoluteAndRelative;
|
|
4322
4322
|
function isAbsolute2(pattern) {
|
|
@@ -4626,7 +4626,7 @@ var require_async = __commonJS({
|
|
|
4626
4626
|
callSuccessCallback(callback, lstat);
|
|
4627
4627
|
return;
|
|
4628
4628
|
}
|
|
4629
|
-
settings.fs.stat(path, (statError,
|
|
4629
|
+
settings.fs.stat(path, (statError, stat2) => {
|
|
4630
4630
|
if (statError !== null) {
|
|
4631
4631
|
if (settings.throwErrorOnBrokenSymbolicLink) {
|
|
4632
4632
|
callFailureCallback(callback, statError);
|
|
@@ -4636,9 +4636,9 @@ var require_async = __commonJS({
|
|
|
4636
4636
|
return;
|
|
4637
4637
|
}
|
|
4638
4638
|
if (settings.markSymbolicLink) {
|
|
4639
|
-
|
|
4639
|
+
stat2.isSymbolicLink = () => true;
|
|
4640
4640
|
}
|
|
4641
|
-
callSuccessCallback(callback,
|
|
4641
|
+
callSuccessCallback(callback, stat2);
|
|
4642
4642
|
});
|
|
4643
4643
|
});
|
|
4644
4644
|
}
|
|
@@ -4665,11 +4665,11 @@ var require_sync = __commonJS({
|
|
|
4665
4665
|
return lstat;
|
|
4666
4666
|
}
|
|
4667
4667
|
try {
|
|
4668
|
-
const
|
|
4668
|
+
const stat2 = settings.fs.statSync(path);
|
|
4669
4669
|
if (settings.markSymbolicLink) {
|
|
4670
|
-
|
|
4670
|
+
stat2.isSymbolicLink = () => true;
|
|
4671
4671
|
}
|
|
4672
|
-
return
|
|
4672
|
+
return stat2;
|
|
4673
4673
|
} catch (error2) {
|
|
4674
4674
|
if (!settings.throwErrorOnBrokenSymbolicLink) {
|
|
4675
4675
|
return lstat;
|
|
@@ -4739,14 +4739,14 @@ var require_out = __commonJS({
|
|
|
4739
4739
|
var sync = require_sync();
|
|
4740
4740
|
var settings_1 = require_settings();
|
|
4741
4741
|
exports.Settings = settings_1.default;
|
|
4742
|
-
function
|
|
4742
|
+
function stat2(path, optionsOrSettingsOrCallback, callback) {
|
|
4743
4743
|
if (typeof optionsOrSettingsOrCallback === "function") {
|
|
4744
4744
|
async.read(path, getSettings(), optionsOrSettingsOrCallback);
|
|
4745
4745
|
return;
|
|
4746
4746
|
}
|
|
4747
4747
|
async.read(path, getSettings(optionsOrSettingsOrCallback), callback);
|
|
4748
4748
|
}
|
|
4749
|
-
exports.stat =
|
|
4749
|
+
exports.stat = stat2;
|
|
4750
4750
|
function statSync3(path, optionsOrSettings) {
|
|
4751
4751
|
const settings = getSettings(optionsOrSettings);
|
|
4752
4752
|
return sync.read(path, settings);
|
|
@@ -4916,7 +4916,7 @@ var require_async2 = __commonJS({
|
|
|
4916
4916
|
readdirWithFileTypes(directory, settings, callback);
|
|
4917
4917
|
return;
|
|
4918
4918
|
}
|
|
4919
|
-
|
|
4919
|
+
readdir3(directory, settings, callback);
|
|
4920
4920
|
}
|
|
4921
4921
|
exports.read = read2;
|
|
4922
4922
|
function readdirWithFileTypes(directory, settings, callback) {
|
|
@@ -4965,7 +4965,7 @@ var require_async2 = __commonJS({
|
|
|
4965
4965
|
});
|
|
4966
4966
|
};
|
|
4967
4967
|
}
|
|
4968
|
-
function
|
|
4968
|
+
function readdir3(directory, settings, callback) {
|
|
4969
4969
|
settings.fs.readdir(directory, (readdirError, names) => {
|
|
4970
4970
|
if (readdirError !== null) {
|
|
4971
4971
|
callFailureCallback(callback, readdirError);
|
|
@@ -5000,7 +5000,7 @@ var require_async2 = __commonJS({
|
|
|
5000
5000
|
});
|
|
5001
5001
|
});
|
|
5002
5002
|
}
|
|
5003
|
-
exports.readdir =
|
|
5003
|
+
exports.readdir = readdir3;
|
|
5004
5004
|
function callFailureCallback(callback, error2) {
|
|
5005
5005
|
callback(error2);
|
|
5006
5006
|
}
|
|
@@ -5025,7 +5025,7 @@ var require_sync2 = __commonJS({
|
|
|
5025
5025
|
if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) {
|
|
5026
5026
|
return readdirWithFileTypes(directory, settings);
|
|
5027
5027
|
}
|
|
5028
|
-
return
|
|
5028
|
+
return readdir3(directory, settings);
|
|
5029
5029
|
}
|
|
5030
5030
|
exports.read = read2;
|
|
5031
5031
|
function readdirWithFileTypes(directory, settings) {
|
|
@@ -5050,7 +5050,7 @@ var require_sync2 = __commonJS({
|
|
|
5050
5050
|
});
|
|
5051
5051
|
}
|
|
5052
5052
|
exports.readdirWithFileTypes = readdirWithFileTypes;
|
|
5053
|
-
function
|
|
5053
|
+
function readdir3(directory, settings) {
|
|
5054
5054
|
const names = settings.fs.readdirSync(directory);
|
|
5055
5055
|
return names.map((name) => {
|
|
5056
5056
|
const entryPath = common.joinPathSegments(directory, name, settings.pathSegmentSeparator);
|
|
@@ -5066,7 +5066,7 @@ var require_sync2 = __commonJS({
|
|
|
5066
5066
|
return entry;
|
|
5067
5067
|
});
|
|
5068
5068
|
}
|
|
5069
|
-
exports.readdir =
|
|
5069
|
+
exports.readdir = readdir3;
|
|
5070
5070
|
}
|
|
5071
5071
|
});
|
|
5072
5072
|
|
|
@@ -6628,19 +6628,19 @@ var require_out4 = __commonJS({
|
|
|
6628
6628
|
return utils.path.convertPathToPattern(source);
|
|
6629
6629
|
}
|
|
6630
6630
|
FastGlob2.convertPathToPattern = convertPathToPattern;
|
|
6631
|
-
let
|
|
6632
|
-
(function(
|
|
6631
|
+
let posix2;
|
|
6632
|
+
(function(posix3) {
|
|
6633
6633
|
function escapePath2(source) {
|
|
6634
6634
|
assertPatternsInput(source);
|
|
6635
6635
|
return utils.path.escapePosixPath(source);
|
|
6636
6636
|
}
|
|
6637
|
-
|
|
6637
|
+
posix3.escapePath = escapePath2;
|
|
6638
6638
|
function convertPathToPattern2(source) {
|
|
6639
6639
|
assertPatternsInput(source);
|
|
6640
6640
|
return utils.path.convertPosixPathToPattern(source);
|
|
6641
6641
|
}
|
|
6642
|
-
|
|
6643
|
-
})(
|
|
6642
|
+
posix3.convertPathToPattern = convertPathToPattern2;
|
|
6643
|
+
})(posix2 = FastGlob2.posix || (FastGlob2.posix = {}));
|
|
6644
6644
|
let win32;
|
|
6645
6645
|
(function(win322) {
|
|
6646
6646
|
function escapePath2(source) {
|
|
@@ -7219,7 +7219,7 @@ var init_PathResolver = __esm({
|
|
|
7219
7219
|
}
|
|
7220
7220
|
const detectedFormat = this._detectFormat(filePath, format);
|
|
7221
7221
|
let writeContent;
|
|
7222
|
-
if (
|
|
7222
|
+
if (Buffer.isBuffer(content)) {
|
|
7223
7223
|
writeContent = content;
|
|
7224
7224
|
} else if (detectedFormat === "json" && typeof content === "object") {
|
|
7225
7225
|
writeContent = JSON.stringify(content, null, 2);
|
|
@@ -7228,7 +7228,7 @@ var init_PathResolver = __esm({
|
|
|
7228
7228
|
}
|
|
7229
7229
|
try {
|
|
7230
7230
|
return await safeExecuteAsync(async () => {
|
|
7231
|
-
if (
|
|
7231
|
+
if (Buffer.isBuffer(writeContent)) {
|
|
7232
7232
|
await fs.promises.writeFile(normalizedPath, writeContent);
|
|
7233
7233
|
} else {
|
|
7234
7234
|
await fs.promises.writeFile(normalizedPath, writeContent, "utf8");
|
|
@@ -7280,7 +7280,7 @@ var init_PathResolver = __esm({
|
|
|
7280
7280
|
}
|
|
7281
7281
|
const detectedFormat = this._detectFormat(filePath, format);
|
|
7282
7282
|
let writeContent;
|
|
7283
|
-
if (
|
|
7283
|
+
if (Buffer.isBuffer(content)) {
|
|
7284
7284
|
writeContent = content;
|
|
7285
7285
|
} else if (detectedFormat === "json" && typeof content === "object") {
|
|
7286
7286
|
writeContent = JSON.stringify(content, null, 2);
|
|
@@ -7288,7 +7288,7 @@ var init_PathResolver = __esm({
|
|
|
7288
7288
|
writeContent = String(content);
|
|
7289
7289
|
}
|
|
7290
7290
|
try {
|
|
7291
|
-
if (
|
|
7291
|
+
if (Buffer.isBuffer(writeContent)) {
|
|
7292
7292
|
fs.writeFileSync(normalizedPath, writeContent);
|
|
7293
7293
|
} else {
|
|
7294
7294
|
fs.writeFileSync(normalizedPath, writeContent, "utf8");
|
|
@@ -8181,7 +8181,7 @@ async function isBinaryFile(filePath) {
|
|
|
8181
8181
|
try {
|
|
8182
8182
|
let fileHandle = null;
|
|
8183
8183
|
try {
|
|
8184
|
-
const buffer =
|
|
8184
|
+
const buffer = Buffer.alloc(4096);
|
|
8185
8185
|
const fs2 = await import("node:fs");
|
|
8186
8186
|
fileHandle = await fs2.promises.open(filePath, "r");
|
|
8187
8187
|
const { bytesRead } = await fileHandle.read(buffer, 0, 4096, 0);
|
|
@@ -8359,8 +8359,8 @@ var init_pathResolver = __esm({
|
|
|
8359
8359
|
if (normalizedTarget === normalizedRoot) {
|
|
8360
8360
|
return true;
|
|
8361
8361
|
}
|
|
8362
|
-
const
|
|
8363
|
-
return Boolean(
|
|
8362
|
+
const relative4 = getRelativePathBetween(normalizedRoot, normalizedTarget);
|
|
8363
|
+
return Boolean(relative4) && !relative4.startsWith("../") && !relative4.startsWith("/") && !relative4.includes("..");
|
|
8364
8364
|
};
|
|
8365
8365
|
}
|
|
8366
8366
|
});
|
|
@@ -8491,7 +8491,7 @@ var init_typed_file_operations = __esm({
|
|
|
8491
8491
|
});
|
|
8492
8492
|
|
|
8493
8493
|
// packages/tooling/src/bundler/utils.ts
|
|
8494
|
-
import { Buffer
|
|
8494
|
+
import { Buffer } from "node:buffer";
|
|
8495
8495
|
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "node:fs";
|
|
8496
8496
|
import { createRequire as createRequire3 } from "node:module";
|
|
8497
8497
|
import { dirname as dirname3, resolve as resolve3 } from "node:path";
|
|
@@ -8508,7 +8508,7 @@ var init_utils = __esm({
|
|
|
8508
8508
|
globalThis.require = require2;
|
|
8509
8509
|
globalThis.__filename = __filename;
|
|
8510
8510
|
globalThis.__dirname = __dirname;
|
|
8511
|
-
globalThis.Buffer =
|
|
8511
|
+
globalThis.Buffer = Buffer;
|
|
8512
8512
|
globalThis.process = process;
|
|
8513
8513
|
if (typeof global === "undefined") {
|
|
8514
8514
|
globalThis.global = globalThis;
|
|
@@ -9016,7 +9016,28 @@ var init_cli_tools = __esm({
|
|
|
9016
9016
|
}
|
|
9017
9017
|
});
|
|
9018
9018
|
|
|
9019
|
-
// packages/tooling/src/
|
|
9019
|
+
// packages/tooling/src/utils/secrets-resolver.ts
|
|
9020
|
+
function parseEnvFile(filePath) {
|
|
9021
|
+
if (!pathExists(filePath)) return {};
|
|
9022
|
+
const content = readSync(filePath, { format: "text" });
|
|
9023
|
+
if (typeof content !== "string" || !content) return {};
|
|
9024
|
+
const result = {};
|
|
9025
|
+
for (const line of content.split(/\r?\n/)) {
|
|
9026
|
+
const trimmed = line.trim();
|
|
9027
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
9028
|
+
const eqIdx = trimmed.indexOf("=");
|
|
9029
|
+
if (eqIdx === -1) continue;
|
|
9030
|
+
const key = trimmed.slice(0, eqIdx).trim();
|
|
9031
|
+
let value = trimmed.slice(eqIdx + 1).trim();
|
|
9032
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
9033
|
+
value = value.slice(1, -1);
|
|
9034
|
+
}
|
|
9035
|
+
if (key && value) {
|
|
9036
|
+
result[key] = value;
|
|
9037
|
+
}
|
|
9038
|
+
}
|
|
9039
|
+
return result;
|
|
9040
|
+
}
|
|
9020
9041
|
function readEnvVar(filePath, varName) {
|
|
9021
9042
|
if (!pathExists(filePath)) return null;
|
|
9022
9043
|
const content = readSync(filePath, { format: "text" });
|
|
@@ -9025,16 +9046,93 @@ function readEnvVar(filePath, varName) {
|
|
|
9025
9046
|
const trimmed = line.trim();
|
|
9026
9047
|
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
9027
9048
|
if (trimmed.startsWith(`${varName}=`)) {
|
|
9028
|
-
|
|
9049
|
+
let val = trimmed.substring(`${varName}=`.length).trim();
|
|
9029
9050
|
if (val.startsWith('"') && val.endsWith('"') || val.startsWith("'") && val.endsWith("'")) {
|
|
9030
|
-
|
|
9051
|
+
val = val.slice(1, -1);
|
|
9031
9052
|
}
|
|
9032
9053
|
return val || null;
|
|
9033
9054
|
}
|
|
9034
9055
|
}
|
|
9035
9056
|
return null;
|
|
9036
9057
|
}
|
|
9037
|
-
function
|
|
9058
|
+
function loadDndevSecrets(projectRoot) {
|
|
9059
|
+
const secretsPath = joinPath(projectRoot, ".dndev.secrets");
|
|
9060
|
+
if (cachedSecretsPath === secretsPath && cachedSecrets) {
|
|
9061
|
+
return cachedSecrets;
|
|
9062
|
+
}
|
|
9063
|
+
cachedSecrets = parseEnvFile(secretsPath);
|
|
9064
|
+
cachedSecretsPath = secretsPath;
|
|
9065
|
+
return cachedSecrets;
|
|
9066
|
+
}
|
|
9067
|
+
function resolveSecret(name, projectRoot, opts) {
|
|
9068
|
+
const appDir = opts?.appDir ?? projectRoot;
|
|
9069
|
+
const envValue = process.env[name];
|
|
9070
|
+
if (envValue) {
|
|
9071
|
+
return { value: envValue, source: "process.env" };
|
|
9072
|
+
}
|
|
9073
|
+
const secrets = loadDndevSecrets(projectRoot);
|
|
9074
|
+
if (secrets[name]) {
|
|
9075
|
+
return { value: secrets[name], source: ".dndev.secrets" };
|
|
9076
|
+
}
|
|
9077
|
+
if (name === "SUPABASE_SECRET_KEY" && secrets["SUPABASE_SERVICE_ROLE_KEY"]) {
|
|
9078
|
+
return {
|
|
9079
|
+
value: secrets["SUPABASE_SERVICE_ROLE_KEY"],
|
|
9080
|
+
source: ".dndev.secrets"
|
|
9081
|
+
};
|
|
9082
|
+
}
|
|
9083
|
+
const legacyPaths = LEGACY_PATHS[name];
|
|
9084
|
+
if (legacyPaths) {
|
|
9085
|
+
for (const relPath of legacyPaths) {
|
|
9086
|
+
const fullPath = joinPath(appDir, relPath);
|
|
9087
|
+
const value = readEnvVar(fullPath, name);
|
|
9088
|
+
if (value) {
|
|
9089
|
+
if (!opts?.silent && !warnedLegacy.has(name)) {
|
|
9090
|
+
warnedLegacy.add(name);
|
|
9091
|
+
log.warn(
|
|
9092
|
+
`${name} found in ${relPath} (legacy). Move it to .dndev.secrets at project root.`
|
|
9093
|
+
);
|
|
9094
|
+
}
|
|
9095
|
+
return { value, source: "legacy", legacyPath: relPath };
|
|
9096
|
+
}
|
|
9097
|
+
if (name === "SUPABASE_SECRET_KEY") {
|
|
9098
|
+
const aliasValue = readEnvVar(fullPath, "SUPABASE_SERVICE_ROLE_KEY");
|
|
9099
|
+
if (aliasValue) {
|
|
9100
|
+
if (!opts?.silent && !warnedLegacy.has(name)) {
|
|
9101
|
+
warnedLegacy.add(name);
|
|
9102
|
+
log.warn(
|
|
9103
|
+
`${name} found in ${relPath} (legacy). Move it to .dndev.secrets at project root.`
|
|
9104
|
+
);
|
|
9105
|
+
}
|
|
9106
|
+
return { value: aliasValue, source: "legacy", legacyPath: relPath };
|
|
9107
|
+
}
|
|
9108
|
+
}
|
|
9109
|
+
}
|
|
9110
|
+
}
|
|
9111
|
+
return null;
|
|
9112
|
+
}
|
|
9113
|
+
var LEGACY_PATHS, warnedLegacy, cachedSecretsPath, cachedSecrets;
|
|
9114
|
+
var init_secrets_resolver = __esm({
|
|
9115
|
+
"packages/tooling/src/utils/secrets-resolver.ts"() {
|
|
9116
|
+
"use strict";
|
|
9117
|
+
init_utils();
|
|
9118
|
+
init_pathResolver();
|
|
9119
|
+
init_cli_output();
|
|
9120
|
+
LEGACY_PATHS = {
|
|
9121
|
+
VERCEL_TOKEN: [".env.local"],
|
|
9122
|
+
SUPABASE_SECRET_KEY: ["supabase/functions/.env", "functions/.env"],
|
|
9123
|
+
SUPABASE_DB_URL: ["supabase/functions/.env", "functions/.env"],
|
|
9124
|
+
SUPABASE_ACCESS_TOKEN: ["supabase/functions/.env", "functions/.env"],
|
|
9125
|
+
STRIPE_SECRET_KEY: ["supabase/functions/.env", "functions/.env"],
|
|
9126
|
+
STRIPE_WEBHOOK_SECRET: ["supabase/functions/.env", "functions/.env"]
|
|
9127
|
+
};
|
|
9128
|
+
warnedLegacy = /* @__PURE__ */ new Set();
|
|
9129
|
+
cachedSecretsPath = null;
|
|
9130
|
+
cachedSecrets = null;
|
|
9131
|
+
}
|
|
9132
|
+
});
|
|
9133
|
+
|
|
9134
|
+
// packages/tooling/src/cli/setup/vercel-token.ts
|
|
9135
|
+
function resolvePerAppVar(appDir, varName) {
|
|
9038
9136
|
if (process.env[varName]) return process.env[varName];
|
|
9039
9137
|
const fromLocal = readEnvVar(joinPath(appDir, ".env.local"), varName);
|
|
9040
9138
|
if (fromLocal) return fromLocal;
|
|
@@ -9042,10 +9140,11 @@ function resolveVercelVar(appDir, varName) {
|
|
|
9042
9140
|
if (fromEnv) return fromEnv;
|
|
9043
9141
|
return null;
|
|
9044
9142
|
}
|
|
9045
|
-
function resolveVercelCredentials(appDir) {
|
|
9046
|
-
const
|
|
9047
|
-
const
|
|
9048
|
-
const
|
|
9143
|
+
function resolveVercelCredentials(appDir, projectRoot) {
|
|
9144
|
+
const root = projectRoot ?? process.cwd();
|
|
9145
|
+
const token = resolveSecret("VERCEL_TOKEN", root, { appDir })?.value ?? null;
|
|
9146
|
+
const orgId = resolvePerAppVar(appDir, "VERCEL_ORG_ID");
|
|
9147
|
+
const projectId = resolvePerAppVar(appDir, "VERCEL_PROJECT_ID");
|
|
9049
9148
|
const missing = [];
|
|
9050
9149
|
if (!token) missing.push("VERCEL_TOKEN");
|
|
9051
9150
|
if (!orgId) missing.push("VERCEL_ORG_ID");
|
|
@@ -9059,6 +9158,7 @@ var init_vercel_token = __esm({
|
|
|
9059
9158
|
"packages/tooling/src/cli/setup/vercel-token.ts"() {
|
|
9060
9159
|
"use strict";
|
|
9061
9160
|
init_utils();
|
|
9161
|
+
init_secrets_resolver();
|
|
9062
9162
|
init_pathResolver();
|
|
9063
9163
|
}
|
|
9064
9164
|
});
|
|
@@ -16451,10 +16551,14 @@ var init_error_handling = __esm({
|
|
|
16451
16551
|
var sync_secrets_exports = {};
|
|
16452
16552
|
__export(sync_secrets_exports, {
|
|
16453
16553
|
default: () => sync_secrets_default,
|
|
16454
|
-
|
|
16554
|
+
detectGitHubRepo: () => detectGitHubRepo,
|
|
16555
|
+
main: () => main5,
|
|
16556
|
+
parseSecretsWithFallback: () => parseSecretsWithFallback,
|
|
16557
|
+
setGitHubSecret: () => setGitHubSecret,
|
|
16558
|
+
uploadServiceAccountToGitHub: () => uploadServiceAccountToGitHub
|
|
16455
16559
|
});
|
|
16456
|
-
import { spawnSync as
|
|
16457
|
-
function
|
|
16560
|
+
import { spawnSync as spawnSync8 } from "node:child_process";
|
|
16561
|
+
function parseEnvFile2(filePath) {
|
|
16458
16562
|
if (!pathExists(filePath)) {
|
|
16459
16563
|
throw new DoNotDevError(
|
|
16460
16564
|
`Environment file not found: ${filePath}`,
|
|
@@ -16462,30 +16566,22 @@ function parseEnvFile(filePath) {
|
|
|
16462
16566
|
{ context: { filePath } }
|
|
16463
16567
|
);
|
|
16464
16568
|
}
|
|
16465
|
-
const
|
|
16466
|
-
|
|
16467
|
-
|
|
16468
|
-
throw new Error(`Failed to read secrets file: ${filePath}`);
|
|
16569
|
+
const result = parseEnvFile(filePath);
|
|
16570
|
+
if (Object.keys(result).length === 0) {
|
|
16571
|
+
log.debug(`No key-value pairs found in ${filePath}`);
|
|
16469
16572
|
}
|
|
16470
|
-
|
|
16471
|
-
|
|
16472
|
-
|
|
16473
|
-
|
|
16474
|
-
|
|
16475
|
-
|
|
16476
|
-
|
|
16477
|
-
|
|
16478
|
-
|
|
16479
|
-
return;
|
|
16480
|
-
}
|
|
16481
|
-
const key = trimmedLine.substring(0, equalIndex).trim();
|
|
16482
|
-
const value = trimmedLine.substring(equalIndex + 1).trim();
|
|
16483
|
-
const cleanValue = value.replace(/^["']|["']$/g, "");
|
|
16484
|
-
if (key && cleanValue) {
|
|
16485
|
-
secrets[key] = cleanValue;
|
|
16573
|
+
return result;
|
|
16574
|
+
}
|
|
16575
|
+
function parseSecretsWithFallback(envFilePath, projectRoot) {
|
|
16576
|
+
const dndevSecretsPath = joinPath(projectRoot, ".dndev.secrets");
|
|
16577
|
+
if (pathExists(dndevSecretsPath)) {
|
|
16578
|
+
const secrets = parseEnvFile(dndevSecretsPath);
|
|
16579
|
+
if (Object.keys(secrets).length > 0) {
|
|
16580
|
+
log.info(`Reading secrets from: ${dndevSecretsPath}`);
|
|
16581
|
+
return secrets;
|
|
16486
16582
|
}
|
|
16487
|
-
}
|
|
16488
|
-
return
|
|
16583
|
+
}
|
|
16584
|
+
return parseEnvFile2(envFilePath);
|
|
16489
16585
|
}
|
|
16490
16586
|
function detectPlatform() {
|
|
16491
16587
|
const currentDir = process.cwd();
|
|
@@ -16576,8 +16672,8 @@ function detectAppsWithFunctions() {
|
|
|
16576
16672
|
try {
|
|
16577
16673
|
const appsList = readdirSync2(appsDir).filter((item) => {
|
|
16578
16674
|
const itemPath = joinPath(appsDir, item);
|
|
16579
|
-
const
|
|
16580
|
-
return
|
|
16675
|
+
const stat2 = statSync2(itemPath);
|
|
16676
|
+
return stat2?.isDirectory() === true;
|
|
16581
16677
|
});
|
|
16582
16678
|
for (const app of appsList) {
|
|
16583
16679
|
const functionsEnvFile = joinPath(appsDir, app, "functions", ".env");
|
|
@@ -16643,7 +16739,7 @@ async function setFirebaseSecret(key, value, projectId, dryRun = false, cwd) {
|
|
|
16643
16739
|
NODE_OPTIONS: ""
|
|
16644
16740
|
// Clear to avoid conflicts
|
|
16645
16741
|
};
|
|
16646
|
-
const result =
|
|
16742
|
+
const result = spawnSync8(firebaseCmd, args, {
|
|
16647
16743
|
input: value,
|
|
16648
16744
|
encoding: "utf8",
|
|
16649
16745
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -16736,7 +16832,7 @@ function setVercelSecret(key, value, projectId, dryRun = false) {
|
|
|
16736
16832
|
if (projectId) {
|
|
16737
16833
|
args.push("--project", projectId);
|
|
16738
16834
|
}
|
|
16739
|
-
const result =
|
|
16835
|
+
const result = spawnSync8("vercel", args, {
|
|
16740
16836
|
input: value,
|
|
16741
16837
|
encoding: "utf8",
|
|
16742
16838
|
stdio: ["pipe", "inherit", "inherit"]
|
|
@@ -16765,7 +16861,7 @@ function setVercelSecret(key, value, projectId, dryRun = false) {
|
|
|
16765
16861
|
}
|
|
16766
16862
|
function detectGitHubRepo() {
|
|
16767
16863
|
try {
|
|
16768
|
-
const result =
|
|
16864
|
+
const result = spawnSync8("git", ["remote", "get-url", "origin"], {
|
|
16769
16865
|
encoding: "utf8",
|
|
16770
16866
|
stdio: ["pipe", "pipe", "pipe"]
|
|
16771
16867
|
});
|
|
@@ -16793,7 +16889,7 @@ function setGitHubSecret(key, value, repo, dryRun = false) {
|
|
|
16793
16889
|
if (repo) {
|
|
16794
16890
|
args.push("--repo", repo);
|
|
16795
16891
|
}
|
|
16796
|
-
const result =
|
|
16892
|
+
const result = spawnSync8("gh", args, {
|
|
16797
16893
|
input: value,
|
|
16798
16894
|
encoding: "utf8",
|
|
16799
16895
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -16845,7 +16941,7 @@ function uploadServiceAccountToGitHub(appDir, repo, dryRun = false, staging = fa
|
|
|
16845
16941
|
const contentRaw = readSync(filePath, { format: "text" });
|
|
16846
16942
|
const content = typeof contentRaw === "string" ? contentRaw : null;
|
|
16847
16943
|
if (!content) return;
|
|
16848
|
-
const encoded =
|
|
16944
|
+
const encoded = Buffer.from(content).toString("base64");
|
|
16849
16945
|
setGitHubSecret(secretName, encoded, repo, dryRun);
|
|
16850
16946
|
}
|
|
16851
16947
|
async function main5(options = {}) {
|
|
@@ -16932,7 +17028,7 @@ Examples:
|
|
|
16932
17028
|
return 1;
|
|
16933
17029
|
}
|
|
16934
17030
|
log.info(`Syncing secrets to GitHub repository: ${repo}`);
|
|
16935
|
-
const secrets2 =
|
|
17031
|
+
const secrets2 = parseSecretsWithFallback(envFilePath, currentDir);
|
|
16936
17032
|
const secretKeys2 = Object.keys(secrets2);
|
|
16937
17033
|
if (secretKeys2.length === 0) {
|
|
16938
17034
|
log.info("No secrets found in .env file");
|
|
@@ -16968,14 +17064,13 @@ Examples:
|
|
|
16968
17064
|
return 0;
|
|
16969
17065
|
}
|
|
16970
17066
|
const platform6 = config.platform || detectPlatform();
|
|
16971
|
-
log.info(`Reading secrets from: ${envFilePath}`);
|
|
16972
17067
|
if (config.verbose) {
|
|
16973
17068
|
log.debug(`Working directory: ${currentDir}`);
|
|
16974
17069
|
log.debug(`Environment file: ${envFilePath}`);
|
|
16975
17070
|
log.debug(`Platform: ${platform6}`);
|
|
16976
17071
|
log.debug(`Dry run mode: ${config.dryRun}`);
|
|
16977
17072
|
}
|
|
16978
|
-
const secrets =
|
|
17073
|
+
const secrets = parseSecretsWithFallback(envFilePath, currentDir);
|
|
16979
17074
|
const secretKeys = Object.keys(secrets);
|
|
16980
17075
|
if (secretKeys.length === 0) {
|
|
16981
17076
|
log.info("No secrets found in .env file");
|
|
@@ -17036,6 +17131,7 @@ var init_sync_secrets = __esm({
|
|
|
17036
17131
|
init_cli_output();
|
|
17037
17132
|
init_errors();
|
|
17038
17133
|
init_pathResolver();
|
|
17134
|
+
init_secrets_resolver();
|
|
17039
17135
|
sync_secrets_default = main5;
|
|
17040
17136
|
}
|
|
17041
17137
|
});
|
|
@@ -17061,8 +17157,8 @@ async function deploySupabaseFunctions(appDir, config) {
|
|
|
17061
17157
|
);
|
|
17062
17158
|
const functionDirs = readdirSync2(functionsDir).filter((item) => {
|
|
17063
17159
|
const itemPath = joinPath(functionsDir, item);
|
|
17064
|
-
const
|
|
17065
|
-
return
|
|
17160
|
+
const stat2 = statSync2(itemPath);
|
|
17161
|
+
return stat2?.isDirectory() === true;
|
|
17066
17162
|
}).filter((dir) => {
|
|
17067
17163
|
const indexPath = joinPath(functionsDir, dir, "index.ts");
|
|
17068
17164
|
return pathExists(indexPath);
|
|
@@ -18394,9 +18490,11 @@ function processArrayIterations(content, replacements) {
|
|
|
18394
18490
|
function isValidFileName(name) {
|
|
18395
18491
|
return typeof name === "string" && /^[a-zA-Z0-9_-]+$/.test(name);
|
|
18396
18492
|
}
|
|
18397
|
-
var
|
|
18493
|
+
var RESERVED_APP_NAMES = ["demo", "dndev"];
|
|
18398
18494
|
function isReservedAppName(name) {
|
|
18399
|
-
return
|
|
18495
|
+
return RESERVED_APP_NAMES.includes(
|
|
18496
|
+
name.toLowerCase()
|
|
18497
|
+
);
|
|
18400
18498
|
}
|
|
18401
18499
|
async function updateRootPackageJson(rootDir, appNames) {
|
|
18402
18500
|
const packageJsonPath = joinPath(rootDir, "package.json");
|
|
@@ -18696,7 +18794,7 @@ var PROJECT_QUESTIONNAIRE = [
|
|
|
18696
18794
|
},
|
|
18697
18795
|
{
|
|
18698
18796
|
id: "appNames",
|
|
18699
|
-
question: `App name(s) (comma-separated for multiple, e.g., web, admin) - '${
|
|
18797
|
+
question: `App name(s) (comma-separated for multiple, e.g., web, admin) - '${RESERVED_APP_NAMES.join("', '")}' reserved`,
|
|
18700
18798
|
type: "input",
|
|
18701
18799
|
defaultValue: "web"
|
|
18702
18800
|
}
|
|
@@ -18787,48 +18885,168 @@ async function deployFrontend(appDir, serviceAccountPath, projectId, config) {
|
|
|
18787
18885
|
init_utils();
|
|
18788
18886
|
init_cli_output();
|
|
18789
18887
|
init_vercel_token();
|
|
18790
|
-
|
|
18888
|
+
init_pathResolver();
|
|
18889
|
+
import { createHash } from "node:crypto";
|
|
18890
|
+
import { readFile, readdir as readdir2 } from "node:fs/promises";
|
|
18891
|
+
import { join as join3, relative as relative3 } from "node:path";
|
|
18892
|
+
var VERCEL_API = "https://api.vercel.com";
|
|
18893
|
+
var UPLOAD_BATCH_SIZE = 10;
|
|
18894
|
+
var POLL_INTERVAL_MS = 3e3;
|
|
18895
|
+
var POLL_MAX_ATTEMPTS = 100;
|
|
18896
|
+
function apiHeaders(token, extra) {
|
|
18897
|
+
return { Authorization: `Bearer ${token}`, ...extra };
|
|
18898
|
+
}
|
|
18899
|
+
function teamQuery(orgId) {
|
|
18900
|
+
return `?teamId=${encodeURIComponent(orgId)}`;
|
|
18901
|
+
}
|
|
18902
|
+
async function collectDistFiles(distDir) {
|
|
18903
|
+
const files = [];
|
|
18904
|
+
async function walk(dir) {
|
|
18905
|
+
const entries = await readdir2(dir, { withFileTypes: true });
|
|
18906
|
+
for (const entry of entries) {
|
|
18907
|
+
const fullPath = join3(dir, entry.name);
|
|
18908
|
+
if (entry.isDirectory()) {
|
|
18909
|
+
await walk(fullPath);
|
|
18910
|
+
} else {
|
|
18911
|
+
const content = await readFile(fullPath);
|
|
18912
|
+
const sha = createHash("sha1").update(content).digest("hex");
|
|
18913
|
+
const rel = relative3(distDir, fullPath).split("\\").join("/");
|
|
18914
|
+
files.push({
|
|
18915
|
+
relativePath: rel,
|
|
18916
|
+
content,
|
|
18917
|
+
sha,
|
|
18918
|
+
size: content.byteLength
|
|
18919
|
+
});
|
|
18920
|
+
}
|
|
18921
|
+
}
|
|
18922
|
+
}
|
|
18923
|
+
await walk(distDir);
|
|
18924
|
+
return files;
|
|
18925
|
+
}
|
|
18926
|
+
async function uploadFiles(files, token, orgId) {
|
|
18927
|
+
const q2 = teamQuery(orgId);
|
|
18928
|
+
for (let i = 0; i < files.length; i += UPLOAD_BATCH_SIZE) {
|
|
18929
|
+
const batch = files.slice(i, i + UPLOAD_BATCH_SIZE);
|
|
18930
|
+
await Promise.all(
|
|
18931
|
+
batch.map(async (file) => {
|
|
18932
|
+
const res = await fetch(`${VERCEL_API}/v2/files${q2}`, {
|
|
18933
|
+
method: "POST",
|
|
18934
|
+
headers: apiHeaders(token, {
|
|
18935
|
+
"Content-Type": "application/octet-stream",
|
|
18936
|
+
"x-vercel-digest": file.sha,
|
|
18937
|
+
"Content-Length": String(file.size)
|
|
18938
|
+
}),
|
|
18939
|
+
body: new Uint8Array(file.content)
|
|
18940
|
+
});
|
|
18941
|
+
if (!res.ok) {
|
|
18942
|
+
const body = await res.text();
|
|
18943
|
+
throw new Error(
|
|
18944
|
+
`File upload failed for ${file.relativePath} (${res.status}): ${body}`
|
|
18945
|
+
);
|
|
18946
|
+
}
|
|
18947
|
+
})
|
|
18948
|
+
);
|
|
18949
|
+
}
|
|
18950
|
+
}
|
|
18951
|
+
async function createDeployment(files, token, orgId, projectId) {
|
|
18952
|
+
const q2 = teamQuery(orgId);
|
|
18953
|
+
const body = {
|
|
18954
|
+
project: projectId,
|
|
18955
|
+
target: "production",
|
|
18956
|
+
files: files.map((f) => ({
|
|
18957
|
+
file: f.relativePath,
|
|
18958
|
+
sha: f.sha,
|
|
18959
|
+
size: f.size
|
|
18960
|
+
})),
|
|
18961
|
+
projectSettings: {
|
|
18962
|
+
buildCommand: "",
|
|
18963
|
+
installCommand: "",
|
|
18964
|
+
outputDirectory: "."
|
|
18965
|
+
}
|
|
18966
|
+
};
|
|
18967
|
+
const res = await fetch(`${VERCEL_API}/v13/deployments${q2}`, {
|
|
18968
|
+
method: "POST",
|
|
18969
|
+
headers: apiHeaders(token, { "Content-Type": "application/json" }),
|
|
18970
|
+
body: JSON.stringify(body)
|
|
18971
|
+
});
|
|
18972
|
+
if (!res.ok) {
|
|
18973
|
+
const text = await res.text();
|
|
18974
|
+
throw new Error(`Create deployment failed (${res.status}): ${text}`);
|
|
18975
|
+
}
|
|
18976
|
+
return await res.json();
|
|
18977
|
+
}
|
|
18978
|
+
async function waitForReady(deploymentId, token, orgId) {
|
|
18979
|
+
const q2 = teamQuery(orgId);
|
|
18980
|
+
for (let attempt = 0; attempt < POLL_MAX_ATTEMPTS; attempt++) {
|
|
18981
|
+
const res = await fetch(
|
|
18982
|
+
`${VERCEL_API}/v13/deployments/${deploymentId}${q2}`,
|
|
18983
|
+
{ headers: apiHeaders(token) }
|
|
18984
|
+
);
|
|
18985
|
+
if (!res.ok) {
|
|
18986
|
+
const text = await res.text();
|
|
18987
|
+
throw new Error(
|
|
18988
|
+
`Deployment status check failed (${res.status}): ${text}`
|
|
18989
|
+
);
|
|
18990
|
+
}
|
|
18991
|
+
const data = await res.json();
|
|
18992
|
+
if (data.readyState === "READY") return data;
|
|
18993
|
+
if (data.readyState === "ERROR") {
|
|
18994
|
+
throw new Error(
|
|
18995
|
+
`Deployment failed: ${data.errorMessage || "Unknown error"}`
|
|
18996
|
+
);
|
|
18997
|
+
}
|
|
18998
|
+
if (data.readyState === "CANCELED") {
|
|
18999
|
+
throw new Error("Deployment was canceled");
|
|
19000
|
+
}
|
|
19001
|
+
await new Promise((r2) => setTimeout(r2, POLL_INTERVAL_MS));
|
|
19002
|
+
}
|
|
19003
|
+
throw new Error("Deployment timed out (5+ minutes)");
|
|
19004
|
+
}
|
|
18791
19005
|
async function deployVercelFrontend(appDir, _config) {
|
|
18792
19006
|
const result = resolveVercelCredentials(appDir);
|
|
18793
19007
|
if (result.missing) {
|
|
19008
|
+
const secretVars = result.missing.filter((v2) => v2 === "VERCEL_TOKEN");
|
|
19009
|
+
const appVars = result.missing.filter((v2) => v2 !== "VERCEL_TOKEN");
|
|
19010
|
+
const hints = [];
|
|
19011
|
+
if (secretVars.length > 0)
|
|
19012
|
+
hints.push("Add VERCEL_TOKEN to .dndev.secrets at project root.");
|
|
19013
|
+
if (appVars.length > 0)
|
|
19014
|
+
hints.push(`Add ${appVars.join(", ")} to apps/<app>/.env`);
|
|
18794
19015
|
throw new Error(
|
|
18795
|
-
`Missing Vercel credentials
|
|
18796
|
-
|
|
19016
|
+
`Missing Vercel credentials: ${result.missing.join(", ")}
|
|
19017
|
+
` + hints.join("\n") + "\nSee guides/dndev/SETUP_VERCEL.md"
|
|
18797
19018
|
);
|
|
18798
19019
|
}
|
|
18799
19020
|
const { token, orgId, projectId } = result.credentials;
|
|
18800
|
-
|
|
18801
|
-
|
|
18802
|
-
|
|
18803
|
-
|
|
18804
|
-
|
|
18805
|
-
|
|
18806
|
-
|
|
18807
|
-
|
|
18808
|
-
|
|
18809
|
-
|
|
18810
|
-
|
|
18811
|
-
|
|
18812
|
-
|
|
18813
|
-
|
|
18814
|
-
|
|
18815
|
-
|
|
18816
|
-
);
|
|
18817
|
-
|
|
18818
|
-
|
|
18819
|
-
}
|
|
18820
|
-
|
|
18821
|
-
|
|
18822
|
-
log.success(`Production: ${deployUrl}`);
|
|
18823
|
-
} else {
|
|
18824
|
-
log.success("Frontend deployed to Vercel");
|
|
19021
|
+
const distDir = joinPath(appDir, "dist");
|
|
19022
|
+
if (!pathExists(distDir)) {
|
|
19023
|
+
throw new Error(`dist/ not found at ${distDir}. Run build first.`);
|
|
19024
|
+
}
|
|
19025
|
+
log.debug("Using Vercel REST API (token-based, no CLI)");
|
|
19026
|
+
log.info("Collecting dist/ files...");
|
|
19027
|
+
const files = await collectDistFiles(distDir);
|
|
19028
|
+
if (files.length === 0) {
|
|
19029
|
+
throw new Error("dist/ is empty \u2014 nothing to deploy.");
|
|
19030
|
+
}
|
|
19031
|
+
log.info(`Found ${files.length} files`);
|
|
19032
|
+
log.info("Uploading files to Vercel...");
|
|
19033
|
+
await uploadFiles(files, token, orgId);
|
|
19034
|
+
log.success(`${files.length} files uploaded`);
|
|
19035
|
+
log.info("Creating production deployment...");
|
|
19036
|
+
const deployment = await createDeployment(files, token, orgId, projectId);
|
|
19037
|
+
log.info(`Deployment ${deployment.id} created, waiting...`);
|
|
19038
|
+
const ready = await waitForReady(deployment.id, token, orgId);
|
|
19039
|
+
const prodUrl = `https://${ready.url}`;
|
|
19040
|
+
log.success(`Production: ${prodUrl}`);
|
|
19041
|
+
if (ready.alias?.length) {
|
|
19042
|
+
log.info(`Aliases: ${ready.alias.join(", ")}`);
|
|
18825
19043
|
}
|
|
18826
19044
|
}
|
|
18827
19045
|
|
|
18828
19046
|
// packages/tooling/src/apps/deploy-functions.ts
|
|
18829
19047
|
init_utils();
|
|
18830
19048
|
var import_yaml = __toESM(require_dist(), 1);
|
|
18831
|
-
import { execSync as execSync8, spawnSync as
|
|
19049
|
+
import { execSync as execSync8, spawnSync as spawnSync6 } from "node:child_process";
|
|
18832
19050
|
init_pathResolver();
|
|
18833
19051
|
init_cli_tools();
|
|
18834
19052
|
init_typed_file_operations();
|
|
@@ -18885,6 +19103,14 @@ function generateCleanPackageJson(functionsDir) {
|
|
|
18885
19103
|
}
|
|
18886
19104
|
const cleanPackageJson = { ...packageJson };
|
|
18887
19105
|
if (cleanPackageJson.dependencies) {
|
|
19106
|
+
const removedDeps = Object.entries(cleanPackageJson.dependencies).filter(
|
|
19107
|
+
([, version]) => String(version).startsWith("file:") || String(version).startsWith("workspace:")
|
|
19108
|
+
);
|
|
19109
|
+
if (removedDeps.length > 0) {
|
|
19110
|
+
log.warn(
|
|
19111
|
+
`Filtering out ${removedDeps.length} workspace/file dep(s) from dependencies: ${removedDeps.map(([name]) => name).join(", ")}`
|
|
19112
|
+
);
|
|
19113
|
+
}
|
|
18888
19114
|
cleanPackageJson.dependencies = Object.fromEntries(
|
|
18889
19115
|
Object.entries(cleanPackageJson.dependencies).filter(
|
|
18890
19116
|
([, version]) => !String(version).startsWith("file:") && !String(version).startsWith("workspace:")
|
|
@@ -18892,6 +19118,16 @@ function generateCleanPackageJson(functionsDir) {
|
|
|
18892
19118
|
);
|
|
18893
19119
|
}
|
|
18894
19120
|
if (cleanPackageJson.devDependencies) {
|
|
19121
|
+
const removedDevDeps = Object.entries(
|
|
19122
|
+
cleanPackageJson.devDependencies
|
|
19123
|
+
).filter(
|
|
19124
|
+
([, version]) => String(version).startsWith("file:") || String(version).startsWith("workspace:")
|
|
19125
|
+
);
|
|
19126
|
+
if (removedDevDeps.length > 0) {
|
|
19127
|
+
log.warn(
|
|
19128
|
+
`Filtering out ${removedDevDeps.length} workspace/file dep(s) from devDependencies: ${removedDevDeps.map(([name]) => name).join(", ")}`
|
|
19129
|
+
);
|
|
19130
|
+
}
|
|
18895
19131
|
cleanPackageJson.devDependencies = Object.fromEntries(
|
|
18896
19132
|
Object.entries(cleanPackageJson.devDependencies).filter(
|
|
18897
19133
|
([, version]) => !String(version).startsWith("file:") && !String(version).startsWith("workspace:")
|
|
@@ -18997,7 +19233,7 @@ function updateCloudRunIAM(functionNames, projectId, region, serviceAccountPath,
|
|
|
18997
19233
|
let failCount = 0;
|
|
18998
19234
|
for (const funcName of functionNames) {
|
|
18999
19235
|
try {
|
|
19000
|
-
const result =
|
|
19236
|
+
const result = spawnSync6(
|
|
19001
19237
|
"gcloud",
|
|
19002
19238
|
[
|
|
19003
19239
|
"run",
|
|
@@ -19115,7 +19351,7 @@ async function autoSyncSecrets(functionsDir, projectId, config) {
|
|
|
19115
19351
|
let failCount = 0;
|
|
19116
19352
|
for (const { key, value } of secrets) {
|
|
19117
19353
|
try {
|
|
19118
|
-
const result =
|
|
19354
|
+
const result = spawnSync6(
|
|
19119
19355
|
firebaseCmd,
|
|
19120
19356
|
["functions:secrets:set", key, "--project", projectId],
|
|
19121
19357
|
{
|
|
@@ -19302,7 +19538,7 @@ async function deployRules(appDir, serviceAccountPath, projectId, config, option
|
|
|
19302
19538
|
|
|
19303
19539
|
// packages/tooling/src/apps/deploy-utils.ts
|
|
19304
19540
|
init_utils();
|
|
19305
|
-
import { spawnSync as
|
|
19541
|
+
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
19306
19542
|
init_pathResolver();
|
|
19307
19543
|
init_typed_file_operations();
|
|
19308
19544
|
init_error_handling();
|
|
@@ -19314,8 +19550,8 @@ function detectAvailableApps() {
|
|
|
19314
19550
|
}
|
|
19315
19551
|
return readdirSync2(appsDir).filter((item) => {
|
|
19316
19552
|
const itemPath = joinPath(appsDir, item);
|
|
19317
|
-
const
|
|
19318
|
-
return
|
|
19553
|
+
const stat2 = statSync2(itemPath);
|
|
19554
|
+
return stat2?.isDirectory() === true;
|
|
19319
19555
|
}).filter((app) => {
|
|
19320
19556
|
const appDir = joinPath(appsDir, app);
|
|
19321
19557
|
const firebaseJsonPath = joinPath(appDir, "firebase.json");
|
|
@@ -19490,7 +19726,7 @@ How to fix:
|
|
|
19490
19726
|
if (shouldOpen) {
|
|
19491
19727
|
try {
|
|
19492
19728
|
const openCommand = process.platform === "win32" ? "start" : process.platform === "darwin" ? "open" : "xdg-open";
|
|
19493
|
-
|
|
19729
|
+
spawnSync7(openCommand, [consoleUrl], { shell: true });
|
|
19494
19730
|
log.success("Opening Firebase Console...");
|
|
19495
19731
|
} catch {
|
|
19496
19732
|
log.warn("Could not open browser. Please open the URL manually.");
|
|
@@ -19921,12 +20157,6 @@ async function main6(options = {}) {
|
|
|
19921
20157
|
...serviceAccountPath ? [`Service Account: ${serviceAccountPath}`] : []
|
|
19922
20158
|
].join("\n");
|
|
19923
20159
|
Me(configNote, "Deployment Configuration");
|
|
19924
|
-
if (shouldDeployVercelFrontend) {
|
|
19925
|
-
requireCLI(
|
|
19926
|
-
CLI_TOOLS.VERCEL,
|
|
19927
|
-
"Vercel CLI is required to deploy the frontend.\nInstall: bun install -g vercel"
|
|
19928
|
-
);
|
|
19929
|
-
}
|
|
19930
20160
|
if (shouldDeployFirebaseFrontend && serviceAccountPath && config.project) {
|
|
19931
20161
|
await deployFrontend(appDir, serviceAccountPath, config.project, config);
|
|
19932
20162
|
}
|
|
@@ -20057,6 +20287,11 @@ function generateScripts(templateName, options) {
|
|
|
20057
20287
|
scripts.build = "tsc --noEmit && vite build --mode production";
|
|
20058
20288
|
scripts.preview = "vite preview";
|
|
20059
20289
|
scripts["type-check"] = "tsc --noEmit";
|
|
20290
|
+
} else if (templateName === "dndev") {
|
|
20291
|
+
scripts.dev = "vite";
|
|
20292
|
+
scripts.build = "tsc --noEmit && vite build --mode production";
|
|
20293
|
+
scripts.preview = "vite preview";
|
|
20294
|
+
scripts["type-check"] = "tsc --noEmit";
|
|
20060
20295
|
} else if (templateName === "entities") {
|
|
20061
20296
|
}
|
|
20062
20297
|
return scripts;
|
|
@@ -20184,7 +20419,7 @@ function resolveDeployConfig(host, backend) {
|
|
|
20184
20419
|
return "vercel-vercel";
|
|
20185
20420
|
}
|
|
20186
20421
|
function getScaffoldParts(builder, host, functions, backend) {
|
|
20187
|
-
const baseTemplate = builder === "nextjs" ? "app-next" : builder === "demo" ? "app-demo" : `app-${builder}`;
|
|
20422
|
+
const baseTemplate = builder === "nextjs" ? "app-next" : builder === "demo" ? "app-demo" : builder === "dndev" ? "app-dndev" : `app-${builder}`;
|
|
20188
20423
|
return {
|
|
20189
20424
|
builder,
|
|
20190
20425
|
backend,
|
|
@@ -20212,7 +20447,7 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
20212
20447
|
Ie("\u{1F680} DoNotDev App Creator");
|
|
20213
20448
|
if (!appName) {
|
|
20214
20449
|
appName = await askForInput(
|
|
20215
|
-
`App name - '${
|
|
20450
|
+
`App name - '${RESERVED_APP_NAMES.join("', '")}' reserved`,
|
|
20216
20451
|
"my-app"
|
|
20217
20452
|
);
|
|
20218
20453
|
if (!isValidFileName(appName)) {
|
|
@@ -20413,12 +20648,13 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
20413
20648
|
}
|
|
20414
20649
|
}
|
|
20415
20650
|
const executionMode = detectExecutionMode();
|
|
20416
|
-
const
|
|
20651
|
+
const isReservedTemplate = appTemplate === "demo" || appTemplate === "dndev";
|
|
20652
|
+
const templateName = isReservedTemplate ? appTemplate : executionMode === "development" ? `dev-${appTemplate}` : `consumer-${appTemplate}`;
|
|
20417
20653
|
const packageJson = generatePackageJson(templateName, executionMode, {
|
|
20418
20654
|
appName,
|
|
20419
|
-
template:
|
|
20655
|
+
template: isReservedTemplate ? "vite" : appTemplate,
|
|
20420
20656
|
includeFunctions: Boolean(row.functionsTemplate),
|
|
20421
|
-
platform:
|
|
20657
|
+
platform: isReservedTemplate ? void 0 : backendPlatform
|
|
20422
20658
|
});
|
|
20423
20659
|
const packageJsonPath = joinPath(appDir, "package.json");
|
|
20424
20660
|
await write(packageJsonPath, packageJson, {
|
|
@@ -20493,7 +20729,7 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
20493
20729
|
const firebaseJson = readSync(firebaseJsonDest, {
|
|
20494
20730
|
format: "json"
|
|
20495
20731
|
});
|
|
20496
|
-
if (firebaseJson.hosting?.rewrites) {
|
|
20732
|
+
if (firebaseJson.hosting?.rewrites && Array.isArray(firebaseJson.hosting.rewrites)) {
|
|
20497
20733
|
firebaseJson.hosting.rewrites = firebaseJson.hosting.rewrites.filter(
|
|
20498
20734
|
(r2) => r2.destination !== "/index.html"
|
|
20499
20735
|
);
|
|
@@ -20781,6 +21017,14 @@ async function main9(options) {
|
|
|
20781
21017
|
process.exit(0);
|
|
20782
21018
|
}
|
|
20783
21019
|
if (action === "replace") {
|
|
21020
|
+
const confirmDelete = await askForConfirmation(
|
|
21021
|
+
`This will permanently delete "${projectDirNormalized}". Are you sure?`,
|
|
21022
|
+
false
|
|
21023
|
+
);
|
|
21024
|
+
if (!confirmDelete) {
|
|
21025
|
+
Se("Project creation cancelled.");
|
|
21026
|
+
process.exit(0);
|
|
21027
|
+
}
|
|
20784
21028
|
const s2 = Y2();
|
|
20785
21029
|
s2.start("Removing existing project...");
|
|
20786
21030
|
await remove(projectDirNormalized);
|
|
@@ -20842,6 +21086,10 @@ async function main9(options) {
|
|
|
20842
21086
|
"Would you like to install the demo app? (component showcase)",
|
|
20843
21087
|
false
|
|
20844
21088
|
);
|
|
21089
|
+
let installCockpitApp = await askForConfirmation(
|
|
21090
|
+
"Would you like to install the cockpit app? (AI development dashboard)",
|
|
21091
|
+
false
|
|
21092
|
+
);
|
|
20845
21093
|
let allAppNames = [...appNames];
|
|
20846
21094
|
let appsToCreate = [];
|
|
20847
21095
|
let appsToSkip = [];
|
|
@@ -20965,6 +21213,13 @@ async function main9(options) {
|
|
|
20965
21213
|
const primaryPlatform = Object.values(appConfigs).find(
|
|
20966
21214
|
(c) => c.backend !== "none"
|
|
20967
21215
|
)?.backend ?? "firebase";
|
|
21216
|
+
const hasVercel = Object.values(appConfigs).some(
|
|
21217
|
+
(c) => c.host === "vercel"
|
|
21218
|
+
);
|
|
21219
|
+
const hasSupabase = Object.values(appConfigs).some(
|
|
21220
|
+
(c) => c.backend === "supabase"
|
|
21221
|
+
);
|
|
21222
|
+
const hasBilling = Object.values(appConfigs).some((c) => c.billing);
|
|
20968
21223
|
const rootPackageJson = generatePackageJson(
|
|
20969
21224
|
"consumer-root",
|
|
20970
21225
|
executionMode,
|
|
@@ -20999,8 +21254,12 @@ async function main9(options) {
|
|
|
20999
21254
|
// Determined by agent in WAI-WAY Phase 0
|
|
21000
21255
|
needsOAuth: false,
|
|
21001
21256
|
// Determined by agent in WAI-WAY Phase 0
|
|
21002
|
-
needsBilling: false
|
|
21257
|
+
needsBilling: false,
|
|
21003
21258
|
// Determined by agent in WAI-WAY Phase 0
|
|
21259
|
+
// .dndev.secrets conditional sections
|
|
21260
|
+
vercel: hasVercel,
|
|
21261
|
+
supabase: hasSupabase,
|
|
21262
|
+
stripe: hasBilling
|
|
21004
21263
|
};
|
|
21005
21264
|
const firebaseRootFiles = /* @__PURE__ */ new Set([
|
|
21006
21265
|
"firebase.json.example",
|
|
@@ -21029,6 +21288,13 @@ async function main9(options) {
|
|
|
21029
21288
|
await replacePlaceholders(destPath, rootReplacements);
|
|
21030
21289
|
}
|
|
21031
21290
|
}
|
|
21291
|
+
const dndevSecretsPath = joinPath(projectDirNormalized, ".dndev.secrets");
|
|
21292
|
+
if (pathExists(dndevSecretsPath)) {
|
|
21293
|
+
await copy(
|
|
21294
|
+
dndevSecretsPath,
|
|
21295
|
+
joinPath(projectDirNormalized, ".dndev.secrets.example")
|
|
21296
|
+
);
|
|
21297
|
+
}
|
|
21032
21298
|
if (setupGithubActions) {
|
|
21033
21299
|
const ciTemplateDir = joinPath(templatesRoot, "github");
|
|
21034
21300
|
await copyTemplateFiles(
|
|
@@ -21129,6 +21395,61 @@ async function main9(options) {
|
|
|
21129
21395
|
sDemo.stop("Demo app copied");
|
|
21130
21396
|
}
|
|
21131
21397
|
}
|
|
21398
|
+
if (installCockpitApp) {
|
|
21399
|
+
const sCockpit = Y2();
|
|
21400
|
+
sCockpit.start("Copying cockpit app...");
|
|
21401
|
+
const cockpitAppDir = joinPath(projectDirNormalized, "apps", "dndev");
|
|
21402
|
+
const cockpitTemplateDir = joinPath(templatesRoot, "app-dndev");
|
|
21403
|
+
if (pathExists(cockpitAppDir)) {
|
|
21404
|
+
if (isMergeMode) {
|
|
21405
|
+
const cockpitAction = await askForSelection(
|
|
21406
|
+
"Cockpit app already exists. What would you like to do?",
|
|
21407
|
+
[
|
|
21408
|
+
{ title: "Replace (delete and recreate)", value: "replace" },
|
|
21409
|
+
{ title: "Skip (keep existing)", value: "skip" }
|
|
21410
|
+
],
|
|
21411
|
+
1
|
|
21412
|
+
);
|
|
21413
|
+
if (cockpitAction === "replace") {
|
|
21414
|
+
await remove(cockpitAppDir);
|
|
21415
|
+
} else {
|
|
21416
|
+
sCockpit.stop("Cockpit app skipped (already exists)");
|
|
21417
|
+
installCockpitApp = false;
|
|
21418
|
+
}
|
|
21419
|
+
} else {
|
|
21420
|
+
await remove(cockpitAppDir);
|
|
21421
|
+
}
|
|
21422
|
+
}
|
|
21423
|
+
if (installCockpitApp) {
|
|
21424
|
+
const cockpitFirebaseProjectId = projectName.toLowerCase().replace(/\s+/g, "-");
|
|
21425
|
+
await copyTemplateFiles(cockpitTemplateDir, cockpitAppDir, {
|
|
21426
|
+
projectName,
|
|
21427
|
+
appName: "dndev",
|
|
21428
|
+
includeFunctions: false,
|
|
21429
|
+
needsCRUD: false,
|
|
21430
|
+
setupGithubActions: false,
|
|
21431
|
+
appNames,
|
|
21432
|
+
firebaseProjectId: cockpitFirebaseProjectId,
|
|
21433
|
+
firebaseRegion: "europe-west1",
|
|
21434
|
+
firebaseSecretName: projectName.toUpperCase().replace(/-/g, "_"),
|
|
21435
|
+
YOUR_FIREBASE_PROJECT_ID: cockpitFirebaseProjectId,
|
|
21436
|
+
YOUR_REGION: "europe-west1",
|
|
21437
|
+
monorepoRelativePath: executionMode === "development" ? calculateRelativePath(projectDirNormalized, monorepoRoot) : "",
|
|
21438
|
+
appTemplate: "dndev"
|
|
21439
|
+
});
|
|
21440
|
+
const packageJson = generatePackageJson("dndev", executionMode, {
|
|
21441
|
+
appName: "dndev",
|
|
21442
|
+
template: "vite",
|
|
21443
|
+
includeFunctions: false
|
|
21444
|
+
});
|
|
21445
|
+
const packageJsonPath = joinPath(cockpitAppDir, "package.json");
|
|
21446
|
+
await write(packageJsonPath, packageJson, {
|
|
21447
|
+
format: "json",
|
|
21448
|
+
overwrite: true
|
|
21449
|
+
});
|
|
21450
|
+
sCockpit.stop("Cockpit app copied");
|
|
21451
|
+
}
|
|
21452
|
+
}
|
|
21132
21453
|
log.info("Creating apps...");
|
|
21133
21454
|
for (const appName of appNames) {
|
|
21134
21455
|
const appConfig = appConfigs[appName];
|
|
@@ -21139,7 +21460,10 @@ async function main9(options) {
|
|
|
21139
21460
|
await createApp(appName, appConfig, projectDirNormalized, templatesRoot);
|
|
21140
21461
|
}
|
|
21141
21462
|
s.start("Updating root package.json with scripts...");
|
|
21142
|
-
await updateRootPackageJson(
|
|
21463
|
+
await updateRootPackageJson(
|
|
21464
|
+
projectDirNormalized,
|
|
21465
|
+
isMergeMode ? allAppNames : appNames
|
|
21466
|
+
);
|
|
21143
21467
|
s.stop("Root package.json updated");
|
|
21144
21468
|
Se("\u{1F389} Project created successfully!");
|
|
21145
21469
|
const cdCommand = executionMode === "development" ? `cd ../${projectName}` : `cd ${projectName}`;
|
|
@@ -21171,7 +21495,7 @@ init_utils();
|
|
|
21171
21495
|
init_cli_output();
|
|
21172
21496
|
init_errors();
|
|
21173
21497
|
init_pathResolver();
|
|
21174
|
-
import { spawnSync as
|
|
21498
|
+
import { spawnSync as spawnSync9 } from "node:child_process";
|
|
21175
21499
|
import { EOL as EOL2 } from "node:os";
|
|
21176
21500
|
async function main10(options = {}) {
|
|
21177
21501
|
const dryRun = options.dryRun ?? false;
|
|
@@ -21651,7 +21975,7 @@ async function runPrettier(rootDir, dryRun, verbose) {
|
|
|
21651
21975
|
log.info("DRY RUN: Would run Prettier");
|
|
21652
21976
|
return stats;
|
|
21653
21977
|
}
|
|
21654
|
-
const result =
|
|
21978
|
+
const result = spawnSync9("bunx", prettierArgs, {
|
|
21655
21979
|
cwd: rootDir,
|
|
21656
21980
|
stdio: "pipe",
|
|
21657
21981
|
shell: true,
|
|
@@ -21822,8 +22146,8 @@ async function findCacheItems(targetDir, verbose) {
|
|
|
21822
22146
|
for (const nestedPkg of nestedPackages) {
|
|
21823
22147
|
const nestedPkgPath = joinPath(pkgPath, nestedPkg);
|
|
21824
22148
|
try {
|
|
21825
|
-
const
|
|
21826
|
-
if (
|
|
22149
|
+
const stat2 = statSync2(nestedPkgPath);
|
|
22150
|
+
if (stat2?.isDirectory()) {
|
|
21827
22151
|
check(joinPath(nestedPkgPath, ".vite"));
|
|
21828
22152
|
check(joinPath(nestedPkgPath, "dist"));
|
|
21829
22153
|
check(joinPath(nestedPkgPath, "node_modules", ".vite"));
|