@donotdev/cli 0.0.20 → 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 +86 -19
- package/dist/bin/commands/agent-setup.js +2 -2
- package/dist/bin/commands/build.js +6 -6
- package/dist/bin/commands/bump.js +491 -69
- package/dist/bin/commands/cacheout.js +6 -6
- package/dist/bin/commands/coach.js +6 -6
- package/dist/bin/commands/create-app.js +23 -15
- package/dist/bin/commands/create-project.js +101 -16
- package/dist/bin/commands/db.js +142136 -0
- package/dist/bin/commands/deploy.js +336 -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 +256 -212
- package/dist/bin/commands/staging.js +343 -127
- package/dist/bin/commands/sync-secrets.js +55 -33
- package/dist/bin/commands/type-check.js +6 -6
- package/dist/bin/commands/wai.js +6 -6
- package/dist/bin/dndev.js +76 -11
- package/dist/bin/donotdev.js +21 -12
- package/dist/index.js +437 -142
- 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-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-next/src/locales/home_en.json.example +6 -6
- package/templates/app-vite/index.html.example +1 -1
- package/templates/app-vite/src/locales/home_en.json.example +6 -6
- 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/dndev/advanced/COOKIE_REFERENCE.md.example +252 -252
- package/templates/root-consumer/guides/dndev/advanced/VERSION_CONTROL.md.example +174 -174
- 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();
|
|
@@ -19015,7 +19233,7 @@ function updateCloudRunIAM(functionNames, projectId, region, serviceAccountPath,
|
|
|
19015
19233
|
let failCount = 0;
|
|
19016
19234
|
for (const funcName of functionNames) {
|
|
19017
19235
|
try {
|
|
19018
|
-
const result =
|
|
19236
|
+
const result = spawnSync6(
|
|
19019
19237
|
"gcloud",
|
|
19020
19238
|
[
|
|
19021
19239
|
"run",
|
|
@@ -19133,7 +19351,7 @@ async function autoSyncSecrets(functionsDir, projectId, config) {
|
|
|
19133
19351
|
let failCount = 0;
|
|
19134
19352
|
for (const { key, value } of secrets) {
|
|
19135
19353
|
try {
|
|
19136
|
-
const result =
|
|
19354
|
+
const result = spawnSync6(
|
|
19137
19355
|
firebaseCmd,
|
|
19138
19356
|
["functions:secrets:set", key, "--project", projectId],
|
|
19139
19357
|
{
|
|
@@ -19320,7 +19538,7 @@ async function deployRules(appDir, serviceAccountPath, projectId, config, option
|
|
|
19320
19538
|
|
|
19321
19539
|
// packages/tooling/src/apps/deploy-utils.ts
|
|
19322
19540
|
init_utils();
|
|
19323
|
-
import { spawnSync as
|
|
19541
|
+
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
19324
19542
|
init_pathResolver();
|
|
19325
19543
|
init_typed_file_operations();
|
|
19326
19544
|
init_error_handling();
|
|
@@ -19332,8 +19550,8 @@ function detectAvailableApps() {
|
|
|
19332
19550
|
}
|
|
19333
19551
|
return readdirSync2(appsDir).filter((item) => {
|
|
19334
19552
|
const itemPath = joinPath(appsDir, item);
|
|
19335
|
-
const
|
|
19336
|
-
return
|
|
19553
|
+
const stat2 = statSync2(itemPath);
|
|
19554
|
+
return stat2?.isDirectory() === true;
|
|
19337
19555
|
}).filter((app) => {
|
|
19338
19556
|
const appDir = joinPath(appsDir, app);
|
|
19339
19557
|
const firebaseJsonPath = joinPath(appDir, "firebase.json");
|
|
@@ -19508,7 +19726,7 @@ How to fix:
|
|
|
19508
19726
|
if (shouldOpen) {
|
|
19509
19727
|
try {
|
|
19510
19728
|
const openCommand = process.platform === "win32" ? "start" : process.platform === "darwin" ? "open" : "xdg-open";
|
|
19511
|
-
|
|
19729
|
+
spawnSync7(openCommand, [consoleUrl], { shell: true });
|
|
19512
19730
|
log.success("Opening Firebase Console...");
|
|
19513
19731
|
} catch {
|
|
19514
19732
|
log.warn("Could not open browser. Please open the URL manually.");
|
|
@@ -19939,12 +20157,6 @@ async function main6(options = {}) {
|
|
|
19939
20157
|
...serviceAccountPath ? [`Service Account: ${serviceAccountPath}`] : []
|
|
19940
20158
|
].join("\n");
|
|
19941
20159
|
Me(configNote, "Deployment Configuration");
|
|
19942
|
-
if (shouldDeployVercelFrontend) {
|
|
19943
|
-
requireCLI(
|
|
19944
|
-
CLI_TOOLS.VERCEL,
|
|
19945
|
-
"Vercel CLI is required to deploy the frontend.\nInstall: bun install -g vercel"
|
|
19946
|
-
);
|
|
19947
|
-
}
|
|
19948
20160
|
if (shouldDeployFirebaseFrontend && serviceAccountPath && config.project) {
|
|
19949
20161
|
await deployFrontend(appDir, serviceAccountPath, config.project, config);
|
|
19950
20162
|
}
|
|
@@ -20075,6 +20287,11 @@ function generateScripts(templateName, options) {
|
|
|
20075
20287
|
scripts.build = "tsc --noEmit && vite build --mode production";
|
|
20076
20288
|
scripts.preview = "vite preview";
|
|
20077
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";
|
|
20078
20295
|
} else if (templateName === "entities") {
|
|
20079
20296
|
}
|
|
20080
20297
|
return scripts;
|
|
@@ -20202,7 +20419,7 @@ function resolveDeployConfig(host, backend) {
|
|
|
20202
20419
|
return "vercel-vercel";
|
|
20203
20420
|
}
|
|
20204
20421
|
function getScaffoldParts(builder, host, functions, backend) {
|
|
20205
|
-
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}`;
|
|
20206
20423
|
return {
|
|
20207
20424
|
builder,
|
|
20208
20425
|
backend,
|
|
@@ -20230,7 +20447,7 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
20230
20447
|
Ie("\u{1F680} DoNotDev App Creator");
|
|
20231
20448
|
if (!appName) {
|
|
20232
20449
|
appName = await askForInput(
|
|
20233
|
-
`App name - '${
|
|
20450
|
+
`App name - '${RESERVED_APP_NAMES.join("', '")}' reserved`,
|
|
20234
20451
|
"my-app"
|
|
20235
20452
|
);
|
|
20236
20453
|
if (!isValidFileName(appName)) {
|
|
@@ -20431,12 +20648,13 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
20431
20648
|
}
|
|
20432
20649
|
}
|
|
20433
20650
|
const executionMode = detectExecutionMode();
|
|
20434
|
-
const
|
|
20651
|
+
const isReservedTemplate = appTemplate === "demo" || appTemplate === "dndev";
|
|
20652
|
+
const templateName = isReservedTemplate ? appTemplate : executionMode === "development" ? `dev-${appTemplate}` : `consumer-${appTemplate}`;
|
|
20435
20653
|
const packageJson = generatePackageJson(templateName, executionMode, {
|
|
20436
20654
|
appName,
|
|
20437
|
-
template:
|
|
20655
|
+
template: isReservedTemplate ? "vite" : appTemplate,
|
|
20438
20656
|
includeFunctions: Boolean(row.functionsTemplate),
|
|
20439
|
-
platform:
|
|
20657
|
+
platform: isReservedTemplate ? void 0 : backendPlatform
|
|
20440
20658
|
});
|
|
20441
20659
|
const packageJsonPath = joinPath(appDir, "package.json");
|
|
20442
20660
|
await write(packageJsonPath, packageJson, {
|
|
@@ -20868,6 +21086,10 @@ async function main9(options) {
|
|
|
20868
21086
|
"Would you like to install the demo app? (component showcase)",
|
|
20869
21087
|
false
|
|
20870
21088
|
);
|
|
21089
|
+
let installCockpitApp = await askForConfirmation(
|
|
21090
|
+
"Would you like to install the cockpit app? (AI development dashboard)",
|
|
21091
|
+
false
|
|
21092
|
+
);
|
|
20871
21093
|
let allAppNames = [...appNames];
|
|
20872
21094
|
let appsToCreate = [];
|
|
20873
21095
|
let appsToSkip = [];
|
|
@@ -20991,6 +21213,13 @@ async function main9(options) {
|
|
|
20991
21213
|
const primaryPlatform = Object.values(appConfigs).find(
|
|
20992
21214
|
(c) => c.backend !== "none"
|
|
20993
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);
|
|
20994
21223
|
const rootPackageJson = generatePackageJson(
|
|
20995
21224
|
"consumer-root",
|
|
20996
21225
|
executionMode,
|
|
@@ -21025,8 +21254,12 @@ async function main9(options) {
|
|
|
21025
21254
|
// Determined by agent in WAI-WAY Phase 0
|
|
21026
21255
|
needsOAuth: false,
|
|
21027
21256
|
// Determined by agent in WAI-WAY Phase 0
|
|
21028
|
-
needsBilling: false
|
|
21257
|
+
needsBilling: false,
|
|
21029
21258
|
// Determined by agent in WAI-WAY Phase 0
|
|
21259
|
+
// .dndev.secrets conditional sections
|
|
21260
|
+
vercel: hasVercel,
|
|
21261
|
+
supabase: hasSupabase,
|
|
21262
|
+
stripe: hasBilling
|
|
21030
21263
|
};
|
|
21031
21264
|
const firebaseRootFiles = /* @__PURE__ */ new Set([
|
|
21032
21265
|
"firebase.json.example",
|
|
@@ -21055,6 +21288,13 @@ async function main9(options) {
|
|
|
21055
21288
|
await replacePlaceholders(destPath, rootReplacements);
|
|
21056
21289
|
}
|
|
21057
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
|
+
}
|
|
21058
21298
|
if (setupGithubActions) {
|
|
21059
21299
|
const ciTemplateDir = joinPath(templatesRoot, "github");
|
|
21060
21300
|
await copyTemplateFiles(
|
|
@@ -21155,6 +21395,61 @@ async function main9(options) {
|
|
|
21155
21395
|
sDemo.stop("Demo app copied");
|
|
21156
21396
|
}
|
|
21157
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
|
+
}
|
|
21158
21453
|
log.info("Creating apps...");
|
|
21159
21454
|
for (const appName of appNames) {
|
|
21160
21455
|
const appConfig = appConfigs[appName];
|
|
@@ -21200,7 +21495,7 @@ init_utils();
|
|
|
21200
21495
|
init_cli_output();
|
|
21201
21496
|
init_errors();
|
|
21202
21497
|
init_pathResolver();
|
|
21203
|
-
import { spawnSync as
|
|
21498
|
+
import { spawnSync as spawnSync9 } from "node:child_process";
|
|
21204
21499
|
import { EOL as EOL2 } from "node:os";
|
|
21205
21500
|
async function main10(options = {}) {
|
|
21206
21501
|
const dryRun = options.dryRun ?? false;
|
|
@@ -21680,7 +21975,7 @@ async function runPrettier(rootDir, dryRun, verbose) {
|
|
|
21680
21975
|
log.info("DRY RUN: Would run Prettier");
|
|
21681
21976
|
return stats;
|
|
21682
21977
|
}
|
|
21683
|
-
const result =
|
|
21978
|
+
const result = spawnSync9("bunx", prettierArgs, {
|
|
21684
21979
|
cwd: rootDir,
|
|
21685
21980
|
stdio: "pipe",
|
|
21686
21981
|
shell: true,
|
|
@@ -21851,8 +22146,8 @@ async function findCacheItems(targetDir, verbose) {
|
|
|
21851
22146
|
for (const nestedPkg of nestedPackages) {
|
|
21852
22147
|
const nestedPkgPath = joinPath(pkgPath, nestedPkg);
|
|
21853
22148
|
try {
|
|
21854
|
-
const
|
|
21855
|
-
if (
|
|
22149
|
+
const stat2 = statSync2(nestedPkgPath);
|
|
22150
|
+
if (stat2?.isDirectory()) {
|
|
21856
22151
|
check(joinPath(nestedPkgPath, ".vite"));
|
|
21857
22152
|
check(joinPath(nestedPkgPath, "dist"));
|
|
21858
22153
|
check(joinPath(nestedPkgPath, "node_modules", ".vite"));
|