create-krispya 0.13.0 → 0.15.0
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/dist/cli.cjs +476 -188
- package/dist/cli.d.cts +2 -2
- package/dist/cli.d.mts +2 -2
- package/dist/cli.d.ts +2 -2
- package/dist/cli.mjs +483 -194
- package/dist/index.cjs +39 -1
- package/dist/index.d.cts +127 -7
- package/dist/index.d.mts +127 -7
- package/dist/index.d.ts +127 -7
- package/dist/index.mjs +2 -1
- package/dist/shared/{create-krispya.CcQTepKu.d.cts → create-krispya.8Jt7v_KA.d.cts} +1 -1
- package/dist/shared/{create-krispya.CcQTepKu.d.mts → create-krispya.8Jt7v_KA.d.mts} +1 -1
- package/dist/shared/{create-krispya.CcQTepKu.d.ts → create-krispya.8Jt7v_KA.d.ts} +1 -1
- package/dist/shared/{create-krispya.B2px1YOh.mjs → create-krispya.BYCdQkPo.mjs} +634 -380
- package/dist/shared/{create-krispya.CiGwBdQ3.cjs → create-krispya.Wf4wp5cQ.cjs} +664 -379
- package/package.json +9 -10
package/dist/cli.cjs
CHANGED
|
@@ -4,17 +4,18 @@
|
|
|
4
4
|
const p = require('@clack/prompts');
|
|
5
5
|
const color = require('chalk');
|
|
6
6
|
const commander = require('commander');
|
|
7
|
-
const promises
|
|
7
|
+
const promises = require('node:fs/promises');
|
|
8
8
|
const node_module = require('node:module');
|
|
9
9
|
const node_path = require('node:path');
|
|
10
10
|
const node_process = require('node:process');
|
|
11
11
|
const undici = require('undici');
|
|
12
|
-
const workspace = require('./shared/create-krispya.
|
|
13
|
-
const
|
|
14
|
-
const promises = require('fs/promises');
|
|
12
|
+
const workspace = require('./shared/create-krispya.Wf4wp5cQ.cjs');
|
|
13
|
+
const promises$1 = require('fs/promises');
|
|
15
14
|
const fs = require('fs');
|
|
16
15
|
const path = require('path');
|
|
17
16
|
const node_fs = require('node:fs');
|
|
17
|
+
const node_child_process = require('node:child_process');
|
|
18
|
+
require('conf');
|
|
18
19
|
|
|
19
20
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
20
21
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
@@ -33,7 +34,6 @@ function _interopNamespaceCompat(e) {
|
|
|
33
34
|
|
|
34
35
|
const p__namespace = /*#__PURE__*/_interopNamespaceCompat(p);
|
|
35
36
|
const color__default = /*#__PURE__*/_interopDefaultCompat(color);
|
|
36
|
-
const Conf__default = /*#__PURE__*/_interopDefaultCompat(Conf);
|
|
37
37
|
|
|
38
38
|
function formatConfigSummary(options, inherited) {
|
|
39
39
|
const lines = [];
|
|
@@ -134,8 +134,9 @@ function formatMonorepoConfigSummary(options) {
|
|
|
134
134
|
lines.push(
|
|
135
135
|
formatRow("Engine", `${workspace.getEngineName(options.engine)}@${options.engine.version ?? "latest"}`)
|
|
136
136
|
);
|
|
137
|
-
|
|
138
|
-
|
|
137
|
+
const packageManagerName = workspace.getPackageManagerName(options.packageManager);
|
|
138
|
+
lines.push(formatRow("Package manager", packageManagerName));
|
|
139
|
+
if (packageManagerName === "pnpm") {
|
|
139
140
|
const versionManaged = options.pnpmManageVersions ? "yes" : "no";
|
|
140
141
|
lines.push(formatRow("\u21B3 Version managed", versionManaged, ""));
|
|
141
142
|
}
|
|
@@ -145,22 +146,6 @@ function formatMonorepoConfigSummary(options) {
|
|
|
145
146
|
return lines.join("\n");
|
|
146
147
|
}
|
|
147
148
|
|
|
148
|
-
const config = new Conf__default({
|
|
149
|
-
projectName: "create-krispya"
|
|
150
|
-
});
|
|
151
|
-
function getAiPlatforms() {
|
|
152
|
-
return config.get("aiPlatforms");
|
|
153
|
-
}
|
|
154
|
-
function getConfigStrategy() {
|
|
155
|
-
return config.get("configStrategy") ?? "stealth";
|
|
156
|
-
}
|
|
157
|
-
function clearConfig() {
|
|
158
|
-
config.clear();
|
|
159
|
-
}
|
|
160
|
-
function getConfigPath() {
|
|
161
|
-
return config.path;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
149
|
const R3F_INTEGRATION_OPTIONS = [
|
|
165
150
|
{ value: "drei", label: "Drei" },
|
|
166
151
|
{ value: "handle", label: "Handle" },
|
|
@@ -224,7 +209,7 @@ function getDefaultOptions(template, name, projectType = "app", libraryBundler,
|
|
|
224
209
|
formatter: inheritedSettings?.formatter ?? "prettier",
|
|
225
210
|
// Libraries get vitest by default, apps don't
|
|
226
211
|
testing: projectType === "library" ? "vitest" : "none",
|
|
227
|
-
configStrategy: getConfigStrategy(),
|
|
212
|
+
configStrategy: workspace.getConfigStrategy(),
|
|
228
213
|
ide: "vscode"
|
|
229
214
|
};
|
|
230
215
|
return {
|
|
@@ -274,7 +259,7 @@ async function promptForCustomization(template, name, projectType, features, inh
|
|
|
274
259
|
libraryBundler = bundler;
|
|
275
260
|
}
|
|
276
261
|
let engine = inheritedSettings?.engine ?? presets?.engine ?? { name: "node", version: "latest" };
|
|
277
|
-
let finalPackageManager = inheritedSettings?.packageManager?.name ?? presets?.packageManager ?? "pnpm";
|
|
262
|
+
let finalPackageManager = inheritedSettings?.packageManager?.name ?? presets?.packageManager?.name ?? "pnpm";
|
|
278
263
|
let pnpmManageVersions = inheritedSettings?.pnpmManageVersions ?? presets?.pnpmManageVersions ?? true;
|
|
279
264
|
if (!inheritedSettings?.engine?.version) {
|
|
280
265
|
const nodeVersionInput = await p__namespace.text({
|
|
@@ -282,7 +267,7 @@ async function promptForCustomization(template, name, projectType, features, inh
|
|
|
282
267
|
placeholder: presets?.engine?.version ?? "latest",
|
|
283
268
|
defaultValue: presets?.engine?.version ?? "latest",
|
|
284
269
|
validate: (value) => {
|
|
285
|
-
if (!value
|
|
270
|
+
if (!value?.length) return "Required";
|
|
286
271
|
if (value !== "latest" && !/^\d+(\.\d+(\.\d+)?)?$/.test(value)) {
|
|
287
272
|
return 'Must be "latest" or a valid semver (e.g., "22" or "22.13.0")';
|
|
288
273
|
}
|
|
@@ -302,7 +287,7 @@ async function promptForCustomization(template, name, projectType, features, inh
|
|
|
302
287
|
{ value: "npm", label: "npm" },
|
|
303
288
|
{ value: "yarn", label: "yarn" }
|
|
304
289
|
],
|
|
305
|
-
initialValue: presets?.packageManager ?? "pnpm"
|
|
290
|
+
initialValue: presets?.packageManager?.name ?? "pnpm"
|
|
306
291
|
});
|
|
307
292
|
if (p__namespace.isCancel(packageManager)) {
|
|
308
293
|
p__namespace.cancel("Operation cancelled.");
|
|
@@ -385,7 +370,7 @@ async function promptForCustomization(template, name, projectType, features, inh
|
|
|
385
370
|
{ value: "stealth", label: "stealth", hint: "configs in .config/" },
|
|
386
371
|
{ value: "root", label: "root", hint: "configs at project root" }
|
|
387
372
|
],
|
|
388
|
-
initialValue: getConfigStrategy()
|
|
373
|
+
initialValue: workspace.getConfigStrategy()
|
|
389
374
|
});
|
|
390
375
|
if (p__namespace.isCancel(configStrategyChoice)) {
|
|
391
376
|
p__namespace.cancel("Operation cancelled.");
|
|
@@ -411,7 +396,7 @@ async function promptForCustomization(template, name, projectType, features, inh
|
|
|
411
396
|
projectType,
|
|
412
397
|
libraryBundler: projectType === "library" ? libraryBundler : void 0,
|
|
413
398
|
engine,
|
|
414
|
-
packageManager: { name: finalPackageManager },
|
|
399
|
+
packageManager: presets?.packageManager?.name === finalPackageManager ? presets.packageManager : { name: finalPackageManager },
|
|
415
400
|
pnpmManageVersions,
|
|
416
401
|
linter,
|
|
417
402
|
formatter,
|
|
@@ -458,7 +443,7 @@ async function promptForMonorepoCustomization(name, presets) {
|
|
|
458
443
|
placeholder: presets?.engine?.version ?? "latest",
|
|
459
444
|
defaultValue: presets?.engine?.version ?? "latest",
|
|
460
445
|
validate: (value) => {
|
|
461
|
-
if (!value
|
|
446
|
+
if (!value?.length) return "Required";
|
|
462
447
|
if (value !== "latest" && !/^\d+(\.\d+(\.\d+)?)?$/.test(value)) {
|
|
463
448
|
return 'Must be "latest" or a valid semver (e.g., "22" or "22.13.0")';
|
|
464
449
|
}
|
|
@@ -539,7 +524,7 @@ async function promptForMonorepo(workspaceName, presets) {
|
|
|
539
524
|
formatMonorepoConfigSummary({
|
|
540
525
|
name: defaultOptions.name,
|
|
541
526
|
engine: defaultOptions.engine ?? { name: "node", version: "latest" },
|
|
542
|
-
packageManager:
|
|
527
|
+
packageManager: defaultOptions.packageManager ?? { name: "pnpm" },
|
|
543
528
|
pnpmManageVersions: defaultOptions.pnpmManageVersions,
|
|
544
529
|
linter: defaultOptions.linter ?? "oxlint",
|
|
545
530
|
formatter: defaultOptions.formatter ?? "prettier",
|
|
@@ -560,7 +545,7 @@ async function promptForOptions(name, presets) {
|
|
|
560
545
|
placeholder: workspace.generateRandomName(),
|
|
561
546
|
defaultValue: workspace.generateRandomName(),
|
|
562
547
|
validate: (value) => {
|
|
563
|
-
if (!value
|
|
548
|
+
if (!value?.length) return "Project name is required";
|
|
564
549
|
}
|
|
565
550
|
});
|
|
566
551
|
if (p__namespace.isCancel(nameResult)) {
|
|
@@ -592,7 +577,7 @@ function presetsToInheritedSettings(presets) {
|
|
|
592
577
|
return {
|
|
593
578
|
linter: presets.linter,
|
|
594
579
|
formatter: presets.formatter,
|
|
595
|
-
packageManager: presets.packageManager
|
|
580
|
+
packageManager: presets.packageManager,
|
|
596
581
|
engine: presets.engine,
|
|
597
582
|
pnpmManageVersions: presets.pnpmManageVersions
|
|
598
583
|
};
|
|
@@ -644,7 +629,7 @@ async function promptForPackageOptions(projectName, projectType, inheritedSettin
|
|
|
644
629
|
}
|
|
645
630
|
|
|
646
631
|
async function promptForAiAgentPlatforms(isNonInteractive) {
|
|
647
|
-
const savedPlatforms = getAiPlatforms();
|
|
632
|
+
const savedPlatforms = workspace.getAiPlatforms();
|
|
648
633
|
if (isNonInteractive) {
|
|
649
634
|
return savedPlatforms ?? workspace.ALL_AI_PLATFORMS;
|
|
650
635
|
}
|
|
@@ -677,54 +662,9 @@ async function promptForAiAgentPlatforms(isNonInteractive) {
|
|
|
677
662
|
return selected;
|
|
678
663
|
}
|
|
679
664
|
|
|
680
|
-
async function checkAnyExists(paths) {
|
|
681
|
-
for (const path of paths) {
|
|
682
|
-
try {
|
|
683
|
-
await promises.access(path, promises.constants.F_OK);
|
|
684
|
-
return true;
|
|
685
|
-
} catch {
|
|
686
|
-
}
|
|
687
|
-
}
|
|
688
|
-
return false;
|
|
689
|
-
}
|
|
690
|
-
async function validateWorkspace(monorepoRoot) {
|
|
691
|
-
const errors = [];
|
|
692
|
-
const tsConfigPath = path.join(monorepoRoot, ".config/typescript/package.json");
|
|
693
|
-
try {
|
|
694
|
-
await promises.access(tsConfigPath, promises.constants.F_OK);
|
|
695
|
-
} catch {
|
|
696
|
-
errors.push("Missing .config/typescript package");
|
|
697
|
-
}
|
|
698
|
-
const linterPaths = [
|
|
699
|
-
path.join(monorepoRoot, ".config/oxlint/package.json"),
|
|
700
|
-
path.join(monorepoRoot, ".config/eslint/package.json"),
|
|
701
|
-
path.join(monorepoRoot, "eslint.config.js"),
|
|
702
|
-
path.join(monorepoRoot, "biome.json")
|
|
703
|
-
];
|
|
704
|
-
const hasLinter = await checkAnyExists(linterPaths);
|
|
705
|
-
if (!hasLinter) {
|
|
706
|
-
errors.push(
|
|
707
|
-
"Missing linter config (.config/oxlint, .config/eslint, eslint.config.js, or biome.json)"
|
|
708
|
-
);
|
|
709
|
-
}
|
|
710
|
-
const formatterPaths = [
|
|
711
|
-
path.join(monorepoRoot, ".config/oxfmt/package.json"),
|
|
712
|
-
path.join(monorepoRoot, ".config/prettier/package.json"),
|
|
713
|
-
path.join(monorepoRoot, ".prettierrc.json"),
|
|
714
|
-
path.join(monorepoRoot, "biome.json")
|
|
715
|
-
];
|
|
716
|
-
const hasFormatter = await checkAnyExists(formatterPaths);
|
|
717
|
-
if (!hasFormatter) {
|
|
718
|
-
errors.push(
|
|
719
|
-
"Missing formatter config (.config/oxfmt, .config/prettier, .prettierrc.json, or biome.json)"
|
|
720
|
-
);
|
|
721
|
-
}
|
|
722
|
-
return { valid: errors.length === 0, errors };
|
|
723
|
-
}
|
|
724
|
-
|
|
725
665
|
async function fileExists$1(path) {
|
|
726
666
|
try {
|
|
727
|
-
await promises
|
|
667
|
+
await promises.access(path, node_fs.constants.F_OK);
|
|
728
668
|
return true;
|
|
729
669
|
} catch {
|
|
730
670
|
return false;
|
|
@@ -740,8 +680,8 @@ async function detectMonorepoRoot() {
|
|
|
740
680
|
while (currentDir !== root) {
|
|
741
681
|
const workspaceFile = node_path.join(currentDir, "pnpm-workspace.yaml");
|
|
742
682
|
try {
|
|
743
|
-
await promises
|
|
744
|
-
const content = await promises
|
|
683
|
+
await promises.access(workspaceFile, node_fs.constants.F_OK);
|
|
684
|
+
const content = await promises.readFile(workspaceFile, "utf-8");
|
|
745
685
|
if (content.includes("packages:")) {
|
|
746
686
|
return currentDir;
|
|
747
687
|
}
|
|
@@ -765,7 +705,7 @@ async function detectPackageRoot() {
|
|
|
765
705
|
async function parseWorkspaceDirectories(monorepoRoot) {
|
|
766
706
|
try {
|
|
767
707
|
const workspaceFile = node_path.join(monorepoRoot, "pnpm-workspace.yaml");
|
|
768
|
-
const content = await promises
|
|
708
|
+
const content = await promises.readFile(workspaceFile, "utf-8");
|
|
769
709
|
return workspace.parseWorkspaceYamlContent(content);
|
|
770
710
|
} catch {
|
|
771
711
|
return [];
|
|
@@ -775,14 +715,14 @@ async function detectWorkspaceSettings(monorepoRoot) {
|
|
|
775
715
|
try {
|
|
776
716
|
const tooling = await workspace.detectTooling(monorepoRoot);
|
|
777
717
|
const pkgPath = node_path.join(monorepoRoot, "package.json");
|
|
778
|
-
const content = await promises
|
|
718
|
+
const content = await promises.readFile(pkgPath, "utf-8");
|
|
779
719
|
const pkgJson = JSON.parse(content);
|
|
780
|
-
const packageManager = workspace.
|
|
720
|
+
const packageManager = workspace.parsePackageManagerSpec(pkgJson.packageManager);
|
|
781
721
|
const engine = workspace.parseEngine(pkgJson.engines);
|
|
782
722
|
let pnpmManageVersions;
|
|
783
723
|
try {
|
|
784
724
|
const workspaceFile = node_path.join(monorepoRoot, "pnpm-workspace.yaml");
|
|
785
|
-
const workspaceContent = await promises
|
|
725
|
+
const workspaceContent = await promises.readFile(workspaceFile, "utf-8");
|
|
786
726
|
pnpmManageVersions = workspaceContent.includes("manage-package-manager-versions: true");
|
|
787
727
|
} catch {
|
|
788
728
|
}
|
|
@@ -820,7 +760,7 @@ async function detectExistingConfigs(monorepoRoot) {
|
|
|
820
760
|
async function getMonorepoScope(monorepoRoot) {
|
|
821
761
|
try {
|
|
822
762
|
const pkgPath = node_path.join(monorepoRoot, "package.json");
|
|
823
|
-
const content = await promises
|
|
763
|
+
const content = await promises.readFile(pkgPath, "utf-8");
|
|
824
764
|
const pkgJson = JSON.parse(content);
|
|
825
765
|
if (pkgJson.name) {
|
|
826
766
|
return pkgJson.name.replace(/^@/, "").replace(/\/.*$/, "");
|
|
@@ -832,12 +772,12 @@ async function getMonorepoScope(monorepoRoot) {
|
|
|
832
772
|
async function getWorkspacePackages(monorepoRoot) {
|
|
833
773
|
const packagesDir = node_path.join(monorepoRoot, "packages");
|
|
834
774
|
try {
|
|
835
|
-
const entries = await promises
|
|
775
|
+
const entries = await promises.readdir(packagesDir, { withFileTypes: true });
|
|
836
776
|
const names = [];
|
|
837
777
|
for (const entry of entries) {
|
|
838
778
|
if (!entry.isDirectory()) continue;
|
|
839
779
|
try {
|
|
840
|
-
const content = await promises
|
|
780
|
+
const content = await promises.readFile(node_path.join(packagesDir, entry.name, "package.json"), "utf-8");
|
|
841
781
|
const pkg = JSON.parse(content);
|
|
842
782
|
if (pkg.name) names.push(pkg.name);
|
|
843
783
|
} catch {
|
|
@@ -852,13 +792,13 @@ async function ensureConfigInWorkspace(monorepoRoot) {
|
|
|
852
792
|
const workspacePath = node_path.join(monorepoRoot, "pnpm-workspace.yaml");
|
|
853
793
|
let content;
|
|
854
794
|
try {
|
|
855
|
-
content = await promises
|
|
795
|
+
content = await promises.readFile(workspacePath, "utf-8");
|
|
856
796
|
} catch {
|
|
857
797
|
content = `packages:
|
|
858
798
|
- '.config/*'
|
|
859
799
|
- 'packages/*'
|
|
860
800
|
`;
|
|
861
|
-
await promises
|
|
801
|
+
await promises.writeFile(workspacePath, content);
|
|
862
802
|
return;
|
|
863
803
|
}
|
|
864
804
|
if (content.includes(".config/*")) {
|
|
@@ -874,7 +814,7 @@ ${content}`;
|
|
|
874
814
|
lines.splice(packagesIndex + 1, 0, " - '.config/*'");
|
|
875
815
|
content = lines.join("\n");
|
|
876
816
|
}
|
|
877
|
-
await promises
|
|
817
|
+
await promises.writeFile(workspacePath, content);
|
|
878
818
|
}
|
|
879
819
|
|
|
880
820
|
async function handleCheckCommand() {
|
|
@@ -883,7 +823,7 @@ async function handleCheckCommand() {
|
|
|
883
823
|
console.log(color__default.red("\u2717") + " Not a monorepo workspace");
|
|
884
824
|
process.exit(1);
|
|
885
825
|
}
|
|
886
|
-
const { valid, errors } = await validateWorkspace(monorepoRoot);
|
|
826
|
+
const { valid, errors } = await workspace.validateWorkspace(monorepoRoot);
|
|
887
827
|
if (valid) {
|
|
888
828
|
console.log(color__default.green("\u2713") + " Valid monorepo workspace");
|
|
889
829
|
console.log(color__default.dim(` ${monorepoRoot}`));
|
|
@@ -902,7 +842,7 @@ async function migrateEslintConfig(monorepoRoot, files) {
|
|
|
902
842
|
const existingConfigPath = node_path.join(monorepoRoot, "eslint.config.js");
|
|
903
843
|
let existingContent;
|
|
904
844
|
try {
|
|
905
|
-
existingContent = await promises
|
|
845
|
+
existingContent = await promises.readFile(existingConfigPath, "utf-8");
|
|
906
846
|
} catch {
|
|
907
847
|
workspace.renderEslintConfigPackage(files);
|
|
908
848
|
return;
|
|
@@ -981,7 +921,7 @@ async function migratePrettierConfig(monorepoRoot, files) {
|
|
|
981
921
|
const existingConfigPath = node_path.join(monorepoRoot, ".prettierrc.json");
|
|
982
922
|
let existingContent;
|
|
983
923
|
try {
|
|
984
|
-
existingContent = await promises
|
|
924
|
+
existingContent = await promises.readFile(existingConfigPath, "utf-8");
|
|
985
925
|
} catch {
|
|
986
926
|
workspace.renderPrettierConfigPackage(files);
|
|
987
927
|
return;
|
|
@@ -1040,7 +980,7 @@ async function handleFixCommand(options) {
|
|
|
1040
980
|
console.log(color__default.dim(" Run this command from within a monorepo"));
|
|
1041
981
|
process.exit(1);
|
|
1042
982
|
}
|
|
1043
|
-
const { valid, errors } = await validateWorkspace(monorepoRoot);
|
|
983
|
+
const { valid, errors } = await workspace.validateWorkspace(monorepoRoot);
|
|
1044
984
|
if (valid) {
|
|
1045
985
|
console.log(color__default.green("\u2713") + " Workspace is already valid");
|
|
1046
986
|
console.log(color__default.dim(` ${monorepoRoot}`));
|
|
@@ -1174,19 +1114,19 @@ async function handleFixCommand(options) {
|
|
|
1174
1114
|
}
|
|
1175
1115
|
for (const [filePath, file] of Object.entries(files)) {
|
|
1176
1116
|
const fullPath = node_path.join(monorepoRoot, filePath);
|
|
1177
|
-
await promises
|
|
1178
|
-
await promises
|
|
1117
|
+
await promises.mkdir(node_path.dirname(fullPath), { recursive: true });
|
|
1118
|
+
await promises.writeFile(fullPath, file.content);
|
|
1179
1119
|
}
|
|
1180
1120
|
await ensureConfigInWorkspace(monorepoRoot);
|
|
1181
1121
|
if (existingConfigs.eslintConfigPath && linter === "eslint") {
|
|
1182
1122
|
try {
|
|
1183
|
-
await promises
|
|
1123
|
+
await promises.unlink(existingConfigs.eslintConfigPath);
|
|
1184
1124
|
} catch {
|
|
1185
1125
|
}
|
|
1186
1126
|
}
|
|
1187
1127
|
if (existingConfigs.prettierConfigPath && formatter === "prettier") {
|
|
1188
1128
|
try {
|
|
1189
|
-
await promises
|
|
1129
|
+
await promises.unlink(existingConfigs.prettierConfigPath);
|
|
1190
1130
|
} catch {
|
|
1191
1131
|
}
|
|
1192
1132
|
}
|
|
@@ -1215,8 +1155,8 @@ async function handleFixCommand(options) {
|
|
|
1215
1155
|
workspace.renderVscodeFiles(vscodeFiles, linter, formatter);
|
|
1216
1156
|
for (const [filePath, file] of Object.entries(vscodeFiles)) {
|
|
1217
1157
|
const fullPath = node_path.join(monorepoRoot, filePath);
|
|
1218
|
-
await promises
|
|
1219
|
-
await promises
|
|
1158
|
+
await promises.mkdir(node_path.dirname(fullPath), { recursive: true });
|
|
1159
|
+
await promises.writeFile(fullPath, file.content);
|
|
1220
1160
|
}
|
|
1221
1161
|
console.log(color__default.dim(" Generated .vscode/settings.json"));
|
|
1222
1162
|
console.log(color__default.dim(" Generated .vscode/extensions.json"));
|
|
@@ -1239,8 +1179,8 @@ async function handleFixCommand(options) {
|
|
|
1239
1179
|
});
|
|
1240
1180
|
for (const [filePath, file] of Object.entries(aiFilesOutput)) {
|
|
1241
1181
|
const fullPath = node_path.join(monorepoRoot, filePath);
|
|
1242
|
-
await promises
|
|
1243
|
-
await promises
|
|
1182
|
+
await promises.mkdir(node_path.dirname(fullPath), { recursive: true });
|
|
1183
|
+
await promises.writeFile(fullPath, file.content);
|
|
1244
1184
|
console.log(color__default.dim(` Generated ${filePath}`));
|
|
1245
1185
|
}
|
|
1246
1186
|
}
|
|
@@ -1282,18 +1222,22 @@ function renderExpectedViteConfig(template) {
|
|
|
1282
1222
|
async function detectCurrentConfig(root, isMonorepo = true) {
|
|
1283
1223
|
let name = root.split(/[/\\]/).pop() ?? "workspace";
|
|
1284
1224
|
let packageManager = "pnpm";
|
|
1225
|
+
let packageManagerSpec = { name: "pnpm" };
|
|
1226
|
+
let engine;
|
|
1285
1227
|
let hasTypecheck = false;
|
|
1286
1228
|
let viteTemplate;
|
|
1287
1229
|
try {
|
|
1288
1230
|
const pkgPath = path.join(root, "package.json");
|
|
1289
|
-
const content = await promises.readFile(pkgPath, "utf-8");
|
|
1231
|
+
const content = await promises$1.readFile(pkgPath, "utf-8");
|
|
1290
1232
|
const pkgJson = JSON.parse(content);
|
|
1291
1233
|
if (pkgJson.name) {
|
|
1292
1234
|
name = pkgJson.name.replace(/^@/, "").replace(/\/.*$/, "");
|
|
1293
1235
|
}
|
|
1294
1236
|
if (pkgJson.packageManager) {
|
|
1295
|
-
|
|
1237
|
+
packageManagerSpec = workspace.parsePackageManagerSpec(pkgJson.packageManager) ?? packageManagerSpec;
|
|
1238
|
+
packageManager = packageManagerSpec.name;
|
|
1296
1239
|
}
|
|
1240
|
+
engine = workspace.parseEngine(pkgJson.engines);
|
|
1297
1241
|
hasTypecheck = pkgJson.scripts?.typecheck != null;
|
|
1298
1242
|
viteTemplate = detectViteTemplate(pkgJson);
|
|
1299
1243
|
} catch {
|
|
@@ -1305,6 +1249,8 @@ async function detectCurrentConfig(root, isMonorepo = true) {
|
|
|
1305
1249
|
linter: tooling.linter ?? "oxlint",
|
|
1306
1250
|
formatter: tooling.formatter ?? "prettier",
|
|
1307
1251
|
packageManager,
|
|
1252
|
+
packageManagerSpec,
|
|
1253
|
+
engine,
|
|
1308
1254
|
isMonorepo,
|
|
1309
1255
|
configStrategy,
|
|
1310
1256
|
hasTypecheck,
|
|
@@ -1411,7 +1357,7 @@ async function planExpectedFiles(config) {
|
|
|
1411
1357
|
}
|
|
1412
1358
|
async function fileExists(path) {
|
|
1413
1359
|
try {
|
|
1414
|
-
await promises.access(path, fs.constants.F_OK);
|
|
1360
|
+
await promises$1.access(path, fs.constants.F_OK);
|
|
1415
1361
|
return true;
|
|
1416
1362
|
} catch {
|
|
1417
1363
|
return false;
|
|
@@ -1553,7 +1499,7 @@ async function compareWithDisk(expected, root) {
|
|
|
1553
1499
|
const fullPath = path.join(root, filePath);
|
|
1554
1500
|
const newContent = file.content;
|
|
1555
1501
|
if (await fileExists(fullPath)) {
|
|
1556
|
-
const currentContent = await promises.readFile(fullPath, "utf-8");
|
|
1502
|
+
const currentContent = await promises$1.readFile(fullPath, "utf-8");
|
|
1557
1503
|
if (fileContentsEqual(filePath, currentContent, newContent)) {
|
|
1558
1504
|
changes.push({
|
|
1559
1505
|
path: filePath,
|
|
@@ -1631,7 +1577,7 @@ function detectLibraryPackage(pkg) {
|
|
|
1631
1577
|
return pkg.exports != null || pkg.main?.includes("dist") === true || pkg.module?.includes("dist") === true || Array.isArray(pkg.files) && pkg.files.includes("dist");
|
|
1632
1578
|
}
|
|
1633
1579
|
function getPackageManagerForScripts(config, pkg) {
|
|
1634
|
-
const packageManager = pkg.packageManager?.
|
|
1580
|
+
const packageManager = workspace.parsePackageManagerSpec(pkg.packageManager)?.name ?? config.packageManager;
|
|
1635
1581
|
return isPackageManagerName(packageManager) ? packageManager : "pnpm";
|
|
1636
1582
|
}
|
|
1637
1583
|
function getSinglePackageToolScripts(config) {
|
|
@@ -1661,6 +1607,35 @@ function scriptsEqual(left, right) {
|
|
|
1661
1607
|
if (leftEntries.length !== Object.keys(right).length) return false;
|
|
1662
1608
|
return leftEntries.every(([key, value]) => right[key] === value);
|
|
1663
1609
|
}
|
|
1610
|
+
function packageManagerFieldsEqual(pkg, packageManagerSpec, targetNodeVersion) {
|
|
1611
|
+
if (packageManagerSpec == null || packageManagerSpec.version == null) {
|
|
1612
|
+
return targetNodeVersion == null || pkg.engines?.node === `>=${targetNodeVersion}`;
|
|
1613
|
+
}
|
|
1614
|
+
const majorVersion = workspace.getSemverMajorString(packageManagerSpec.version);
|
|
1615
|
+
return pkg.packageManager === workspace.formatPackageManager(packageManagerSpec) && pkg.engines?.[packageManagerSpec.name] === `>=${majorVersion}.0.0` && (targetNodeVersion == null || pkg.engines?.node === `>=${targetNodeVersion}`);
|
|
1616
|
+
}
|
|
1617
|
+
function applyPackageManagerFields(pkg, packageManagerSpec, targetNodeVersion) {
|
|
1618
|
+
if (packageManagerSpec == null || packageManagerSpec.version == null) {
|
|
1619
|
+
if (targetNodeVersion == null) return pkg;
|
|
1620
|
+
return {
|
|
1621
|
+
...pkg,
|
|
1622
|
+
engines: {
|
|
1623
|
+
...pkg.engines,
|
|
1624
|
+
node: `>=${targetNodeVersion}`
|
|
1625
|
+
}
|
|
1626
|
+
};
|
|
1627
|
+
}
|
|
1628
|
+
const majorVersion = workspace.getSemverMajorString(packageManagerSpec.version);
|
|
1629
|
+
return {
|
|
1630
|
+
...pkg,
|
|
1631
|
+
packageManager: workspace.formatPackageManager(packageManagerSpec),
|
|
1632
|
+
engines: {
|
|
1633
|
+
...pkg.engines,
|
|
1634
|
+
[packageManagerSpec.name]: `>=${majorVersion}.0.0`,
|
|
1635
|
+
...targetNodeVersion == null ? {} : { node: `>=${targetNodeVersion}` }
|
|
1636
|
+
}
|
|
1637
|
+
};
|
|
1638
|
+
}
|
|
1664
1639
|
async function getExpectedPackageScripts(root, config, pkg) {
|
|
1665
1640
|
if (config.isMonorepo) {
|
|
1666
1641
|
return workspace.packageJsonScripts.monorepoRoot(config.linter, config.formatter);
|
|
@@ -1702,7 +1677,7 @@ async function getPackageJsonScriptUpdates(root, config) {
|
|
|
1702
1677
|
const packageJsonPath = path.join(root, "package.json");
|
|
1703
1678
|
let currentContent;
|
|
1704
1679
|
try {
|
|
1705
|
-
currentContent = await promises.readFile(packageJsonPath, "utf-8");
|
|
1680
|
+
currentContent = await promises$1.readFile(packageJsonPath, "utf-8");
|
|
1706
1681
|
} catch {
|
|
1707
1682
|
return [];
|
|
1708
1683
|
}
|
|
@@ -1712,7 +1687,9 @@ async function getPackageJsonScriptUpdates(root, config) {
|
|
|
1712
1687
|
const nextScripts = workspace.mergePackageJsonScripts(currentScripts, expectedScripts);
|
|
1713
1688
|
const currentDevDependencies = pkg.devDependencies ?? {};
|
|
1714
1689
|
const nextDevDependencies = await getExpectedPackageDevDependencies(root, config, pkg);
|
|
1715
|
-
|
|
1690
|
+
const targetPackageManagerSpec = config.targetPackageManagerSpec;
|
|
1691
|
+
const targetNodeVersion = config.targetNodeVersion;
|
|
1692
|
+
if (scriptsEqual(currentScripts, nextScripts) && scriptsEqual(currentDevDependencies, nextDevDependencies) && packageManagerFieldsEqual(pkg, targetPackageManagerSpec, targetNodeVersion)) {
|
|
1716
1693
|
return [
|
|
1717
1694
|
{
|
|
1718
1695
|
path: "package.json",
|
|
@@ -1722,10 +1699,14 @@ async function getPackageJsonScriptUpdates(root, config) {
|
|
|
1722
1699
|
}
|
|
1723
1700
|
];
|
|
1724
1701
|
}
|
|
1725
|
-
const nextPackageJson =
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1702
|
+
const nextPackageJson = applyPackageManagerFields(
|
|
1703
|
+
{
|
|
1704
|
+
...pkg,
|
|
1705
|
+
scripts: nextScripts
|
|
1706
|
+
},
|
|
1707
|
+
targetPackageManagerSpec,
|
|
1708
|
+
targetNodeVersion
|
|
1709
|
+
);
|
|
1729
1710
|
if (Object.keys(nextDevDependencies).length > 0 || pkg.devDependencies != null) {
|
|
1730
1711
|
nextPackageJson.devDependencies = nextDevDependencies;
|
|
1731
1712
|
}
|
|
@@ -1740,6 +1721,41 @@ async function getPackageJsonScriptUpdates(root, config) {
|
|
|
1740
1721
|
}
|
|
1741
1722
|
];
|
|
1742
1723
|
}
|
|
1724
|
+
async function getPackageManagerConfigUpdates(root, config) {
|
|
1725
|
+
if (config.targetPackageManagerSpec == null && config.targetNodeVersion == null) return [];
|
|
1726
|
+
const packageJsonPath = path.join(root, "package.json");
|
|
1727
|
+
let currentContent;
|
|
1728
|
+
try {
|
|
1729
|
+
currentContent = await promises$1.readFile(packageJsonPath, "utf-8");
|
|
1730
|
+
} catch {
|
|
1731
|
+
return [];
|
|
1732
|
+
}
|
|
1733
|
+
const pkg = JSON.parse(currentContent);
|
|
1734
|
+
if (packageManagerFieldsEqual(pkg, config.targetPackageManagerSpec, config.targetNodeVersion)) {
|
|
1735
|
+
return [
|
|
1736
|
+
{
|
|
1737
|
+
path: "package.json",
|
|
1738
|
+
status: "unchanged",
|
|
1739
|
+
currentContent,
|
|
1740
|
+
newContent: currentContent
|
|
1741
|
+
}
|
|
1742
|
+
];
|
|
1743
|
+
}
|
|
1744
|
+
const nextPackageJson = applyPackageManagerFields(
|
|
1745
|
+
pkg,
|
|
1746
|
+
config.targetPackageManagerSpec,
|
|
1747
|
+
config.targetNodeVersion
|
|
1748
|
+
);
|
|
1749
|
+
return [
|
|
1750
|
+
{
|
|
1751
|
+
path: "package.json",
|
|
1752
|
+
status: "modified",
|
|
1753
|
+
currentContent,
|
|
1754
|
+
newContent: `${JSON.stringify(nextPackageJson, null, 2)}
|
|
1755
|
+
`
|
|
1756
|
+
}
|
|
1757
|
+
];
|
|
1758
|
+
}
|
|
1743
1759
|
function planSinglePackageOxlintConfig(config) {
|
|
1744
1760
|
if (config.linter !== "oxlint" || config.isMonorepo) return void 0;
|
|
1745
1761
|
const isStealth = (config.configStrategy ?? "stealth") === "stealth";
|
|
@@ -1763,7 +1779,7 @@ async function getOxlintConfigReplacementUpdates(root, config) {
|
|
|
1763
1779
|
const fullPath = path.join(root, expected.path);
|
|
1764
1780
|
let currentContent;
|
|
1765
1781
|
try {
|
|
1766
|
-
currentContent = await promises.readFile(fullPath, "utf-8");
|
|
1782
|
+
currentContent = await promises$1.readFile(fullPath, "utf-8");
|
|
1767
1783
|
} catch {
|
|
1768
1784
|
return [expected];
|
|
1769
1785
|
}
|
|
@@ -1785,26 +1801,118 @@ async function getOxlintConfigReplacementUpdates(root, config) {
|
|
|
1785
1801
|
}
|
|
1786
1802
|
];
|
|
1787
1803
|
}
|
|
1788
|
-
|
|
1804
|
+
function extractBuildDependencies(content) {
|
|
1805
|
+
const buildDependencies = {};
|
|
1806
|
+
let section;
|
|
1807
|
+
for (const line of content.split("\n")) {
|
|
1808
|
+
const trimmed = line.trim();
|
|
1809
|
+
if (trimmed === "onlyBuiltDependencies:") {
|
|
1810
|
+
section = "onlyBuiltDependencies";
|
|
1811
|
+
continue;
|
|
1812
|
+
}
|
|
1813
|
+
if (trimmed === "allowBuilds:") {
|
|
1814
|
+
section = "allowBuilds";
|
|
1815
|
+
continue;
|
|
1816
|
+
}
|
|
1817
|
+
if (section != null && trimmed && !line.startsWith(" ") && !line.startsWith(" ")) {
|
|
1818
|
+
section = void 0;
|
|
1819
|
+
}
|
|
1820
|
+
if (section === "onlyBuiltDependencies" && trimmed.startsWith("-")) {
|
|
1821
|
+
const dependency = trimmed.slice(1).trim().replace(/^["']|["']$/g, "");
|
|
1822
|
+
if (dependency.length > 0) {
|
|
1823
|
+
buildDependencies[dependency] = true;
|
|
1824
|
+
}
|
|
1825
|
+
}
|
|
1826
|
+
if (section === "allowBuilds") {
|
|
1827
|
+
const match = trimmed.match(/^([^:]+):\s*(true|false)$/);
|
|
1828
|
+
if (match == null) continue;
|
|
1829
|
+
const dependency = match[1].trim().replace(/^["']|["']$/g, "");
|
|
1830
|
+
if (dependency.length > 0) {
|
|
1831
|
+
buildDependencies[dependency] = match[2] === "true";
|
|
1832
|
+
}
|
|
1833
|
+
}
|
|
1834
|
+
}
|
|
1835
|
+
return buildDependencies;
|
|
1836
|
+
}
|
|
1837
|
+
function withDefaultBuildDependencies(buildDependencies) {
|
|
1838
|
+
return Object.keys(buildDependencies).length > 0 ? buildDependencies : { esbuild: true };
|
|
1839
|
+
}
|
|
1840
|
+
function isPnpmWorkspaceManagedScalarKey(trimmed) {
|
|
1841
|
+
return trimmed.startsWith("manage-package-manager-versions:") || trimmed.startsWith("pmOnFail:");
|
|
1842
|
+
}
|
|
1843
|
+
function isPnpmWorkspaceManagedBlockKey(trimmed) {
|
|
1844
|
+
return trimmed === "onlyBuiltDependencies:" || trimmed === "allowBuilds:";
|
|
1845
|
+
}
|
|
1846
|
+
function isIndentedWorkspaceLine(line) {
|
|
1847
|
+
return line.startsWith(" ") || line.startsWith(" ");
|
|
1848
|
+
}
|
|
1849
|
+
function removePnpmWorkspaceManagedKeys(content) {
|
|
1850
|
+
const sourceLines = content.split("\n");
|
|
1851
|
+
const lines = [];
|
|
1852
|
+
let insertionIndex = 0;
|
|
1853
|
+
let foundManagedKey = false;
|
|
1854
|
+
for (let index = 0; index < sourceLines.length; index++) {
|
|
1855
|
+
const line = sourceLines[index];
|
|
1856
|
+
const trimmed = line.trim();
|
|
1857
|
+
if (isPnpmWorkspaceManagedScalarKey(trimmed)) {
|
|
1858
|
+
if (!foundManagedKey) {
|
|
1859
|
+
insertionIndex = lines.length;
|
|
1860
|
+
foundManagedKey = true;
|
|
1861
|
+
}
|
|
1862
|
+
continue;
|
|
1863
|
+
}
|
|
1864
|
+
if (isPnpmWorkspaceManagedBlockKey(trimmed)) {
|
|
1865
|
+
if (!foundManagedKey) {
|
|
1866
|
+
insertionIndex = lines.length;
|
|
1867
|
+
foundManagedKey = true;
|
|
1868
|
+
}
|
|
1869
|
+
while (index + 1 < sourceLines.length) {
|
|
1870
|
+
const nextLine = sourceLines[index + 1];
|
|
1871
|
+
const nextTrimmed = nextLine.trim();
|
|
1872
|
+
if (nextTrimmed !== "" && !isIndentedWorkspaceLine(nextLine)) break;
|
|
1873
|
+
index++;
|
|
1874
|
+
}
|
|
1875
|
+
continue;
|
|
1876
|
+
}
|
|
1877
|
+
lines.push(line);
|
|
1878
|
+
}
|
|
1879
|
+
return {
|
|
1880
|
+
content: lines.join("\n").trim(),
|
|
1881
|
+
insertionIndex
|
|
1882
|
+
};
|
|
1883
|
+
}
|
|
1884
|
+
function patchPnpmWorkspaceManagedKeys(content, profile, buildDependencies) {
|
|
1885
|
+
const managedContent = workspace.renderPnpmWorkspaceConfig({
|
|
1886
|
+
profile,
|
|
1887
|
+
manageVersions: true,
|
|
1888
|
+
buildDependencies
|
|
1889
|
+
});
|
|
1890
|
+
const existing = removePnpmWorkspaceManagedKeys(content);
|
|
1891
|
+
const preservedLines = existing.content.length > 0 ? existing.content.split("\n") : [];
|
|
1892
|
+
const insertionIndex = Math.min(existing.insertionIndex, preservedLines.length);
|
|
1893
|
+
const managedLines = managedContent.split("\n");
|
|
1894
|
+
preservedLines.splice(insertionIndex, 0, ...managedLines);
|
|
1895
|
+
return preservedLines.join("\n").replace(/\n{3,}/g, "\n\n").trim();
|
|
1896
|
+
}
|
|
1897
|
+
async function getWorkspaceConfigUpdates(root, config) {
|
|
1789
1898
|
const workspacePath = path.join(root, "pnpm-workspace.yaml");
|
|
1790
1899
|
const changes = [];
|
|
1900
|
+
const packageManagerSpec = config?.targetPackageManagerSpec ?? config?.packageManagerSpec ?? { name: "pnpm" };
|
|
1901
|
+
const profile = workspace.getPackageManagerProfile(packageManagerSpec);
|
|
1902
|
+
const defaultPackages = [".config/*", "apps/*", "packages/*"];
|
|
1791
1903
|
let currentContent = "";
|
|
1792
1904
|
let exists = false;
|
|
1793
1905
|
try {
|
|
1794
|
-
currentContent = await promises.readFile(workspacePath, "utf-8");
|
|
1906
|
+
currentContent = await promises$1.readFile(workspacePath, "utf-8");
|
|
1795
1907
|
exists = true;
|
|
1796
1908
|
} catch {
|
|
1797
1909
|
}
|
|
1798
1910
|
if (!exists) {
|
|
1799
|
-
const newContent =
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
- 'packages/*'
|
|
1805
|
-
|
|
1806
|
-
onlyBuiltDependencies:
|
|
1807
|
-
- esbuild
|
|
1911
|
+
const newContent = `${workspace.renderPnpmWorkspaceConfig({
|
|
1912
|
+
profile,
|
|
1913
|
+
manageVersions: true,
|
|
1914
|
+
packages: defaultPackages
|
|
1915
|
+
})}
|
|
1808
1916
|
`;
|
|
1809
1917
|
changes.push({
|
|
1810
1918
|
path: "pnpm-workspace.yaml",
|
|
@@ -1813,32 +1921,14 @@ onlyBuiltDependencies:
|
|
|
1813
1921
|
});
|
|
1814
1922
|
return changes;
|
|
1815
1923
|
}
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
needsUpdate = true;
|
|
1823
|
-
}
|
|
1824
|
-
if (!currentContent.includes("onlyBuiltDependencies")) {
|
|
1825
|
-
updatedContent = `${updatedContent.trimEnd()}
|
|
1826
|
-
|
|
1827
|
-
onlyBuiltDependencies:
|
|
1828
|
-
- esbuild
|
|
1924
|
+
const buildDependencies = withDefaultBuildDependencies(extractBuildDependencies(currentContent));
|
|
1925
|
+
const updatedContent = `${patchPnpmWorkspaceManagedKeys(
|
|
1926
|
+
currentContent,
|
|
1927
|
+
profile,
|
|
1928
|
+
buildDependencies
|
|
1929
|
+
)}
|
|
1829
1930
|
`;
|
|
1830
|
-
|
|
1831
|
-
}
|
|
1832
|
-
if (!currentContent.includes(".config/*")) {
|
|
1833
|
-
const lines = updatedContent.split("\n");
|
|
1834
|
-
const packagesIndex = lines.findIndex((line) => line.trim().startsWith("packages:"));
|
|
1835
|
-
if (packagesIndex !== -1) {
|
|
1836
|
-
lines.splice(packagesIndex + 1, 0, " - '.config/*'");
|
|
1837
|
-
updatedContent = lines.join("\n");
|
|
1838
|
-
needsUpdate = true;
|
|
1839
|
-
}
|
|
1840
|
-
}
|
|
1841
|
-
if (needsUpdate) {
|
|
1931
|
+
if (updatedContent !== currentContent) {
|
|
1842
1932
|
changes.push({
|
|
1843
1933
|
path: "pnpm-workspace.yaml",
|
|
1844
1934
|
status: "modified",
|
|
@@ -1859,8 +1949,8 @@ async function applyUpdates(changes, root) {
|
|
|
1859
1949
|
for (const change of changes) {
|
|
1860
1950
|
if (change.status === "unchanged") continue;
|
|
1861
1951
|
const fullPath = path.join(root, change.path);
|
|
1862
|
-
await promises.mkdir(path.dirname(fullPath), { recursive: true });
|
|
1863
|
-
await promises.writeFile(fullPath, change.newContent);
|
|
1952
|
+
await promises$1.mkdir(path.dirname(fullPath), { recursive: true });
|
|
1953
|
+
await promises$1.writeFile(fullPath, change.newContent);
|
|
1864
1954
|
}
|
|
1865
1955
|
}
|
|
1866
1956
|
function formatFileChange(change) {
|
|
@@ -1936,6 +2026,96 @@ function orderUpdateCategories(categories) {
|
|
|
1936
2026
|
(left, right) => getCategoryOrder(left.category) - getCategoryOrder(right.category)
|
|
1937
2027
|
);
|
|
1938
2028
|
}
|
|
2029
|
+
function isPnpmMajorMigration(config) {
|
|
2030
|
+
const currentPackageManager = config.packageManagerSpec;
|
|
2031
|
+
const targetPackageManager = config.targetPackageManagerSpec;
|
|
2032
|
+
if (currentPackageManager?.name !== "pnpm" || targetPackageManager?.name !== "pnpm") {
|
|
2033
|
+
return false;
|
|
2034
|
+
}
|
|
2035
|
+
const currentMajor = workspace.getSemverMajor(currentPackageManager.version);
|
|
2036
|
+
const targetMajor = workspace.getSemverMajor(targetPackageManager.version);
|
|
2037
|
+
return currentMajor != null && targetMajor != null && currentMajor !== targetMajor;
|
|
2038
|
+
}
|
|
2039
|
+
function getPackageUpdateCommand(config) {
|
|
2040
|
+
const packageManagerName = config.packageManager.split("@")[0] ?? config.packageManager;
|
|
2041
|
+
if (packageManagerName === "pnpm") {
|
|
2042
|
+
if (isPnpmMajorMigration(config)) {
|
|
2043
|
+
return {
|
|
2044
|
+
command: "pnpm",
|
|
2045
|
+
args: ["install"],
|
|
2046
|
+
displayCommand: "pnpm install",
|
|
2047
|
+
promptMessage: "Install dependencies?",
|
|
2048
|
+
successMessage: "Dependencies installed",
|
|
2049
|
+
failureLabel: "Dependency install"
|
|
2050
|
+
};
|
|
2051
|
+
}
|
|
2052
|
+
return {
|
|
2053
|
+
command: "pnpm",
|
|
2054
|
+
args: ["update"],
|
|
2055
|
+
displayCommand: "pnpm update",
|
|
2056
|
+
promptMessage: "Update packages?",
|
|
2057
|
+
successMessage: "Packages updated",
|
|
2058
|
+
failureLabel: "Package update"
|
|
2059
|
+
};
|
|
2060
|
+
}
|
|
2061
|
+
if (packageManagerName === "npm") {
|
|
2062
|
+
return {
|
|
2063
|
+
command: "npm",
|
|
2064
|
+
args: ["update"],
|
|
2065
|
+
displayCommand: "npm update",
|
|
2066
|
+
promptMessage: "Update packages?",
|
|
2067
|
+
successMessage: "Packages updated",
|
|
2068
|
+
failureLabel: "Package update"
|
|
2069
|
+
};
|
|
2070
|
+
}
|
|
2071
|
+
return void 0;
|
|
2072
|
+
}
|
|
2073
|
+
async function runPackageUpdate(projectRoot, updateCommand) {
|
|
2074
|
+
await new Promise((resolve, reject) => {
|
|
2075
|
+
const child = node_child_process.spawn(updateCommand.command, updateCommand.args, {
|
|
2076
|
+
cwd: projectRoot,
|
|
2077
|
+
shell: process.platform === "win32",
|
|
2078
|
+
stdio: "inherit"
|
|
2079
|
+
});
|
|
2080
|
+
child.on("error", reject);
|
|
2081
|
+
child.on("exit", (code) => {
|
|
2082
|
+
if (code === 0) {
|
|
2083
|
+
resolve();
|
|
2084
|
+
return;
|
|
2085
|
+
}
|
|
2086
|
+
reject(new Error(`${updateCommand.displayCommand} exited with code ${code ?? "unknown"}`));
|
|
2087
|
+
});
|
|
2088
|
+
});
|
|
2089
|
+
}
|
|
2090
|
+
async function promptForPackageUpdate(projectRoot, config, options) {
|
|
2091
|
+
const updateCommand = getPackageUpdateCommand(config);
|
|
2092
|
+
if (!updateCommand) {
|
|
2093
|
+
console.log(color__default.dim(` Package updates are not supported for ${config.packageManager}`));
|
|
2094
|
+
return;
|
|
2095
|
+
}
|
|
2096
|
+
const shouldUpdatePackages = options.yes || await p__namespace.confirm({
|
|
2097
|
+
message: updateCommand.promptMessage,
|
|
2098
|
+
initialValue: true
|
|
2099
|
+
});
|
|
2100
|
+
if (p__namespace.isCancel(shouldUpdatePackages)) {
|
|
2101
|
+
p__namespace.cancel("Operation cancelled.");
|
|
2102
|
+
process.exit(0);
|
|
2103
|
+
}
|
|
2104
|
+
if (!shouldUpdatePackages) {
|
|
2105
|
+
console.log(color__default.dim(" Skipped package updates"));
|
|
2106
|
+
return;
|
|
2107
|
+
}
|
|
2108
|
+
console.log();
|
|
2109
|
+
console.log(color__default.cyan(`Running ${updateCommand.displayCommand}...`));
|
|
2110
|
+
try {
|
|
2111
|
+
await runPackageUpdate(projectRoot, updateCommand);
|
|
2112
|
+
console.log(color__default.green("\u2713") + ` ${updateCommand.successMessage}`);
|
|
2113
|
+
} catch (error) {
|
|
2114
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2115
|
+
console.log(color__default.red("\u2717") + ` ${updateCommand.failureLabel} failed: ${message}`);
|
|
2116
|
+
process.exit(1);
|
|
2117
|
+
}
|
|
2118
|
+
}
|
|
1939
2119
|
async function collectUpdateCategories(projectRoot, config, isMonorepo) {
|
|
1940
2120
|
const expected = await planExpectedFiles(config);
|
|
1941
2121
|
const categories = await compareWithDisk(expected, projectRoot);
|
|
@@ -1959,7 +2139,7 @@ async function collectUpdateCategories(projectRoot, config, isMonorepo) {
|
|
|
1959
2139
|
});
|
|
1960
2140
|
}
|
|
1961
2141
|
if (isMonorepo) {
|
|
1962
|
-
const workspaceConfigChanges = await getWorkspaceConfigUpdates(projectRoot);
|
|
2142
|
+
const workspaceConfigChanges = await getWorkspaceConfigUpdates(projectRoot, config);
|
|
1963
2143
|
if (workspaceConfigChanges.length > 0) {
|
|
1964
2144
|
allCategories.push({
|
|
1965
2145
|
category: "workspace-config",
|
|
@@ -1971,6 +2151,110 @@ async function collectUpdateCategories(projectRoot, config, isMonorepo) {
|
|
|
1971
2151
|
}
|
|
1972
2152
|
return orderUpdateCategories(allCategories);
|
|
1973
2153
|
}
|
|
2154
|
+
async function resolveTargetPackageManagerSpec(options, config) {
|
|
2155
|
+
if (options.packageManager == null) return void 0;
|
|
2156
|
+
const packageManager = workspace.parsePackageManagerSpec(options.packageManager);
|
|
2157
|
+
if (packageManager == null) {
|
|
2158
|
+
console.log(color__default.red("\u2717") + ` Unsupported package manager: ${options.packageManager}`);
|
|
2159
|
+
process.exit(1);
|
|
2160
|
+
}
|
|
2161
|
+
return workspace.resolvePackageManager({
|
|
2162
|
+
name: config.name,
|
|
2163
|
+
packageManager
|
|
2164
|
+
});
|
|
2165
|
+
}
|
|
2166
|
+
function getPackageManagerMajorUpdateTarget(currentPackageManager, latestPackageManager) {
|
|
2167
|
+
if (currentPackageManager?.version == null) return void 0;
|
|
2168
|
+
const currentMajor = workspace.getSemverMajor(currentPackageManager.version);
|
|
2169
|
+
const latestMajor = workspace.getSemverMajor(latestPackageManager.version);
|
|
2170
|
+
if (currentMajor == null || latestMajor == null || latestMajor <= currentMajor) {
|
|
2171
|
+
return void 0;
|
|
2172
|
+
}
|
|
2173
|
+
return latestPackageManager;
|
|
2174
|
+
}
|
|
2175
|
+
function getRequiredNodeUpdateTarget(currentNodeVersion, requiredNodeVersion) {
|
|
2176
|
+
if (requiredNodeVersion == null) return void 0;
|
|
2177
|
+
if (currentNodeVersion == null) return requiredNodeVersion;
|
|
2178
|
+
return workspace.compareNumericSemver(currentNodeVersion, requiredNodeVersion) < 0 ? requiredNodeVersion : void 0;
|
|
2179
|
+
}
|
|
2180
|
+
function formatPackageManagerMajor(packageManager) {
|
|
2181
|
+
const major = workspace.getSemverMajor(packageManager.version);
|
|
2182
|
+
return major == null ? packageManager.name : `${packageManager.name}@${major}`;
|
|
2183
|
+
}
|
|
2184
|
+
async function promptForNodeRequirementUpdate(options, config, targetPackageManagerSpec) {
|
|
2185
|
+
if (targetPackageManagerSpec == null) return void 0;
|
|
2186
|
+
const profile = workspace.getPackageManagerProfile(targetPackageManagerSpec);
|
|
2187
|
+
const requiredNodeVersion = profile.requirements.node;
|
|
2188
|
+
const currentNodeVersion = config.engine?.version;
|
|
2189
|
+
const targetNodeVersion = getRequiredNodeUpdateTarget(currentNodeVersion, requiredNodeVersion);
|
|
2190
|
+
if (targetNodeVersion == null) return void 0;
|
|
2191
|
+
const currentNodeLabel = currentNodeVersion == null ? "not set" : `>=${currentNodeVersion}`;
|
|
2192
|
+
p__namespace.log.warn(
|
|
2193
|
+
`${workspace.formatPackageManager(targetPackageManagerSpec)} requires Node >=${targetNodeVersion}; current engines.node is ${currentNodeLabel}.`
|
|
2194
|
+
);
|
|
2195
|
+
const shouldUpdate = options.yes || await p__namespace.confirm({
|
|
2196
|
+
message: `Update engines.node to >=${targetNodeVersion} too?`,
|
|
2197
|
+
initialValue: true
|
|
2198
|
+
});
|
|
2199
|
+
if (p__namespace.isCancel(shouldUpdate)) {
|
|
2200
|
+
p__namespace.cancel("Operation cancelled.");
|
|
2201
|
+
process.exit(0);
|
|
2202
|
+
}
|
|
2203
|
+
return shouldUpdate ? targetNodeVersion : void 0;
|
|
2204
|
+
}
|
|
2205
|
+
async function promptForPackageManagerMajorUpdate(options, config) {
|
|
2206
|
+
if (options.packageManager != null || config.packageManagerSpec == null) return void 0;
|
|
2207
|
+
const currentPackageManager = config.packageManagerSpec;
|
|
2208
|
+
if (currentPackageManager.version == null) return void 0;
|
|
2209
|
+
const latestPackageManager = await workspace.resolvePackageManager({
|
|
2210
|
+
name: config.name,
|
|
2211
|
+
packageManager: { name: currentPackageManager.name }
|
|
2212
|
+
});
|
|
2213
|
+
const updateTarget = getPackageManagerMajorUpdateTarget(
|
|
2214
|
+
currentPackageManager,
|
|
2215
|
+
latestPackageManager
|
|
2216
|
+
);
|
|
2217
|
+
if (updateTarget == null) return void 0;
|
|
2218
|
+
const shouldUpdate = options.yes || await p__namespace.confirm({
|
|
2219
|
+
message: `Update ${currentPackageManager.name} from ${formatPackageManagerMajor(
|
|
2220
|
+
currentPackageManager
|
|
2221
|
+
)} to ${formatPackageManagerMajor(latestPackageManager)}?`,
|
|
2222
|
+
initialValue: true
|
|
2223
|
+
});
|
|
2224
|
+
if (p__namespace.isCancel(shouldUpdate)) {
|
|
2225
|
+
p__namespace.cancel("Operation cancelled.");
|
|
2226
|
+
process.exit(0);
|
|
2227
|
+
}
|
|
2228
|
+
return shouldUpdate ? updateTarget : void 0;
|
|
2229
|
+
}
|
|
2230
|
+
async function applyPackageManagerMigration(projectRoot, isMonorepo, options, detectedConfig) {
|
|
2231
|
+
const targetPackageManagerSpec = await resolveTargetPackageManagerSpec(options, detectedConfig) ?? await promptForPackageManagerMajorUpdate(options, detectedConfig);
|
|
2232
|
+
if (targetPackageManagerSpec == null) return detectedConfig;
|
|
2233
|
+
const targetNodeVersion = await promptForNodeRequirementUpdate(
|
|
2234
|
+
options,
|
|
2235
|
+
detectedConfig,
|
|
2236
|
+
targetPackageManagerSpec
|
|
2237
|
+
);
|
|
2238
|
+
const migrationConfig = {
|
|
2239
|
+
...detectedConfig,
|
|
2240
|
+
packageManager: targetPackageManagerSpec.name,
|
|
2241
|
+
targetPackageManagerSpec,
|
|
2242
|
+
targetNodeVersion
|
|
2243
|
+
};
|
|
2244
|
+
const changes = [
|
|
2245
|
+
...await getPackageManagerConfigUpdates(projectRoot, migrationConfig),
|
|
2246
|
+
...isMonorepo || targetPackageManagerSpec.name === "pnpm" ? await getWorkspaceConfigUpdates(projectRoot, migrationConfig) : []
|
|
2247
|
+
].filter((change) => change.status === "added" || change.status === "modified");
|
|
2248
|
+
if (changes.length === 0) return migrationConfig;
|
|
2249
|
+
console.log();
|
|
2250
|
+
console.log(color__default.cyan("Package Manager:"));
|
|
2251
|
+
for (const change of changes) {
|
|
2252
|
+
console.log(formatFileChange(change));
|
|
2253
|
+
}
|
|
2254
|
+
await applyUpdates(changes, projectRoot);
|
|
2255
|
+
console.log(color__default.green("\u2713") + ` Package Manager: updated ${changes.length}`);
|
|
2256
|
+
return migrationConfig;
|
|
2257
|
+
}
|
|
1974
2258
|
async function processUpdateCategory(category, projectRoot, options) {
|
|
1975
2259
|
const newChanges = category.changes.filter((change) => change.status === "added");
|
|
1976
2260
|
const modifiedChanges = category.changes.filter((change) => change.status === "modified");
|
|
@@ -2010,11 +2294,8 @@ async function processUpdateCategory(category, projectRoot, options) {
|
|
|
2010
2294
|
if (addedCount > 0) parts.push(`added ${addedCount}`);
|
|
2011
2295
|
if (updatedFilesCount > 0) parts.push(`updated ${updatedFilesCount}`);
|
|
2012
2296
|
console.log(color__default.green("\u2713") + ` ${category.label}: ${parts.join(", ")}`);
|
|
2013
|
-
console.log();
|
|
2014
2297
|
return "updated";
|
|
2015
2298
|
}
|
|
2016
|
-
console.log(color__default.dim(` Skipped ${category.label}`));
|
|
2017
|
-
console.log();
|
|
2018
2299
|
return "skipped";
|
|
2019
2300
|
}
|
|
2020
2301
|
async function handleUpdateCommand(options, handleFixCommand) {
|
|
@@ -2027,7 +2308,7 @@ async function handleUpdateCommand(options, handleFixCommand) {
|
|
|
2027
2308
|
}
|
|
2028
2309
|
const isMonorepo = monorepoRoot != null;
|
|
2029
2310
|
if (isMonorepo) {
|
|
2030
|
-
const { valid, errors } = await validateWorkspace(projectRoot);
|
|
2311
|
+
const { valid, errors } = await workspace.validateWorkspace(projectRoot);
|
|
2031
2312
|
if (!valid) {
|
|
2032
2313
|
console.log(color__default.yellow("!") + " Workspace has issues:");
|
|
2033
2314
|
for (const error of errors) {
|
|
@@ -2080,6 +2361,8 @@ async function handleUpdateCommand(options, handleFixCommand) {
|
|
|
2080
2361
|
console.log(color__default.dim(` Skipped ${skippedCount}`));
|
|
2081
2362
|
}
|
|
2082
2363
|
}
|
|
2364
|
+
const finalConfig = await applyPackageManagerMigration(projectRoot, isMonorepo, options, config);
|
|
2365
|
+
await promptForPackageUpdate(projectRoot, finalConfig, options);
|
|
2083
2366
|
process.exit(0);
|
|
2084
2367
|
}
|
|
2085
2368
|
|
|
@@ -2097,9 +2380,10 @@ async function createPackageInWorkspace(monorepoRoot, packageManager, inheritedS
|
|
|
2097
2380
|
message: "Package name?",
|
|
2098
2381
|
initialValue: `@${scope}/`,
|
|
2099
2382
|
validate: (value) => {
|
|
2100
|
-
const
|
|
2383
|
+
const packageName = value ?? "";
|
|
2384
|
+
const validationError = workspace.validatePackageName(packageName);
|
|
2101
2385
|
if (validationError) return validationError;
|
|
2102
|
-
const dirName =
|
|
2386
|
+
const dirName = workspace.getPackageDirectoryName(packageName);
|
|
2103
2387
|
if (!dirName) return "Package name is required";
|
|
2104
2388
|
if (!hasCustomDirectories) {
|
|
2105
2389
|
const targetPath = node_path.join(monorepoRoot, defaultDir, dirName);
|
|
@@ -2116,7 +2400,7 @@ async function createPackageInWorkspace(monorepoRoot, packageManager, inheritedS
|
|
|
2116
2400
|
return false;
|
|
2117
2401
|
}
|
|
2118
2402
|
const scopedName = packageNameInput;
|
|
2119
|
-
const shortName =
|
|
2403
|
+
const shortName = workspace.getPackageDirectoryName(scopedName);
|
|
2120
2404
|
const packageOptions = await promptForPackageOptions(scopedName, packageType, inheritedSettings);
|
|
2121
2405
|
let targetDir = defaultDir;
|
|
2122
2406
|
if (hasCustomDirectories && workspaceDirectories.length > 0) {
|
|
@@ -2197,10 +2481,11 @@ async function handleWorkspaceCommand(name, options, writeGeneratedFiles) {
|
|
|
2197
2481
|
const template = options.template ?? "vanilla";
|
|
2198
2482
|
const baseTemplate = workspace.getBaseTemplate(template);
|
|
2199
2483
|
const scopedName = name.startsWith("@") ? name : `@${scope}/${name}`;
|
|
2200
|
-
const
|
|
2484
|
+
const packageDirName = workspace.getPackageDirectoryName(name);
|
|
2485
|
+
const fullPackagePath = node_path.join(monorepoRoot, targetDir, packageDirName);
|
|
2201
2486
|
try {
|
|
2202
|
-
await promises
|
|
2203
|
-
console.error(color__default.red("Error:") + ` Directory ${targetDir}/${
|
|
2487
|
+
await promises.access(fullPackagePath, node_fs.constants.F_OK);
|
|
2488
|
+
console.error(color__default.red("Error:") + ` Directory ${targetDir}/${packageDirName} already exists`);
|
|
2204
2489
|
process.exit(1);
|
|
2205
2490
|
} catch {
|
|
2206
2491
|
}
|
|
@@ -2213,7 +2498,7 @@ async function handleWorkspaceCommand(name, options, writeGeneratedFiles) {
|
|
|
2213
2498
|
};
|
|
2214
2499
|
const pnpmManageVersions = inheritedSettings.pnpmManageVersions ?? true;
|
|
2215
2500
|
const isLibrary = projectType === "library";
|
|
2216
|
-
const relativePkgPath = node_path.join(targetDir,
|
|
2501
|
+
const relativePkgPath = node_path.join(targetDir, packageDirName);
|
|
2217
2502
|
const workspaceRoot = calculateWorkspaceRoot(relativePkgPath);
|
|
2218
2503
|
const projectOptions = {
|
|
2219
2504
|
name: scopedName,
|
|
@@ -2241,11 +2526,11 @@ async function handleWorkspaceCommand(name, options, writeGeneratedFiles) {
|
|
|
2241
2526
|
triplex: options.triplex ? {} : void 0
|
|
2242
2527
|
}
|
|
2243
2528
|
};
|
|
2244
|
-
console.log(color__default.cyan("Creating") + ` ${scopedName} in ${targetDir}/${
|
|
2529
|
+
console.log(color__default.cyan("Creating") + ` ${scopedName} in ${targetDir}/${packageDirName}...`);
|
|
2245
2530
|
try {
|
|
2246
2531
|
const { files } = await workspace.planProject(workspace.resolveProjectPlanInput(projectOptions));
|
|
2247
2532
|
await writeGeneratedFiles(fullPackagePath, files);
|
|
2248
|
-
console.log(color__default.green("\u2713") + ` Created ${scopedName} at ${targetDir}/${
|
|
2533
|
+
console.log(color__default.green("\u2713") + ` Created ${scopedName} at ${targetDir}/${packageDirName}`);
|
|
2249
2534
|
process.exit(0);
|
|
2250
2535
|
} catch (error) {
|
|
2251
2536
|
console.error(color__default.red("Error:") + " Failed to create package");
|
|
@@ -2316,13 +2601,13 @@ async function writeGeneratedFiles(basePath, files) {
|
|
|
2316
2601
|
const filePaths = Object.keys(files).sort();
|
|
2317
2602
|
for (const filePath of filePaths) {
|
|
2318
2603
|
const fullFilePath = node_path.join(basePath, filePath);
|
|
2319
|
-
await promises
|
|
2604
|
+
await promises.mkdir(node_path.dirname(fullFilePath), { recursive: true });
|
|
2320
2605
|
const file = files[filePath];
|
|
2321
2606
|
if (file.type === "text") {
|
|
2322
|
-
await promises
|
|
2607
|
+
await promises.writeFile(fullFilePath, file.content);
|
|
2323
2608
|
} else {
|
|
2324
2609
|
const response = await undici.fetch(file.url);
|
|
2325
|
-
await promises
|
|
2610
|
+
await promises.writeFile(fullFilePath, response.body);
|
|
2326
2611
|
}
|
|
2327
2612
|
}
|
|
2328
2613
|
}
|
|
@@ -2390,7 +2675,8 @@ async function handleSingleWorkspaceCreation(projectOptions, isNonInteractive) {
|
|
|
2390
2675
|
const defaultFallbackName = base === "vanilla" ? "vanilla-app" : base === "react" ? "react-app" : "react-three-app";
|
|
2391
2676
|
projectOptions.name ??= defaultFallbackName;
|
|
2392
2677
|
const packageManager = workspace.getPackageManagerName(projectOptions.packageManager);
|
|
2393
|
-
const
|
|
2678
|
+
const projectDirName = workspace.getPackageDirectoryName(projectOptions.name);
|
|
2679
|
+
const projectPath = node_path.join(node_process.cwd(), projectDirName);
|
|
2394
2680
|
const spinner = p__namespace.spinner();
|
|
2395
2681
|
spinner.start("Creating project...");
|
|
2396
2682
|
try {
|
|
@@ -2399,15 +2685,11 @@ async function handleSingleWorkspaceCreation(projectOptions, isNonInteractive) {
|
|
|
2399
2685
|
await writeGeneratedFiles(projectPath, files);
|
|
2400
2686
|
spinner.stop(color__default.green.inverse(" \u2713 Project created! "));
|
|
2401
2687
|
if (isNonInteractive) process.exit(0);
|
|
2402
|
-
const nextSteps = projectOptions.projectType === "library" ? [
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
`cd ${projectOptions.name}`,
|
|
2408
|
-
`${packageManager} install`,
|
|
2409
|
-
`${packageManager} run dev`
|
|
2410
|
-
].join("\n");
|
|
2688
|
+
const nextSteps = projectOptions.projectType === "library" ? [`cd ${projectDirName}`, `${packageManager} install`, `${packageManager} run build`].join(
|
|
2689
|
+
"\n"
|
|
2690
|
+
) : [`cd ${projectDirName}`, `${packageManager} install`, `${packageManager} run dev`].join(
|
|
2691
|
+
"\n"
|
|
2692
|
+
);
|
|
2411
2693
|
p__namespace.note(nextSteps, "Next steps");
|
|
2412
2694
|
p__namespace.outro(color__default.green("Happy coding! \u2728"));
|
|
2413
2695
|
} catch (error) {
|
|
@@ -2423,7 +2705,7 @@ async function main() {
|
|
|
2423
2705
|
).option(
|
|
2424
2706
|
"--template <type>",
|
|
2425
2707
|
"project template: vanilla, vanilla-js, react, react-js, r3f, r3f-js (default: vanilla)"
|
|
2426
|
-
).option("--linter <type>", "linter: eslint, oxlint, or biome (default: oxlint)").option("--formatter <type>", "formatter: prettier, oxfmt, or biome (default: prettier)").option("--drei", "add @react-three/drei (r3f only)").option("--handle", "add @react-three/handle (r3f only)").option("--leva", "add leva (r3f only)").option("--postprocessing", "add @react-three/postprocessing (r3f only)").option("--rapier", "add @react-three/rapier (r3f only)").option("--xr", "add @react-three/xr (r3f only)").option("--uikit", "add @react-three/uikit (r3f only)").option("--offscreen", "add @react-three/offscreen (r3f only)").option("--zustand", "add zustand (r3f only)").option("--koota", "add koota (r3f only)").option("--triplex", "set up triplex development environment (r3f only)").option("--viverse", "set up viverse deployment (r3f only)").option("--package-manager <manager>", "specify package manager (e.g. npm, yarn, pnpm)").option("--ide <ide>", "IDE files: vscode or none (default: vscode)").option(
|
|
2708
|
+
).option("--linter <type>", "linter: eslint, oxlint, or biome (default: oxlint)").option("--formatter <type>", "formatter: prettier, oxfmt, or biome (default: prettier)").option("--drei", "add @react-three/drei (r3f only)").option("--handle", "add @react-three/handle (r3f only)").option("--leva", "add leva (r3f only)").option("--postprocessing", "add @react-three/postprocessing (r3f only)").option("--rapier", "add @react-three/rapier (r3f only)").option("--xr", "add @react-three/xr (r3f only)").option("--uikit", "add @react-three/uikit (r3f only)").option("--offscreen", "add @react-three/offscreen (r3f only)").option("--zustand", "add zustand (r3f only)").option("--koota", "add koota (r3f only)").option("--triplex", "set up triplex development environment (r3f only)").option("--viverse", "set up viverse deployment (r3f only)").option("--package-manager <manager>", "specify package manager (e.g. npm, yarn, pnpm@11)").option("--ide <ide>", "IDE files: vscode or none (default: vscode)").option(
|
|
2427
2709
|
"--pnpm-manage-versions",
|
|
2428
2710
|
"enable manage-package-manager-versions in pnpm-workspace.yaml (default: true)"
|
|
2429
2711
|
).option(
|
|
@@ -2437,18 +2719,24 @@ async function main() {
|
|
|
2437
2719
|
process.chdir(options.path);
|
|
2438
2720
|
}
|
|
2439
2721
|
if (options.clearConfig) {
|
|
2440
|
-
clearConfig();
|
|
2722
|
+
workspace.clearConfig();
|
|
2441
2723
|
console.log("Configuration cleared.");
|
|
2442
2724
|
process.exit(0);
|
|
2443
2725
|
}
|
|
2444
2726
|
if (options.configPath) {
|
|
2445
|
-
console.log(getConfigPath());
|
|
2727
|
+
console.log(workspace.getConfigPath());
|
|
2446
2728
|
process.exit(0);
|
|
2447
2729
|
}
|
|
2448
2730
|
if (options.ide && !["vscode", "none"].includes(options.ide)) {
|
|
2449
2731
|
console.error(color__default.red("Error:") + ' --ide must be "vscode" or "none"');
|
|
2450
2732
|
process.exit(1);
|
|
2451
2733
|
}
|
|
2734
|
+
const packageManagerSpec = workspace.parsePackageManagerSpec(options.packageManager);
|
|
2735
|
+
if (options.packageManager && packageManagerSpec == null) {
|
|
2736
|
+
console.error(color__default.red("Error:") + " --package-manager must be npm, yarn, or pnpm");
|
|
2737
|
+
console.log(color__default.dim(" Version specs are allowed, e.g. pnpm@10 or pnpm@11"));
|
|
2738
|
+
process.exit(1);
|
|
2739
|
+
}
|
|
2452
2740
|
if (name?.startsWith("-")) {
|
|
2453
2741
|
switch (name) {
|
|
2454
2742
|
case "--version":
|
|
@@ -2460,11 +2748,11 @@ async function main() {
|
|
|
2460
2748
|
program.help();
|
|
2461
2749
|
break;
|
|
2462
2750
|
case "--clear-config":
|
|
2463
|
-
clearConfig();
|
|
2751
|
+
workspace.clearConfig();
|
|
2464
2752
|
console.log("Configuration cleared.");
|
|
2465
2753
|
process.exit(0);
|
|
2466
2754
|
case "--config-path":
|
|
2467
|
-
console.log(getConfigPath());
|
|
2755
|
+
console.log(workspace.getConfigPath());
|
|
2468
2756
|
process.exit(0);
|
|
2469
2757
|
case "--check":
|
|
2470
2758
|
await handleCheckCommand();
|
|
@@ -2534,7 +2822,7 @@ async function main() {
|
|
|
2534
2822
|
viverse: options.viverse ? {} : void 0,
|
|
2535
2823
|
triplex: options.triplex ? {} : void 0
|
|
2536
2824
|
},
|
|
2537
|
-
packageManager:
|
|
2825
|
+
packageManager: packageManagerSpec,
|
|
2538
2826
|
pnpmManageVersions: options.pnpmManageVersions,
|
|
2539
2827
|
engine: { name: "node", version: options.nodeVersion ?? "latest" }
|
|
2540
2828
|
};
|
|
@@ -2545,7 +2833,7 @@ async function main() {
|
|
|
2545
2833
|
bundler: options.bundler,
|
|
2546
2834
|
linter: options.linter,
|
|
2547
2835
|
formatter: options.formatter,
|
|
2548
|
-
packageManager:
|
|
2836
|
+
packageManager: packageManagerSpec,
|
|
2549
2837
|
ide: options.ide,
|
|
2550
2838
|
engine: options.nodeVersion ? { name: "node", version: options.nodeVersion } : void 0,
|
|
2551
2839
|
pnpmManageVersions: options.pnpmManageVersions,
|