@mnci/cli 4.48.0 → 4.50.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/README.md +63 -0
- package/dist/cli.js +659 -304
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -3187,7 +3187,7 @@ function runPhase(phase, workspaceRoot, dependencies) {
|
|
|
3187
3187
|
}
|
|
3188
3188
|
|
|
3189
3189
|
// src/project-scaffolding/add-project.use-case.ts
|
|
3190
|
-
var
|
|
3190
|
+
var import_node_path35 = require("path");
|
|
3191
3191
|
var import_prompts3 = require("@inquirer/prompts");
|
|
3192
3192
|
|
|
3193
3193
|
// src/project-name/project-name.validator.ts
|
|
@@ -3372,7 +3372,10 @@ function findCodeWorkspaceFile(workspaceRoot) {
|
|
|
3372
3372
|
function projectTask(name, kind) {
|
|
3373
3373
|
const script = `${name}:${kind}`;
|
|
3374
3374
|
const base = { label: `${name}: ${kind}`, type: "npm", script, problemMatcher: [] };
|
|
3375
|
-
|
|
3375
|
+
if (kind === "start") {
|
|
3376
|
+
return { ...base, isBackground: true };
|
|
3377
|
+
}
|
|
3378
|
+
return kind === "build" || kind === "qa" ? { ...base, group: kind } : base;
|
|
3376
3379
|
}
|
|
3377
3380
|
function renameScaffoldPlaceholder(projectRoot, name, empty = false) {
|
|
3378
3381
|
reshapeScaffoldSlice(projectRoot, name, "ts", "use-case", empty);
|
|
@@ -3521,7 +3524,7 @@ function registerProjectCommands(workspaceRoot, name, commands) {
|
|
|
3521
3524
|
removeStaleGitkeeps(workspaceRoot);
|
|
3522
3525
|
ensurePythonArtefactsIgnored(workspaceRoot);
|
|
3523
3526
|
const scripts = {
|
|
3524
|
-
[`${name}:qa`]: `nx run ${name}:lint && nx run ${name}:test`
|
|
3527
|
+
[`${name}:qa`]: commands.qa ?? `nx run ${name}:lint && nx run ${name}:test`
|
|
3525
3528
|
};
|
|
3526
3529
|
if (commands.build) {
|
|
3527
3530
|
scripts[`${name}:build`] = `nx run ${name}:build`;
|
|
@@ -3529,6 +3532,10 @@ function registerProjectCommands(workspaceRoot, name, commands) {
|
|
|
3529
3532
|
if (commands.start) {
|
|
3530
3533
|
scripts[`${name}:start`] = commands.start;
|
|
3531
3534
|
}
|
|
3535
|
+
const extraScripts = Object.entries(commands.extra ?? {});
|
|
3536
|
+
for (const [suffix, command] of extraScripts) {
|
|
3537
|
+
scripts[`${name}:${suffix}`] = command;
|
|
3538
|
+
}
|
|
3532
3539
|
const dependabotPath = (0, import_node_path11.join)(workspaceRoot, ".github/dependabot.yml");
|
|
3533
3540
|
if ((0, import_node_fs13.existsSync)(dependabotPath)) {
|
|
3534
3541
|
writeFileEnsured(dependabotPath, dependabotConfig(workspaceRoot));
|
|
@@ -3555,7 +3562,8 @@ function registerProjectCommands(workspaceRoot, name, commands) {
|
|
|
3555
3562
|
const newTasks = [
|
|
3556
3563
|
projectTask(name, "qa"),
|
|
3557
3564
|
...commands.build ? [projectTask(name, "build")] : [],
|
|
3558
|
-
...commands.start ? [projectTask(name, "start")] : []
|
|
3565
|
+
...commands.start ? [projectTask(name, "start")] : [],
|
|
3566
|
+
...Object.keys(commands.extra ?? {}).map((suffix) => projectTask(name, suffix))
|
|
3559
3567
|
];
|
|
3560
3568
|
writeFileEnsured(
|
|
3561
3569
|
codeWorkspacePath,
|
|
@@ -4797,9 +4805,70 @@ function addGoInternalLib(workspaceRoot, name) {
|
|
|
4797
4805
|
}
|
|
4798
4806
|
}
|
|
4799
4807
|
|
|
4800
|
-
// src/project-scaffolding/
|
|
4808
|
+
// src/project-scaffolding/esm-conversion.use-case.ts
|
|
4809
|
+
var import_node_fs19 = require("fs");
|
|
4801
4810
|
var import_node_path18 = require("path");
|
|
4802
4811
|
|
|
4812
|
+
// src/project-scaffolding/esm-specifiers.algorithm.ts
|
|
4813
|
+
var RELATIVE_SPECIFIER = /((?:\bfrom|\bimport)\s*)(['"])(\.{1,2}\/[^'"\n]*|\.{1,2})\2/g;
|
|
4814
|
+
var HAS_EXTENSION = /\.(?:[cm]?js|json|node)$/;
|
|
4815
|
+
function withJsSpecifiers(source, directories = []) {
|
|
4816
|
+
return source.replaceAll(RELATIVE_SPECIFIER, (_match, lead, quote, specifier) => {
|
|
4817
|
+
if (HAS_EXTENSION.test(specifier)) {
|
|
4818
|
+
return `${lead}${quote}${specifier}${quote}`;
|
|
4819
|
+
}
|
|
4820
|
+
const extended = directories.includes(specifier) ? `${specifier}/index.js` : `${specifier}.js`;
|
|
4821
|
+
return `${lead}${quote}${extended}${quote}`;
|
|
4822
|
+
});
|
|
4823
|
+
}
|
|
4824
|
+
|
|
4825
|
+
// src/project-scaffolding/esm-conversion.use-case.ts
|
|
4826
|
+
var SAMPLE_DIRECTORIES = ["./hello"];
|
|
4827
|
+
var JEST_ANCHOR = " moduleFileExtensions:";
|
|
4828
|
+
var JEST_MAPPER = String.raw` moduleNameMapper: { '^(\\.{1,2}/.*)\\.js$': '$1' },`;
|
|
4829
|
+
function typescriptFiles(directory) {
|
|
4830
|
+
const entries = (0, import_node_fs19.readdirSync)(directory, { withFileTypes: true });
|
|
4831
|
+
return entries.flatMap((entry) => {
|
|
4832
|
+
const path = (0, import_node_path18.join)(directory, entry.name);
|
|
4833
|
+
if (entry.isDirectory()) {
|
|
4834
|
+
return typescriptFiles(path);
|
|
4835
|
+
}
|
|
4836
|
+
return entry.name.endsWith(".ts") ? [path] : [];
|
|
4837
|
+
});
|
|
4838
|
+
}
|
|
4839
|
+
function convertAppToEsm(appRoot) {
|
|
4840
|
+
const manifestPath = (0, import_node_path18.join)(appRoot, "package.json");
|
|
4841
|
+
const manifest = readJson(manifestPath);
|
|
4842
|
+
const build = manifest.nx?.targets?.build;
|
|
4843
|
+
if (build?.options === void 0) {
|
|
4844
|
+
throw new Error(`${manifestPath} has no nx build target to switch to ESM; the generator's output changed.`);
|
|
4845
|
+
}
|
|
4846
|
+
build.options.format = ["esm"];
|
|
4847
|
+
writeFileEnsured(manifestPath, toJson({ ...manifest, type: "module" }));
|
|
4848
|
+
const sources = typescriptFiles((0, import_node_path18.join)(appRoot, "src"));
|
|
4849
|
+
for (const file of sources) {
|
|
4850
|
+
const source = (0, import_node_fs19.readFileSync)(file, "utf8");
|
|
4851
|
+
const converted = withJsSpecifiers(source, SAMPLE_DIRECTORIES);
|
|
4852
|
+
if (converted !== source) {
|
|
4853
|
+
writeFileEnsured(file, converted);
|
|
4854
|
+
}
|
|
4855
|
+
}
|
|
4856
|
+
const jestPath = (0, import_node_path18.join)(appRoot, "jest.config.cts");
|
|
4857
|
+
if (fileExists(jestPath)) {
|
|
4858
|
+
const jest = (0, import_node_fs19.readFileSync)(jestPath, "utf8");
|
|
4859
|
+
if (!jest.includes("moduleNameMapper")) {
|
|
4860
|
+
if (!jest.includes(JEST_ANCHOR)) {
|
|
4861
|
+
throw new Error(`${jestPath} has no moduleFileExtensions line to put the .js mapper above; the generator's output changed.`);
|
|
4862
|
+
}
|
|
4863
|
+
writeFileEnsured(jestPath, jest.replace(JEST_ANCHOR, () => `${JEST_MAPPER}
|
|
4864
|
+
${JEST_ANCHOR}`));
|
|
4865
|
+
}
|
|
4866
|
+
}
|
|
4867
|
+
}
|
|
4868
|
+
|
|
4869
|
+
// src/project-scaffolding/node.use-case.ts
|
|
4870
|
+
var import_node_path19 = require("path");
|
|
4871
|
+
|
|
4803
4872
|
// src/project-scaffolding/node-app-example.algorithm.ts
|
|
4804
4873
|
var GREET_USE_CASE = `import type { Greeting } from './greeting.contract'
|
|
4805
4874
|
|
|
@@ -4921,12 +4990,12 @@ function runNodeApp(workspaceRoot, name, stack, framework) {
|
|
|
4921
4990
|
],
|
|
4922
4991
|
workspaceRoot
|
|
4923
4992
|
);
|
|
4924
|
-
const appRoot = (0,
|
|
4993
|
+
const appRoot = (0, import_node_path19.join)(workspaceRoot, "apps", name);
|
|
4925
4994
|
separateDeclarationOutput(appRoot);
|
|
4926
4995
|
repairAssetMapping(appRoot, name);
|
|
4927
4996
|
}
|
|
4928
4997
|
function separateDeclarationOutput(appRoot) {
|
|
4929
|
-
const tsconfigPath = (0,
|
|
4998
|
+
const tsconfigPath = (0, import_node_path19.join)(appRoot, "tsconfig.app.json");
|
|
4930
4999
|
if (!fileExists(tsconfigPath)) {
|
|
4931
5000
|
return;
|
|
4932
5001
|
}
|
|
@@ -4948,7 +5017,7 @@ function separateDeclarationOutput(appRoot) {
|
|
|
4948
5017
|
);
|
|
4949
5018
|
}
|
|
4950
5019
|
function repairAssetMapping(appRoot, name) {
|
|
4951
|
-
const manifestPath = (0,
|
|
5020
|
+
const manifestPath = (0, import_node_path19.join)(appRoot, "package.json");
|
|
4952
5021
|
if (!fileExists(manifestPath)) {
|
|
4953
5022
|
return;
|
|
4954
5023
|
}
|
|
@@ -4972,16 +5041,19 @@ function nodeAppPackageTarget(name) {
|
|
|
4972
5041
|
options: { command }
|
|
4973
5042
|
};
|
|
4974
5043
|
}
|
|
4975
|
-
function addNodeApp(workspaceRoot, name, stack, framework = "none") {
|
|
5044
|
+
function addNodeApp(workspaceRoot, name, stack, framework = "none", esm = false) {
|
|
4976
5045
|
runNodeApp(workspaceRoot, name, stack, framework);
|
|
4977
5046
|
const example = nodeAppExampleFiles(framework);
|
|
4978
5047
|
if (example !== null) {
|
|
4979
5048
|
for (const [relative, contents] of Object.entries(example)) {
|
|
4980
|
-
writeFileEnsured((0,
|
|
5049
|
+
writeFileEnsured((0, import_node_path19.join)(workspaceRoot, "apps", name, "src", relative), contents);
|
|
4981
5050
|
}
|
|
4982
5051
|
}
|
|
5052
|
+
if (esm) {
|
|
5053
|
+
convertAppToEsm((0, import_node_path19.join)(workspaceRoot, "apps", name));
|
|
5054
|
+
}
|
|
4983
5055
|
ensureAdmZip(workspaceRoot);
|
|
4984
|
-
addNxTargets((0,
|
|
5056
|
+
addNxTargets((0, import_node_path19.join)(workspaceRoot, "apps", name, "package.json"), {
|
|
4985
5057
|
package: nodeAppPackageTarget(name)
|
|
4986
5058
|
});
|
|
4987
5059
|
removeGeneratedEslintConfig(workspaceRoot, `apps/${name}`);
|
|
@@ -5050,10 +5122,10 @@ describe('greet', () => {
|
|
|
5050
5122
|
})
|
|
5051
5123
|
`;
|
|
5052
5124
|
function repairNodeFunctionAppManifest(nodeFunctionAppRoot, workspaceRoot) {
|
|
5053
|
-
const manifestPath = (0,
|
|
5125
|
+
const manifestPath = (0, import_node_path19.join)(nodeFunctionAppRoot, "package.json");
|
|
5054
5126
|
const manifest = readJson(manifestPath);
|
|
5055
5127
|
const azureFunctionsVersion = readJson(
|
|
5056
|
-
(0,
|
|
5128
|
+
(0, import_node_path19.join)(workspaceRoot, "node_modules/@azure/functions/package.json")
|
|
5057
5129
|
).version;
|
|
5058
5130
|
const dependencies = manifest.dependencies ?? {};
|
|
5059
5131
|
writeFileEnsured(
|
|
@@ -5093,23 +5165,26 @@ function nodeFunctionAppStartTarget(name) {
|
|
|
5093
5165
|
options: { command: "func start", cwd: `apps/${name}` }
|
|
5094
5166
|
};
|
|
5095
5167
|
}
|
|
5096
|
-
function addNodeFunctionApp(workspaceRoot, name, stack, empty = false) {
|
|
5168
|
+
function addNodeFunctionApp(workspaceRoot, name, stack, empty = false, esm = false) {
|
|
5097
5169
|
runNodeApp(workspaceRoot, name, stack, "none");
|
|
5098
5170
|
ensureAzureFunctionsPackage(workspaceRoot);
|
|
5099
|
-
const nodeFunctionAppRoot = (0,
|
|
5100
|
-
writeFileEnsured((0,
|
|
5171
|
+
const nodeFunctionAppRoot = (0, import_node_path19.join)(workspaceRoot, "apps", name);
|
|
5172
|
+
writeFileEnsured((0, import_node_path19.join)(nodeFunctionAppRoot, "src/main.ts"), empty ? NODE_FUNCTION_APP_MAIN_EMPTY : NODE_FUNCTION_APP_MAIN);
|
|
5101
5173
|
if (!empty) {
|
|
5102
|
-
const slice = (0,
|
|
5103
|
-
writeFileEnsured((0,
|
|
5104
|
-
writeFileEnsured((0,
|
|
5105
|
-
writeFileEnsured((0,
|
|
5106
|
-
writeFileEnsured((0,
|
|
5107
|
-
writeFileEnsured((0,
|
|
5108
|
-
}
|
|
5109
|
-
writeFileEnsured((0,
|
|
5174
|
+
const slice = (0, import_node_path19.join)(nodeFunctionAppRoot, "src/hello");
|
|
5175
|
+
writeFileEnsured((0, import_node_path19.join)(slice, "hello.handler.ts"), NODE_FUNCTION_APP_HELLO);
|
|
5176
|
+
writeFileEnsured((0, import_node_path19.join)(slice, "greet.use-case.ts"), NODE_FUNCTION_APP_GREET_USE_CASE);
|
|
5177
|
+
writeFileEnsured((0, import_node_path19.join)(slice, "greet.use-case.spec.ts"), NODE_FUNCTION_APP_GREET_SPEC);
|
|
5178
|
+
writeFileEnsured((0, import_node_path19.join)(slice, "greeting.contract.ts"), NODE_FUNCTION_APP_GREETING_CONTRACT);
|
|
5179
|
+
writeFileEnsured((0, import_node_path19.join)(slice, "index.ts"), NODE_FUNCTION_APP_HELLO_BARREL);
|
|
5180
|
+
}
|
|
5181
|
+
writeFileEnsured((0, import_node_path19.join)(nodeFunctionAppRoot, "host.json"), NODE_FUNCTION_APP_HOST_JSON);
|
|
5110
5182
|
repairNodeFunctionAppManifest(nodeFunctionAppRoot, workspaceRoot);
|
|
5183
|
+
if (esm) {
|
|
5184
|
+
convertAppToEsm(nodeFunctionAppRoot);
|
|
5185
|
+
}
|
|
5111
5186
|
ensureAdmZip(workspaceRoot);
|
|
5112
|
-
addNxTargets((0,
|
|
5187
|
+
addNxTargets((0, import_node_path19.join)(nodeFunctionAppRoot, "package.json"), {
|
|
5113
5188
|
package: nodeFunctionAppPackageTarget(name),
|
|
5114
5189
|
prune: nodeFunctionAppPruneTarget(name),
|
|
5115
5190
|
start: nodeFunctionAppStartTarget(name),
|
|
@@ -5121,24 +5196,24 @@ function addNodeFunctionApp(workspaceRoot, name, stack, empty = false) {
|
|
|
5121
5196
|
}
|
|
5122
5197
|
|
|
5123
5198
|
// src/project-scaffolding/npm-lib.use-case.ts
|
|
5124
|
-
var
|
|
5199
|
+
var import_node_path25 = require("path");
|
|
5125
5200
|
|
|
5126
5201
|
// src/lockfile-pruning/prune-stale-local-registry.use-case.ts
|
|
5127
|
-
var
|
|
5128
|
-
var
|
|
5202
|
+
var import_node_fs21 = require("fs");
|
|
5203
|
+
var import_node_path21 = require("path");
|
|
5129
5204
|
|
|
5130
5205
|
// src/lockfile-pruning/stale-local-registry.validator.ts
|
|
5131
|
-
var
|
|
5132
|
-
var
|
|
5206
|
+
var import_node_fs20 = require("fs");
|
|
5207
|
+
var import_node_path20 = require("path");
|
|
5133
5208
|
var LOCAL_REGISTRY_PACKAGE = "verdaccio";
|
|
5134
5209
|
var LOCAL_REGISTRY_LOCK_KEY = `node_modules/${LOCAL_REGISTRY_PACKAGE}`;
|
|
5135
5210
|
var DEPENDENCY_FIELDS = ["dependencies", "devDependencies", "optionalDependencies", "peerDependencies"];
|
|
5136
5211
|
function readJsonFile(path) {
|
|
5137
|
-
if (!(0,
|
|
5212
|
+
if (!(0, import_node_fs20.existsSync)(path)) {
|
|
5138
5213
|
return void 0;
|
|
5139
5214
|
}
|
|
5140
5215
|
try {
|
|
5141
|
-
return JSON.parse((0,
|
|
5216
|
+
return JSON.parse((0, import_node_fs20.readFileSync)(path, "utf8"));
|
|
5142
5217
|
} catch {
|
|
5143
5218
|
return void 0;
|
|
5144
5219
|
}
|
|
@@ -5150,13 +5225,13 @@ function declaresLocalRegistry(manifest) {
|
|
|
5150
5225
|
});
|
|
5151
5226
|
}
|
|
5152
5227
|
function hasStaleLocalRegistry(workspaceRoot) {
|
|
5153
|
-
const lock = readJsonFile((0,
|
|
5228
|
+
const lock = readJsonFile((0, import_node_path20.join)(workspaceRoot, "package-lock.json"));
|
|
5154
5229
|
const entries = lock?.packages ?? {};
|
|
5155
5230
|
if (!Object.hasOwn(entries, LOCAL_REGISTRY_LOCK_KEY)) {
|
|
5156
5231
|
return false;
|
|
5157
5232
|
}
|
|
5158
5233
|
const members = Object.keys(entries).filter((key) => key !== "" && !key.startsWith("node_modules/") && !key.includes("/node_modules/"));
|
|
5159
|
-
const manifests = ["", ...members].map((directory) => readJsonFile((0,
|
|
5234
|
+
const manifests = ["", ...members].map((directory) => readJsonFile((0, import_node_path20.join)(workspaceRoot, directory, "package.json")));
|
|
5160
5235
|
return manifests.every((manifest) => !declaresLocalRegistry(manifest));
|
|
5161
5236
|
}
|
|
5162
5237
|
|
|
@@ -5165,21 +5240,21 @@ function pruneStaleLocalRegistry(workspaceRoot, resolve2 = runShell) {
|
|
|
5165
5240
|
if (!hasStaleLocalRegistry(workspaceRoot)) {
|
|
5166
5241
|
return { stale: false, status: 0 };
|
|
5167
5242
|
}
|
|
5168
|
-
const lockPath = (0,
|
|
5169
|
-
const lock = JSON.parse((0,
|
|
5243
|
+
const lockPath = (0, import_node_path21.join)(workspaceRoot, "package-lock.json");
|
|
5244
|
+
const lock = JSON.parse((0, import_node_fs21.readFileSync)(lockPath, "utf8"));
|
|
5170
5245
|
Reflect.deleteProperty(lock.packages, LOCAL_REGISTRY_LOCK_KEY);
|
|
5171
5246
|
const root = lock.packages[""];
|
|
5172
5247
|
if (root?.devDependencies !== void 0) {
|
|
5173
5248
|
Reflect.deleteProperty(root.devDependencies, LOCAL_REGISTRY_PACKAGE);
|
|
5174
5249
|
}
|
|
5175
|
-
(0,
|
|
5250
|
+
(0, import_node_fs21.writeFileSync)(lockPath, `${JSON.stringify(lock, void 0, 2)}
|
|
5176
5251
|
`);
|
|
5177
5252
|
return { stale: true, status: resolve2("npm", ["install", "--package-lock-only", "--ignore-scripts", "--no-audit", "--no-fund"], workspaceRoot) };
|
|
5178
5253
|
}
|
|
5179
5254
|
|
|
5180
5255
|
// src/rollup-library/repair-publishable-manifest.use-case.ts
|
|
5181
|
-
var
|
|
5182
|
-
var
|
|
5256
|
+
var import_node_fs22 = require("fs");
|
|
5257
|
+
var import_node_path22 = require("path");
|
|
5183
5258
|
var WRONG_TYPES_PATH = "./dist/index.esm.d.ts";
|
|
5184
5259
|
var ACTUAL_TYPES_PATH = "./dist/src/index.d.ts";
|
|
5185
5260
|
var DECLARATION_MAP_EXCLUSION = "!**/*.d.ts.map";
|
|
@@ -5202,14 +5277,14 @@ function repairPublishableManifest(manifestPath) {
|
|
|
5202
5277
|
}
|
|
5203
5278
|
function repairPublishableManifests(workspaceRoot) {
|
|
5204
5279
|
const changed = [];
|
|
5205
|
-
const manifests = (0,
|
|
5280
|
+
const manifests = (0, import_node_fs22.globSync)(["packages/*/package.json", "libs/*/package.json"], {
|
|
5206
5281
|
cwd: workspaceRoot
|
|
5207
5282
|
});
|
|
5208
5283
|
for (const relativePath of manifests) {
|
|
5209
|
-
const manifestPath = (0,
|
|
5210
|
-
const before = (0,
|
|
5284
|
+
const manifestPath = (0, import_node_path22.join)(workspaceRoot, relativePath);
|
|
5285
|
+
const before = (0, import_node_fs22.readFileSync)(manifestPath, "utf8");
|
|
5211
5286
|
repairPublishableManifest(manifestPath);
|
|
5212
|
-
const after = (0,
|
|
5287
|
+
const after = (0, import_node_fs22.readFileSync)(manifestPath, "utf8");
|
|
5213
5288
|
if (after !== before) {
|
|
5214
5289
|
changed.push(relativePath.replaceAll("\\", "/"));
|
|
5215
5290
|
}
|
|
@@ -5218,8 +5293,8 @@ function repairPublishableManifests(workspaceRoot) {
|
|
|
5218
5293
|
}
|
|
5219
5294
|
|
|
5220
5295
|
// src/rollup-library/repair-rollup-config.use-case.ts
|
|
5221
|
-
var
|
|
5222
|
-
var
|
|
5296
|
+
var import_node_fs23 = require("fs");
|
|
5297
|
+
var import_node_path23 = require("path");
|
|
5223
5298
|
|
|
5224
5299
|
// src/rollup-library/rollup-config.algorithm.ts
|
|
5225
5300
|
var ROLLUP_CONFIG_PLACEHOLDER = [
|
|
@@ -5437,12 +5512,12 @@ ${DECLARATION_SPECIFIER_PLUGIN},`);
|
|
|
5437
5512
|
// src/rollup-library/repair-rollup-config.use-case.ts
|
|
5438
5513
|
function repairRollupSourceMaps(workspaceRoot) {
|
|
5439
5514
|
const changed = [];
|
|
5440
|
-
const configs = (0,
|
|
5515
|
+
const configs = (0, import_node_fs23.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
|
|
5441
5516
|
cwd: workspaceRoot
|
|
5442
5517
|
});
|
|
5443
5518
|
for (const relativePath of configs) {
|
|
5444
|
-
const configPath = (0,
|
|
5445
|
-
const before = (0,
|
|
5519
|
+
const configPath = (0, import_node_path23.join)(workspaceRoot, relativePath);
|
|
5520
|
+
const before = (0, import_node_fs23.readFileSync)(configPath, "utf8");
|
|
5446
5521
|
const after = withRollupSourceMaps(before);
|
|
5447
5522
|
if (after !== before) {
|
|
5448
5523
|
writeFileEnsured(configPath, after);
|
|
@@ -5453,12 +5528,12 @@ function repairRollupSourceMaps(workspaceRoot) {
|
|
|
5453
5528
|
}
|
|
5454
5529
|
function upgradeDeclarationSpecifierPlugins(workspaceRoot) {
|
|
5455
5530
|
const changed = [];
|
|
5456
|
-
const configs = (0,
|
|
5531
|
+
const configs = (0, import_node_fs23.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
|
|
5457
5532
|
cwd: workspaceRoot
|
|
5458
5533
|
});
|
|
5459
5534
|
for (const relativePath of configs) {
|
|
5460
|
-
const configPath = (0,
|
|
5461
|
-
const before = (0,
|
|
5535
|
+
const configPath = (0, import_node_path23.join)(workspaceRoot, relativePath);
|
|
5536
|
+
const before = (0, import_node_fs23.readFileSync)(configPath, "utf8");
|
|
5462
5537
|
const after = withUpgradedDeclarationSpecifierPlugin(before);
|
|
5463
5538
|
if (after !== before) {
|
|
5464
5539
|
writeFileEnsured(configPath, after);
|
|
@@ -5468,11 +5543,11 @@ function upgradeDeclarationSpecifierPlugins(workspaceRoot) {
|
|
|
5468
5543
|
return changed;
|
|
5469
5544
|
}
|
|
5470
5545
|
function repairDeclarationSpecifiers(projectRoot) {
|
|
5471
|
-
const configPath = (0,
|
|
5546
|
+
const configPath = (0, import_node_path23.join)(projectRoot, "rollup.config.cjs");
|
|
5472
5547
|
if (!fileExists(configPath)) {
|
|
5473
5548
|
return;
|
|
5474
5549
|
}
|
|
5475
|
-
const config = (0,
|
|
5550
|
+
const config = (0, import_node_fs23.readFileSync)(configPath, "utf8");
|
|
5476
5551
|
if (!config.includes(ROLLUP_CONFIG_PLACEHOLDER)) {
|
|
5477
5552
|
const repaired = withRollupSourceMaps(withDeclarationSpecifierPlugin(config));
|
|
5478
5553
|
if (repaired !== config) {
|
|
@@ -5487,12 +5562,12 @@ function repairDeclarationSpecifiers(projectRoot) {
|
|
|
5487
5562
|
}
|
|
5488
5563
|
function addMissingDeclarationSpecifierPlugins(workspaceRoot) {
|
|
5489
5564
|
const changed = [];
|
|
5490
|
-
const configs = (0,
|
|
5565
|
+
const configs = (0, import_node_fs23.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
|
|
5491
5566
|
cwd: workspaceRoot
|
|
5492
5567
|
});
|
|
5493
5568
|
for (const relativePath of configs) {
|
|
5494
|
-
const configPath = (0,
|
|
5495
|
-
const before = (0,
|
|
5569
|
+
const configPath = (0, import_node_path23.join)(workspaceRoot, relativePath);
|
|
5570
|
+
const before = (0, import_node_fs23.readFileSync)(configPath, "utf8");
|
|
5496
5571
|
const after = withDeclarationSpecifierPlugin(before);
|
|
5497
5572
|
if (after !== before) {
|
|
5498
5573
|
writeFileEnsured(configPath, after);
|
|
@@ -5503,10 +5578,10 @@ function addMissingDeclarationSpecifierPlugins(workspaceRoot) {
|
|
|
5503
5578
|
}
|
|
5504
5579
|
|
|
5505
5580
|
// src/rollup-library/rollup-config.repository.ts
|
|
5506
|
-
var
|
|
5507
|
-
var
|
|
5581
|
+
var import_node_fs24 = require("fs");
|
|
5582
|
+
var import_node_path24 = require("path");
|
|
5508
5583
|
function resolveRequireTarget(fromDir, specifier) {
|
|
5509
|
-
const base = (0,
|
|
5584
|
+
const base = (0, import_node_path24.join)(fromDir, specifier);
|
|
5510
5585
|
return [base, `${base}.cjs`, `${base}.js`].find((candidate) => fileExists(candidate));
|
|
5511
5586
|
}
|
|
5512
5587
|
function resolveRollupConfigText(configPath, visited = /* @__PURE__ */ new Set()) {
|
|
@@ -5516,7 +5591,7 @@ function resolveRollupConfigText(configPath, visited = /* @__PURE__ */ new Set()
|
|
|
5516
5591
|
visited.add(configPath);
|
|
5517
5592
|
let text;
|
|
5518
5593
|
try {
|
|
5519
|
-
text = (0,
|
|
5594
|
+
text = (0, import_node_fs24.readFileSync)(configPath, "utf8");
|
|
5520
5595
|
} catch {
|
|
5521
5596
|
return "";
|
|
5522
5597
|
}
|
|
@@ -5524,15 +5599,15 @@ function resolveRollupConfigText(configPath, visited = /* @__PURE__ */ new Set()
|
|
|
5524
5599
|
text.matchAll(/require\((['"])(\.[^'"]*)\1\)/g),
|
|
5525
5600
|
(match) => match[2]
|
|
5526
5601
|
);
|
|
5527
|
-
const requiredText = specifiers.map((specifier) => resolveRequireTarget((0,
|
|
5602
|
+
const requiredText = specifiers.map((specifier) => resolveRequireTarget((0, import_node_path24.dirname)(configPath), specifier)).filter((target) => target !== void 0).map((target) => resolveRollupConfigText(target, visited));
|
|
5528
5603
|
return [text, ...requiredText].join("\n");
|
|
5529
5604
|
}
|
|
5530
5605
|
|
|
5531
5606
|
// src/project-scaffolding/npm-lib.use-case.ts
|
|
5532
5607
|
async function addNpmLib(workspaceRoot, name, options, kindProvided, stack) {
|
|
5533
5608
|
const scope = options.scope ?? (kindProvided ? defaultScope(workspaceRoot) : await promptText("npm scope for the published package", defaultScope(workspaceRoot)));
|
|
5534
|
-
const projectRoot = (0,
|
|
5535
|
-
const manifestPath = (0,
|
|
5609
|
+
const projectRoot = (0, import_node_path25.join)(workspaceRoot, "packages", name);
|
|
5610
|
+
const manifestPath = (0, import_node_path25.join)(projectRoot, "package.json");
|
|
5536
5611
|
runGeneratorAndRepair(
|
|
5537
5612
|
workspaceRoot,
|
|
5538
5613
|
[
|
|
@@ -5565,8 +5640,8 @@ async function addNpmLib(workspaceRoot, name, options, kindProvided, stack) {
|
|
|
5565
5640
|
}
|
|
5566
5641
|
|
|
5567
5642
|
// src/project-scaffolding/python.use-case.ts
|
|
5568
|
-
var
|
|
5569
|
-
var
|
|
5643
|
+
var import_node_fs25 = require("fs");
|
|
5644
|
+
var import_node_path26 = require("path");
|
|
5570
5645
|
function ensurePython(workspaceRoot) {
|
|
5571
5646
|
const hasPython = runShell("python3", ["--version"], workspaceRoot) === 0 || runShell("python", ["--version"], workspaceRoot) === 0;
|
|
5572
5647
|
if (!hasPython) {
|
|
@@ -5589,7 +5664,7 @@ function ensurePythonPipPlugin(workspaceRoot) {
|
|
|
5589
5664
|
registerPythonGraphPlugin(workspaceRoot);
|
|
5590
5665
|
}
|
|
5591
5666
|
function registerPythonGraphPlugin(workspaceRoot) {
|
|
5592
|
-
const nxJsonPath = (0,
|
|
5667
|
+
const nxJsonPath = (0, import_node_path26.join)(workspaceRoot, "nx.json");
|
|
5593
5668
|
if (!fileExists(nxJsonPath)) {
|
|
5594
5669
|
return;
|
|
5595
5670
|
}
|
|
@@ -5612,7 +5687,7 @@ pytest
|
|
|
5612
5687
|
pip-audit
|
|
5613
5688
|
`;
|
|
5614
5689
|
function ensureRequirementsDev(workspaceRoot) {
|
|
5615
|
-
const requirementsDevPath = (0,
|
|
5690
|
+
const requirementsDevPath = (0, import_node_path26.join)(workspaceRoot, "requirements-dev.txt");
|
|
5616
5691
|
if (!fileExists(requirementsDevPath)) {
|
|
5617
5692
|
writeFileEnsured(requirementsDevPath, PYTHON_REQUIREMENTS_DEV);
|
|
5618
5693
|
}
|
|
@@ -5672,8 +5747,8 @@ function addPythonApp(workspaceRoot, name) {
|
|
|
5672
5747
|
["g", "@mnci/nx-python-pip:application", name, `--directory=apps/${name}`, "--no-interactive"],
|
|
5673
5748
|
workspaceRoot
|
|
5674
5749
|
);
|
|
5675
|
-
writeFileEnsured((0,
|
|
5676
|
-
addProjectJsonTargets((0,
|
|
5750
|
+
writeFileEnsured((0, import_node_path26.join)(workspaceRoot, "apps", name, "main.py"), pythonAppMain(name));
|
|
5751
|
+
addProjectJsonTargets((0, import_node_path26.join)(workspaceRoot, "apps", name, "project.json"), {
|
|
5677
5752
|
package: pythonAppPackageTarget(name),
|
|
5678
5753
|
start: pythonAppStartTarget(name)
|
|
5679
5754
|
});
|
|
@@ -5695,7 +5770,7 @@ function addPythonFunctionApp(workspaceRoot, name) {
|
|
|
5695
5770
|
workspaceRoot
|
|
5696
5771
|
);
|
|
5697
5772
|
const moduleDirectory = pythonModuleDirectory(name);
|
|
5698
|
-
addProjectJsonTargets((0,
|
|
5773
|
+
addProjectJsonTargets((0, import_node_path26.join)(workspaceRoot, "apps", name, "project.json"), {
|
|
5699
5774
|
package: pythonFunctionAppPackageTarget(name, moduleDirectory),
|
|
5700
5775
|
start: pythonFunctionAppStartTarget(name)
|
|
5701
5776
|
});
|
|
@@ -5736,7 +5811,7 @@ function addPythonInternalLib(workspaceRoot, name) {
|
|
|
5736
5811
|
var PYTHON_PROJECT_DIRS = ["apps", "python-packages", "libs"];
|
|
5737
5812
|
function findPythonProjectDirectory(workspaceRoot, name) {
|
|
5738
5813
|
return PYTHON_PROJECT_DIRS.find(
|
|
5739
|
-
(directory) => fileExists((0,
|
|
5814
|
+
(directory) => fileExists((0, import_node_path26.join)(workspaceRoot, directory, name, "pyproject.toml"))
|
|
5740
5815
|
);
|
|
5741
5816
|
}
|
|
5742
5817
|
function parseVendorEntries(pyprojectToml) {
|
|
@@ -5775,7 +5850,7 @@ async function addPythonVendor(workspaceRoot, consumer, options, kindProvided) {
|
|
|
5775
5850
|
`No Python project named '${consumer}' with a pyproject.toml found (checked apps/, python-packages/, libs/). A Python function app has no pyproject.toml \u2014 there is nothing to vendor into.`
|
|
5776
5851
|
);
|
|
5777
5852
|
}
|
|
5778
|
-
if (!fileExists((0,
|
|
5853
|
+
if (!fileExists((0, import_node_path26.join)(workspaceRoot, "libs", lib, "pyproject.toml"))) {
|
|
5779
5854
|
throw new Error(
|
|
5780
5855
|
`No internal Python library named '${lib}' found at libs/${lib}/pyproject.toml. Only an internal library (added via 'mnci add python-internal-lib') can be vendored.`
|
|
5781
5856
|
);
|
|
@@ -5783,8 +5858,8 @@ async function addPythonVendor(workspaceRoot, consumer, options, kindProvided) {
|
|
|
5783
5858
|
if (consumerDirectory === "libs" && consumer === lib) {
|
|
5784
5859
|
throw new Error(`'${consumer}' cannot vendor itself.`);
|
|
5785
5860
|
}
|
|
5786
|
-
const pyprojectPath = (0,
|
|
5787
|
-
const pyprojectToml = (0,
|
|
5861
|
+
const pyprojectPath = (0, import_node_path26.join)(workspaceRoot, consumerDirectory, consumer, "pyproject.toml");
|
|
5862
|
+
const pyprojectToml = (0, import_node_fs25.readFileSync)(pyprojectPath, "utf8");
|
|
5788
5863
|
if (parseVendorEntries(pyprojectToml).includes(lib)) {
|
|
5789
5864
|
logger.info(`'${consumer}' already vendors '${lib}' \u2014 nothing to do.`);
|
|
5790
5865
|
return;
|
|
@@ -5795,9 +5870,228 @@ async function addPythonVendor(workspaceRoot, consumer, options, kindProvided) {
|
|
|
5795
5870
|
);
|
|
5796
5871
|
}
|
|
5797
5872
|
|
|
5873
|
+
// src/project-scaffolding/container.use-case.ts
|
|
5874
|
+
var import_node_fs26 = require("fs");
|
|
5875
|
+
var import_node_path27 = require("path");
|
|
5876
|
+
|
|
5877
|
+
// src/project-scaffolding/container-image.algorithm.ts
|
|
5878
|
+
var CONTAINER_TARGETS = ["node-app", "react-app", "go-app"];
|
|
5879
|
+
var NGINX_SPA = `server {
|
|
5880
|
+
listen 80;
|
|
5881
|
+
root /usr/share/nginx/html;
|
|
5882
|
+
index index.html;
|
|
5883
|
+
|
|
5884
|
+
location / {
|
|
5885
|
+
try_files $uri $uri/ /index.html;
|
|
5886
|
+
}
|
|
5887
|
+
}
|
|
5888
|
+
`;
|
|
5889
|
+
function planNode(app, port) {
|
|
5890
|
+
const portLines = port === void 0 ? "" : `ENV HOST=0.0.0.0
|
|
5891
|
+
ENV PORT=${port}
|
|
5892
|
+
EXPOSE ${port}
|
|
5893
|
+
`;
|
|
5894
|
+
return {
|
|
5895
|
+
dockerfile: `# Written by MoNecromanCI. The build context is the app's pruned output (its manifest, lockfile and compiled
|
|
5896
|
+
# code), so the image holds only what the app needs to run.
|
|
5897
|
+
FROM node:24-alpine
|
|
5898
|
+
WORKDIR /app
|
|
5899
|
+
COPY . .
|
|
5900
|
+
RUN npm install --omit=dev --ignore-scripts --no-audit --no-fund
|
|
5901
|
+
ENV NODE_ENV=production
|
|
5902
|
+
${portLines}USER node
|
|
5903
|
+
CMD ["node", "main.js"]
|
|
5904
|
+
`,
|
|
5905
|
+
dockerignore: "node_modules\n",
|
|
5906
|
+
files: {},
|
|
5907
|
+
contextDirectory: `apps/${app}/dist`,
|
|
5908
|
+
dependsOn: "prune",
|
|
5909
|
+
...port !== void 0 && { publish: `${port}:${port}` }
|
|
5910
|
+
};
|
|
5911
|
+
}
|
|
5912
|
+
function planReact(app) {
|
|
5913
|
+
return {
|
|
5914
|
+
dockerfile: `# Written by MoNecromanCI. The build context is the app's production build.
|
|
5915
|
+
FROM nginx:1.27-alpine
|
|
5916
|
+
COPY --from=files default.conf /etc/nginx/conf.d/default.conf
|
|
5917
|
+
COPY . /usr/share/nginx/html
|
|
5918
|
+
EXPOSE 80
|
|
5919
|
+
`,
|
|
5920
|
+
dockerignore: "",
|
|
5921
|
+
files: { "default.conf": NGINX_SPA },
|
|
5922
|
+
contextDirectory: `apps/${app}/dist`,
|
|
5923
|
+
dependsOn: "build",
|
|
5924
|
+
publish: "8080:80"
|
|
5925
|
+
};
|
|
5926
|
+
}
|
|
5927
|
+
function planGo(app, port) {
|
|
5928
|
+
return {
|
|
5929
|
+
dockerfile: `# Written by MoNecromanCI. The build context holds the app's static linux-amd64 binary from build-all.
|
|
5930
|
+
FROM gcr.io/distroless/static-debian12:nonroot
|
|
5931
|
+
COPY ${app} /app
|
|
5932
|
+
${port === void 0 ? "" : `EXPOSE ${port}
|
|
5933
|
+
`}ENTRYPOINT ["/app"]
|
|
5934
|
+
`,
|
|
5935
|
+
dockerignore: "",
|
|
5936
|
+
files: {},
|
|
5937
|
+
contextDirectory: `dist/platforms/${app}/linux-amd64`,
|
|
5938
|
+
dependsOn: "build-all",
|
|
5939
|
+
...port !== void 0 && { publish: `${port}:${port}` }
|
|
5940
|
+
};
|
|
5941
|
+
}
|
|
5942
|
+
function planContainer(target, app, port) {
|
|
5943
|
+
switch (target) {
|
|
5944
|
+
case "node-app": {
|
|
5945
|
+
return planNode(app, port);
|
|
5946
|
+
}
|
|
5947
|
+
case "react-app": {
|
|
5948
|
+
return planReact(app);
|
|
5949
|
+
}
|
|
5950
|
+
case "go-app": {
|
|
5951
|
+
return planGo(app, port);
|
|
5952
|
+
}
|
|
5953
|
+
}
|
|
5954
|
+
}
|
|
5955
|
+
|
|
5956
|
+
// src/project-scaffolding/container.use-case.ts
|
|
5957
|
+
var CONTAINER_TAG = "type:container";
|
|
5958
|
+
var CONTAINER_SCRIPT_PATH = "tools/container-image.cjs";
|
|
5959
|
+
var CONTAINER_SCRIPT = `// Written by MoNecromanCI; \`mnci upgrade\` rewrites it. Builds and runs a container image.
|
|
5960
|
+
// node tools/container-image.cjs build --image <name> --file <Dockerfile> --context <dir> [--files <dir>]
|
|
5961
|
+
// node tools/container-image.cjs start --image <name> [--publish <host:container>]
|
|
5962
|
+
const { spawnSync } = require('node:child_process')
|
|
5963
|
+
const { existsSync } = require('node:fs')
|
|
5964
|
+
|
|
5965
|
+
const [command, ...rest] = process.argv.slice(2)
|
|
5966
|
+
const options = {}
|
|
5967
|
+
for (let index = 0; index < rest.length; index += 2) {
|
|
5968
|
+
options[rest[index].replace(/^--/, '')] = rest[index + 1]
|
|
5969
|
+
}
|
|
5970
|
+
const version = process.env.VERSION || 'dev'
|
|
5971
|
+
|
|
5972
|
+
/** Runs docker with the output shown, and exits with its status. */
|
|
5973
|
+
function docker (args) {
|
|
5974
|
+
const result = spawnSync('docker', args, { stdio: 'inherit' })
|
|
5975
|
+
if (result.error) {
|
|
5976
|
+
console.error('Docker is not available: ' + result.error.message)
|
|
5977
|
+
process.exit(1)
|
|
5978
|
+
}
|
|
5979
|
+
if (result.status !== 0) {
|
|
5980
|
+
process.exit(result.status ?? 1)
|
|
5981
|
+
}
|
|
5982
|
+
}
|
|
5983
|
+
|
|
5984
|
+
if (command === 'build') {
|
|
5985
|
+
const args = ['build', '-f', options.file, '-t', options.image + ':' + version, '-t', options.image + ':latest']
|
|
5986
|
+
if (options.files && existsSync(options.files)) {
|
|
5987
|
+
args.push('--build-context', 'files=' + options.files)
|
|
5988
|
+
}
|
|
5989
|
+
args.push(options.context)
|
|
5990
|
+
docker(args)
|
|
5991
|
+
} else if (command === 'start') {
|
|
5992
|
+
const args = ['run', '--rm', '--init']
|
|
5993
|
+
if (options.publish) {
|
|
5994
|
+
args.push('-p', options.publish)
|
|
5995
|
+
}
|
|
5996
|
+
args.push(options.image + ':latest')
|
|
5997
|
+
docker(args)
|
|
5998
|
+
} else {
|
|
5999
|
+
console.error('usage: container-image.cjs build|start --image <name> ...')
|
|
6000
|
+
process.exit(2)
|
|
6001
|
+
}
|
|
6002
|
+
`;
|
|
6003
|
+
function detectTarget(appRoot) {
|
|
6004
|
+
if (fileExists((0, import_node_path27.join)(appRoot, "go.mod"))) {
|
|
6005
|
+
return fileExists((0, import_node_path27.join)(appRoot, "host.json")) ? void 0 : "go-app";
|
|
6006
|
+
}
|
|
6007
|
+
const manifestPath = (0, import_node_path27.join)(appRoot, "package.json");
|
|
6008
|
+
if (!fileExists(manifestPath) || fileExists((0, import_node_path27.join)(appRoot, "host.json"))) {
|
|
6009
|
+
return void 0;
|
|
6010
|
+
}
|
|
6011
|
+
const manifest = readJson(manifestPath);
|
|
6012
|
+
const declared = Object.keys({ ...manifest.dependencies, ...manifest.devDependencies });
|
|
6013
|
+
if (declared.includes("react") && fileExists((0, import_node_path27.join)(appRoot, "index.html"))) {
|
|
6014
|
+
return "react-app";
|
|
6015
|
+
}
|
|
6016
|
+
return manifest.nx?.targets?.build?.executor === "@nx/esbuild:esbuild" ? "node-app" : void 0;
|
|
6017
|
+
}
|
|
6018
|
+
function containerTargets(name, appProject, plan) {
|
|
6019
|
+
const build = [
|
|
6020
|
+
"node",
|
|
6021
|
+
CONTAINER_SCRIPT_PATH,
|
|
6022
|
+
"build",
|
|
6023
|
+
"--image",
|
|
6024
|
+
name,
|
|
6025
|
+
"--file",
|
|
6026
|
+
`apps/${name}/Dockerfile`,
|
|
6027
|
+
"--context",
|
|
6028
|
+
plan.contextDirectory,
|
|
6029
|
+
"--files",
|
|
6030
|
+
`apps/${name}/files`
|
|
6031
|
+
].join(" ");
|
|
6032
|
+
const start = ["node", CONTAINER_SCRIPT_PATH, "start", "--image", name, ...plan.publish === void 0 ? [] : ["--publish", plan.publish]].join(" ");
|
|
6033
|
+
return {
|
|
6034
|
+
// Not called `build`: CI runs every project's `build`, and building an image needs a Docker engine that
|
|
6035
|
+
// an agent may not have (a Windows agent cannot run Linux images at all).
|
|
6036
|
+
image: { executor: "nx:run-commands", cache: false, dependsOn: [`${appProject}:${plan.dependsOn}`], options: { command: build } },
|
|
6037
|
+
start: { executor: "nx:run-commands", continuous: true, dependsOn: ["image"], options: { command: start } }
|
|
6038
|
+
};
|
|
6039
|
+
}
|
|
6040
|
+
function addContainer(workspaceRoot, name, options) {
|
|
6041
|
+
const appRoot = (0, import_node_path27.join)(workspaceRoot, "apps", options.app);
|
|
6042
|
+
if (!fileExists(appRoot)) {
|
|
6043
|
+
throw new Error(`--app ${options.app}: there is no apps/${options.app} to put in an image. Add the app first.`);
|
|
6044
|
+
}
|
|
6045
|
+
const target = detectTarget(appRoot);
|
|
6046
|
+
if (target === void 0) {
|
|
6047
|
+
throw new Error(`--app ${options.app}: apps/${options.app} is not an app an image is built for (${CONTAINER_TARGETS.join(", ")}). An Azure Functions app has its own host image and is not supported yet.`);
|
|
6048
|
+
}
|
|
6049
|
+
const plan = planContainer(target, options.app, options.port);
|
|
6050
|
+
const appManifestPath = (0, import_node_path27.join)(appRoot, "package.json");
|
|
6051
|
+
const appProject = fileExists(appManifestPath) ? readJson(appManifestPath).name : options.app;
|
|
6052
|
+
const scope = appProject.startsWith("@") ? `${appProject.split("/", 1)[0]}/` : "";
|
|
6053
|
+
const projectRoot = (0, import_node_path27.join)(workspaceRoot, "apps", name);
|
|
6054
|
+
writeFileEnsured((0, import_node_path27.join)(projectRoot, "Dockerfile"), plan.dockerfile);
|
|
6055
|
+
writeFileEnsured((0, import_node_path27.join)(projectRoot, "Dockerfile.dockerignore"), plan.dockerignore);
|
|
6056
|
+
for (const [file, text] of Object.entries(plan.files)) {
|
|
6057
|
+
writeFileEnsured((0, import_node_path27.join)(projectRoot, "files", file), text);
|
|
6058
|
+
}
|
|
6059
|
+
writeFileEnsured((0, import_node_path27.join)(workspaceRoot, CONTAINER_SCRIPT_PATH), CONTAINER_SCRIPT);
|
|
6060
|
+
writeFileEnsured((0, import_node_path27.join)(projectRoot, "package.json"), toJson({
|
|
6061
|
+
name: `${scope}${name}`,
|
|
6062
|
+
version: "0.0.1",
|
|
6063
|
+
private: true,
|
|
6064
|
+
nx: { tags: [CONTAINER_TAG], implicitDependencies: [appProject], targets: containerTargets(name, appProject, plan) }
|
|
6065
|
+
}));
|
|
6066
|
+
registerProjectCommands(workspaceRoot, name, {
|
|
6067
|
+
build: false,
|
|
6068
|
+
start: `nx run ${name}:start`,
|
|
6069
|
+
qa: `nx run ${name}:image`,
|
|
6070
|
+
extra: { image: `nx run ${name}:image` }
|
|
6071
|
+
});
|
|
6072
|
+
}
|
|
6073
|
+
function refreshContainerScript(workspaceRoot) {
|
|
6074
|
+
let entries;
|
|
6075
|
+
try {
|
|
6076
|
+
entries = (0, import_node_fs26.readdirSync)((0, import_node_path27.join)(workspaceRoot, "apps"));
|
|
6077
|
+
} catch {
|
|
6078
|
+
return false;
|
|
6079
|
+
}
|
|
6080
|
+
const hasContainer = entries.some((entry) => {
|
|
6081
|
+
const manifestPath = (0, import_node_path27.join)(workspaceRoot, "apps", entry, "package.json");
|
|
6082
|
+
return fileExists(manifestPath) && (readJson(manifestPath).nx?.tags ?? []).includes(CONTAINER_TAG);
|
|
6083
|
+
});
|
|
6084
|
+
const path = (0, import_node_path27.join)(workspaceRoot, CONTAINER_SCRIPT_PATH);
|
|
6085
|
+
if (!hasContainer || fileExists(path) && (0, import_node_fs26.readFileSync)(path, "utf8") === CONTAINER_SCRIPT) {
|
|
6086
|
+
return false;
|
|
6087
|
+
}
|
|
6088
|
+
writeFileEnsured(path, CONTAINER_SCRIPT);
|
|
6089
|
+
return true;
|
|
6090
|
+
}
|
|
6091
|
+
|
|
5798
6092
|
// src/project-scaffolding/react-app.use-case.ts
|
|
5799
|
-
var
|
|
5800
|
-
var
|
|
6093
|
+
var import_node_fs27 = require("fs");
|
|
6094
|
+
var import_node_path28 = require("path");
|
|
5801
6095
|
|
|
5802
6096
|
// src/project-scaffolding/react-app-example.algorithm.ts
|
|
5803
6097
|
function reactAppExampleFiles(name) {
|
|
@@ -5876,6 +6170,15 @@ describe('App', () => {
|
|
|
5876
6170
|
`
|
|
5877
6171
|
};
|
|
5878
6172
|
}
|
|
6173
|
+
function reactAppE2eSpec(name) {
|
|
6174
|
+
return `import { expect, test } from '@playwright/test'
|
|
6175
|
+
|
|
6176
|
+
test('shows the greeting', async ({ page }) => {
|
|
6177
|
+
await page.goto('/')
|
|
6178
|
+
await expect(page.getByText('Hello, ${name}!')).toBeVisible()
|
|
6179
|
+
})
|
|
6180
|
+
`;
|
|
6181
|
+
}
|
|
5879
6182
|
|
|
5880
6183
|
// src/project-scaffolding/react-app.use-case.ts
|
|
5881
6184
|
var REACT_ENVIRONMENTS = ["dev", "uat", "prod"];
|
|
@@ -5914,12 +6217,12 @@ function reactAppTargets(name) {
|
|
|
5914
6217
|
return targets;
|
|
5915
6218
|
}
|
|
5916
6219
|
function allowEnvFiles(workspaceRoot) {
|
|
5917
|
-
const gitignorePath = (0,
|
|
6220
|
+
const gitignorePath = (0, import_node_path28.join)(workspaceRoot, ".gitignore");
|
|
5918
6221
|
if (!fileExists(gitignorePath)) {
|
|
5919
6222
|
return;
|
|
5920
6223
|
}
|
|
5921
6224
|
const marker = "# MoNecromanCI: keep the committed per-environment Vite config (public VITE_ values)";
|
|
5922
|
-
const current = (0,
|
|
6225
|
+
const current = (0, import_node_fs27.readFileSync)(gitignorePath, "utf8");
|
|
5923
6226
|
if (current.includes(marker)) {
|
|
5924
6227
|
return;
|
|
5925
6228
|
}
|
|
@@ -5929,7 +6232,7 @@ ${marker}
|
|
|
5929
6232
|
${allow}
|
|
5930
6233
|
`);
|
|
5931
6234
|
}
|
|
5932
|
-
function addReactApp(workspaceRoot, name, stack) {
|
|
6235
|
+
function addReactApp(workspaceRoot, name, stack, e2e = false) {
|
|
5933
6236
|
ensurePlugin(workspaceRoot, "@nx/react");
|
|
5934
6237
|
runNx(
|
|
5935
6238
|
[
|
|
@@ -5940,36 +6243,50 @@ function addReactApp(workspaceRoot, name, stack) {
|
|
|
5940
6243
|
`--unitTestRunner=${stack.testRunner}`,
|
|
5941
6244
|
"--linter=none",
|
|
5942
6245
|
"--style=css",
|
|
5943
|
-
"
|
|
6246
|
+
`--e2eTestRunner=${e2e ? "playwright" : "none"}`,
|
|
5944
6247
|
"--no-interactive"
|
|
5945
6248
|
],
|
|
5946
6249
|
workspaceRoot
|
|
5947
6250
|
);
|
|
5948
6251
|
ensureAdmZip(workspaceRoot);
|
|
5949
|
-
const reactAppRoot = (0,
|
|
6252
|
+
const reactAppRoot = (0, import_node_path28.join)(workspaceRoot, "apps", name);
|
|
5950
6253
|
for (const environment of REACT_ENVIRONMENTS) {
|
|
5951
|
-
writeFileEnsured((0,
|
|
6254
|
+
writeFileEnsured((0, import_node_path28.join)(reactAppRoot, `.env.${environment}`), reactEnvironmentFile(environment));
|
|
5952
6255
|
}
|
|
5953
6256
|
allowEnvFiles(workspaceRoot);
|
|
5954
|
-
addNxTargets((0,
|
|
6257
|
+
addNxTargets((0, import_node_path28.join)(reactAppRoot, "package.json"), reactAppTargets(name));
|
|
5955
6258
|
reshapeReactAppScaffold(reactAppRoot);
|
|
5956
|
-
(0,
|
|
6259
|
+
(0, import_node_fs27.rmSync)((0, import_node_path28.join)(reactAppRoot, "src/app/nx-welcome.component.tsx"), { force: true });
|
|
5957
6260
|
const example = reactAppExampleFiles(name);
|
|
5958
6261
|
for (const [relative, contents] of Object.entries(example)) {
|
|
5959
|
-
writeFileEnsured((0,
|
|
6262
|
+
writeFileEnsured((0, import_node_path28.join)(reactAppRoot, "src", relative), contents);
|
|
5960
6263
|
}
|
|
5961
6264
|
removeGeneratedEslintConfig(workspaceRoot, `apps/${name}`);
|
|
5962
6265
|
registerProjectCommands(workspaceRoot, name, { build: true, start: `nx run ${name}:serve` });
|
|
6266
|
+
if (e2e) {
|
|
6267
|
+
pairE2eProject(workspaceRoot, name);
|
|
6268
|
+
}
|
|
6269
|
+
}
|
|
6270
|
+
function pairE2eProject(workspaceRoot, name) {
|
|
6271
|
+
const e2eName = `${name}-e2e`;
|
|
6272
|
+
const e2eRoot = (0, import_node_path28.join)(workspaceRoot, "apps", e2eName);
|
|
6273
|
+
(0, import_node_fs27.rmSync)((0, import_node_path28.join)(e2eRoot, "src/example.spec.ts"), { force: true });
|
|
6274
|
+
writeFileEnsured((0, import_node_path28.join)(e2eRoot, "src/greeting.e2e.spec.ts"), reactAppE2eSpec(name));
|
|
6275
|
+
removeGeneratedEslintConfig(workspaceRoot, `apps/${e2eName}`);
|
|
6276
|
+
registerProjectCommands(workspaceRoot, e2eName, {
|
|
6277
|
+
build: false,
|
|
6278
|
+
qa: `nx run ${e2eName}:lint && nx run ${e2eName}:typecheck`
|
|
6279
|
+
});
|
|
5963
6280
|
}
|
|
5964
6281
|
|
|
5965
6282
|
// src/project-scaffolding/react-lib.use-case.ts
|
|
5966
|
-
var
|
|
6283
|
+
var import_node_path29 = require("path");
|
|
5967
6284
|
var REACT_LIB_BUNDLER = "rollup";
|
|
5968
6285
|
async function addReactLib(workspaceRoot, name, options, kindProvided, stack) {
|
|
5969
6286
|
ensurePlugin(workspaceRoot, "@nx/react");
|
|
5970
6287
|
const scope = options.scope ?? (kindProvided ? defaultScope(workspaceRoot) : await promptText("npm scope for the published package", defaultScope(workspaceRoot)));
|
|
5971
|
-
const projectRoot = (0,
|
|
5972
|
-
const publishableManifest = (0,
|
|
6288
|
+
const projectRoot = (0, import_node_path29.join)(workspaceRoot, "packages", name);
|
|
6289
|
+
const publishableManifest = (0, import_node_path29.join)(projectRoot, "package.json");
|
|
5973
6290
|
runGeneratorAndRepair(
|
|
5974
6291
|
workspaceRoot,
|
|
5975
6292
|
[
|
|
@@ -6013,8 +6330,8 @@ function dropNxProjectName(manifestPath) {
|
|
|
6013
6330
|
}
|
|
6014
6331
|
function addReactInternalLib(workspaceRoot, name, stack, empty = false) {
|
|
6015
6332
|
ensurePlugin(workspaceRoot, "@nx/react");
|
|
6016
|
-
const projectRoot = (0,
|
|
6017
|
-
const privateManifest = (0,
|
|
6333
|
+
const projectRoot = (0, import_node_path29.join)(workspaceRoot, "libs", name);
|
|
6334
|
+
const privateManifest = (0, import_node_path29.join)(projectRoot, "package.json");
|
|
6018
6335
|
runGeneratorAndRepair(
|
|
6019
6336
|
workspaceRoot,
|
|
6020
6337
|
[
|
|
@@ -6041,8 +6358,8 @@ function addReactInternalLib(workspaceRoot, name, stack, empty = false) {
|
|
|
6041
6358
|
}
|
|
6042
6359
|
|
|
6043
6360
|
// src/project-scaffolding/vscode-extension.use-case.ts
|
|
6044
|
-
var
|
|
6045
|
-
var
|
|
6361
|
+
var import_node_fs28 = require("fs");
|
|
6362
|
+
var import_node_path30 = require("path");
|
|
6046
6363
|
var VSCODE_EXTENSION_SCRIPT_PATH = "tools/vscode-extension.cjs";
|
|
6047
6364
|
var VSCODE_ENGINE_FLOOR = "1.96.0";
|
|
6048
6365
|
var VSCODE_SIDECAR_TARGETS = {
|
|
@@ -6227,8 +6544,8 @@ export const window = {
|
|
|
6227
6544
|
var VSCODE_STUB_PATH = "test/vscode.stub.ts";
|
|
6228
6545
|
function mapVscodeToStub(projectRoot, testRunner) {
|
|
6229
6546
|
const [file, anchor, mapping] = testRunner === "jest" ? ["jest.config.cts", "testEnvironment: 'node',", `moduleNameMapper: { '^vscode$': '<rootDir>/${VSCODE_STUB_PATH}' },`] : ["vitest.config.mts", "environment: 'node',", `alias: { vscode: \`\${import.meta.dirname}/${VSCODE_STUB_PATH}\` },`];
|
|
6230
|
-
const path = (0,
|
|
6231
|
-
const content = fileExists(path) ? (0,
|
|
6547
|
+
const path = (0, import_node_path30.join)(projectRoot, file);
|
|
6548
|
+
const content = fileExists(path) ? (0, import_node_fs28.readFileSync)(path, "utf8") : "";
|
|
6232
6549
|
const line = content.split("\n").find((candidate) => candidate.trim() === anchor);
|
|
6233
6550
|
if (line === void 0) {
|
|
6234
6551
|
throw new Error(`${file} has no "${anchor}" line to map the vscode module after; map 'vscode' to ${VSCODE_STUB_PATH} by hand.`);
|
|
@@ -6248,11 +6565,11 @@ function ensureVscodeToolchain(workspaceRoot) {
|
|
|
6248
6565
|
}
|
|
6249
6566
|
}
|
|
6250
6567
|
function defaultPublisher(workspaceRoot) {
|
|
6251
|
-
const { name } = readJson((0,
|
|
6568
|
+
const { name } = readJson((0, import_node_path30.join)(workspaceRoot, "package.json"));
|
|
6252
6569
|
return (name ?? "publisher").replace(/^@/, "").split("/", 1)[0];
|
|
6253
6570
|
}
|
|
6254
6571
|
function reshapeManifest(projectRoot, name, publisher) {
|
|
6255
|
-
const manifestPath = (0,
|
|
6572
|
+
const manifestPath = (0, import_node_path30.join)(projectRoot, "package.json");
|
|
6256
6573
|
const manifest = readJson(manifestPath);
|
|
6257
6574
|
const { nx = {}, ...rest } = manifest;
|
|
6258
6575
|
const targets = { ...nx.targets };
|
|
@@ -6316,11 +6633,11 @@ function vscodeExtensionPublishTarget(name, sidecar) {
|
|
|
6316
6633
|
};
|
|
6317
6634
|
}
|
|
6318
6635
|
function addDebugLaunch(workspaceRoot, name) {
|
|
6319
|
-
const file = (0,
|
|
6636
|
+
const file = (0, import_node_fs28.readdirSync)(workspaceRoot).find((entry) => entry.endsWith(".code-workspace"));
|
|
6320
6637
|
if (file === void 0) {
|
|
6321
6638
|
return;
|
|
6322
6639
|
}
|
|
6323
|
-
const path = (0,
|
|
6640
|
+
const path = (0, import_node_path30.join)(workspaceRoot, file);
|
|
6324
6641
|
const workspace = readCodeWorkspace(path) ?? {};
|
|
6325
6642
|
const folder = `\${workspaceFolder:${workspace.folders?.[0]?.name ?? file.replace(/\.code-workspace$/, "")}}`;
|
|
6326
6643
|
const taskLabel = `${name}: build (development)`;
|
|
@@ -6353,39 +6670,39 @@ function addDebugLaunch(workspaceRoot, name) {
|
|
|
6353
6670
|
);
|
|
6354
6671
|
}
|
|
6355
6672
|
function refreshVscodeExtensionScript(workspaceRoot) {
|
|
6356
|
-
const apps = (0,
|
|
6673
|
+
const apps = (0, import_node_path30.join)(workspaceRoot, "apps");
|
|
6357
6674
|
let entries;
|
|
6358
6675
|
try {
|
|
6359
|
-
entries = (0,
|
|
6676
|
+
entries = (0, import_node_fs28.readdirSync)(apps);
|
|
6360
6677
|
} catch {
|
|
6361
6678
|
return false;
|
|
6362
6679
|
}
|
|
6363
6680
|
const hasExtension = entries.some((entry) => {
|
|
6364
|
-
const manifestPath = (0,
|
|
6681
|
+
const manifestPath = (0, import_node_path30.join)(apps, entry, "package.json");
|
|
6365
6682
|
if (!fileExists(manifestPath)) {
|
|
6366
6683
|
return false;
|
|
6367
6684
|
}
|
|
6368
6685
|
const tags = readJson(manifestPath).nx?.tags ?? [];
|
|
6369
6686
|
return tags.includes(VSCODE_EXTENSION_TAG);
|
|
6370
6687
|
});
|
|
6371
|
-
const path = (0,
|
|
6372
|
-
if (!hasExtension || fileExists(path) && (0,
|
|
6688
|
+
const path = (0, import_node_path30.join)(workspaceRoot, VSCODE_EXTENSION_SCRIPT_PATH);
|
|
6689
|
+
if (!hasExtension || fileExists(path) && (0, import_node_fs28.readFileSync)(path, "utf8") === VSCODE_EXTENSION_SCRIPT) {
|
|
6373
6690
|
return false;
|
|
6374
6691
|
}
|
|
6375
6692
|
writeFileEnsured(path, VSCODE_EXTENSION_SCRIPT);
|
|
6376
6693
|
return true;
|
|
6377
6694
|
}
|
|
6378
6695
|
function pinVscodeExtensionProjectNames(workspaceRoot) {
|
|
6379
|
-
const apps = (0,
|
|
6696
|
+
const apps = (0, import_node_path30.join)(workspaceRoot, "apps");
|
|
6380
6697
|
let entries;
|
|
6381
6698
|
try {
|
|
6382
|
-
entries = (0,
|
|
6699
|
+
entries = (0, import_node_fs28.readdirSync)(apps);
|
|
6383
6700
|
} catch {
|
|
6384
6701
|
return [];
|
|
6385
6702
|
}
|
|
6386
6703
|
const updated = [];
|
|
6387
6704
|
for (const entry of entries) {
|
|
6388
|
-
const manifestPath = (0,
|
|
6705
|
+
const manifestPath = (0, import_node_path30.join)(apps, entry, "package.json");
|
|
6389
6706
|
if (!fileExists(manifestPath)) {
|
|
6390
6707
|
continue;
|
|
6391
6708
|
}
|
|
@@ -6405,22 +6722,22 @@ function refreshLockFile(workspaceRoot, name) {
|
|
|
6405
6722
|
}
|
|
6406
6723
|
function addVscodeExtension(workspaceRoot, name, stack, options = {}) {
|
|
6407
6724
|
const { sidecar } = options;
|
|
6408
|
-
if (sidecar !== void 0 && !fileExists((0,
|
|
6725
|
+
if (sidecar !== void 0 && !fileExists((0, import_node_path30.join)(workspaceRoot, "apps", sidecar, "project.json"))) {
|
|
6409
6726
|
throw new Error(`--sidecar ${sidecar}: no Go app at apps/${sidecar}. Add it first with \`mnci add go-app ${sidecar}\`.`);
|
|
6410
6727
|
}
|
|
6411
6728
|
runNodeApp(workspaceRoot, name, stack, "none");
|
|
6412
6729
|
ensureVscodeToolchain(workspaceRoot);
|
|
6413
|
-
const projectRoot = (0,
|
|
6730
|
+
const projectRoot = (0, import_node_path30.join)(workspaceRoot, "apps", name);
|
|
6414
6731
|
reshapeManifest(projectRoot, name, options.publisher ?? defaultPublisher(workspaceRoot));
|
|
6415
|
-
addVscodeTypes((0,
|
|
6416
|
-
addVscodeTypes((0,
|
|
6417
|
-
writeFileEnsured((0,
|
|
6418
|
-
writeFileEnsured((0,
|
|
6419
|
-
writeFileEnsured((0,
|
|
6732
|
+
addVscodeTypes((0, import_node_path30.join)(projectRoot, "tsconfig.app.json"));
|
|
6733
|
+
addVscodeTypes((0, import_node_path30.join)(projectRoot, "tsconfig.spec.json"));
|
|
6734
|
+
writeFileEnsured((0, import_node_path30.join)(projectRoot, "src/main.ts"), vscodeExtensionMain(name));
|
|
6735
|
+
writeFileEnsured((0, import_node_path30.join)(projectRoot, "src/main.spec.ts"), vscodeExtensionMainSpec(name));
|
|
6736
|
+
writeFileEnsured((0, import_node_path30.join)(projectRoot, VSCODE_STUB_PATH), VSCODE_STUB);
|
|
6420
6737
|
mapVscodeToStub(projectRoot, stack.testRunner);
|
|
6421
|
-
writeFileEnsured((0,
|
|
6422
|
-
writeFileEnsured((0,
|
|
6423
|
-
addNxTargets((0,
|
|
6738
|
+
writeFileEnsured((0, import_node_path30.join)(projectRoot, ".vscodeignore"), VSCODE_IGNORE);
|
|
6739
|
+
writeFileEnsured((0, import_node_path30.join)(workspaceRoot, VSCODE_EXTENSION_SCRIPT_PATH), VSCODE_EXTENSION_SCRIPT);
|
|
6740
|
+
addNxTargets((0, import_node_path30.join)(projectRoot, "package.json"), {
|
|
6424
6741
|
"package": vscodeExtensionPackageTarget(name, sidecar),
|
|
6425
6742
|
"nx-release-publish": vscodeExtensionPublishTarget(name, sidecar)
|
|
6426
6743
|
});
|
|
@@ -6431,12 +6748,12 @@ function addVscodeExtension(workspaceRoot, name, stack, options = {}) {
|
|
|
6431
6748
|
}
|
|
6432
6749
|
|
|
6433
6750
|
// src/dependency-management/install-dependencies.use-case.ts
|
|
6434
|
-
var
|
|
6435
|
-
var
|
|
6751
|
+
var import_node_fs30 = require("fs");
|
|
6752
|
+
var import_node_path32 = require("path");
|
|
6436
6753
|
|
|
6437
6754
|
// src/dependency-management/manifest.repository.ts
|
|
6438
|
-
var
|
|
6439
|
-
var
|
|
6755
|
+
var import_node_fs29 = require("fs");
|
|
6756
|
+
var import_node_path31 = require("path");
|
|
6440
6757
|
var ECOSYSTEMS = ["npm", "pip", "pub", "nuget", "go"];
|
|
6441
6758
|
var ROOT_LABEL = "(root)";
|
|
6442
6759
|
var MANIFEST_GLOBS = {
|
|
@@ -6469,23 +6786,23 @@ function projectOf(manifestRelativePath) {
|
|
|
6469
6786
|
}
|
|
6470
6787
|
function hasEcosystem(workspaceRoot, ecosystem) {
|
|
6471
6788
|
if (ecosystem === "go") {
|
|
6472
|
-
return fileExists((0,
|
|
6789
|
+
return fileExists((0, import_node_path31.join)(workspaceRoot, "go.mod"));
|
|
6473
6790
|
}
|
|
6474
6791
|
if (ecosystem === "nuget") {
|
|
6475
|
-
return (0,
|
|
6792
|
+
return (0, import_node_fs29.globSync)(MANIFEST_GLOBS.nuget, { cwd: workspaceRoot }).length > 0;
|
|
6476
6793
|
}
|
|
6477
6794
|
const rootMarker = {
|
|
6478
6795
|
npm: "package.json",
|
|
6479
6796
|
pip: "requirements-dev.txt",
|
|
6480
6797
|
pub: "pubspec.yaml"
|
|
6481
6798
|
};
|
|
6482
|
-
return fileExists((0,
|
|
6799
|
+
return fileExists((0, import_node_path31.join)(workspaceRoot, rootMarker[ecosystem])) || (0, import_node_fs29.globSync)(MANIFEST_GLOBS[ecosystem], { cwd: workspaceRoot }).length > 0;
|
|
6483
6800
|
}
|
|
6484
6801
|
function collectNpm(workspaceRoot) {
|
|
6485
6802
|
const sites = [];
|
|
6486
|
-
const relativePaths = ["package.json", ...(0,
|
|
6803
|
+
const relativePaths = ["package.json", ...(0, import_node_fs29.globSync)(MANIFEST_GLOBS.npm, { cwd: workspaceRoot })];
|
|
6487
6804
|
for (const relativePath of relativePaths) {
|
|
6488
|
-
const manifestPath = (0,
|
|
6805
|
+
const manifestPath = (0, import_node_path31.join)(workspaceRoot, relativePath);
|
|
6489
6806
|
try {
|
|
6490
6807
|
const manifest = readJson(manifestPath);
|
|
6491
6808
|
sites.push(...npmManifestSites(manifest, relativePath, manifestPath));
|
|
@@ -6546,17 +6863,17 @@ function collectPip(workspaceRoot) {
|
|
|
6546
6863
|
name: parsed.name,
|
|
6547
6864
|
ecosystem: "pip",
|
|
6548
6865
|
project: projectOf(relativePath),
|
|
6549
|
-
manifestPath: (0,
|
|
6866
|
+
manifestPath: (0, import_node_path31.join)(workspaceRoot, relativePath),
|
|
6550
6867
|
section,
|
|
6551
6868
|
spec: parsed.spec,
|
|
6552
6869
|
rewritable: parsed.rewritable && parsed.spec !== ""
|
|
6553
6870
|
});
|
|
6554
6871
|
};
|
|
6555
|
-
const pyprojectPaths = (0,
|
|
6872
|
+
const pyprojectPaths = (0, import_node_fs29.globSync)(MANIFEST_GLOBS.pip, { cwd: workspaceRoot });
|
|
6556
6873
|
for (const relativePath of pyprojectPaths) {
|
|
6557
6874
|
let content;
|
|
6558
6875
|
try {
|
|
6559
|
-
content = (0,
|
|
6876
|
+
content = (0, import_node_fs29.readFileSync)((0, import_node_path31.join)(workspaceRoot, relativePath), "utf8");
|
|
6560
6877
|
} catch {
|
|
6561
6878
|
continue;
|
|
6562
6879
|
}
|
|
@@ -6567,14 +6884,14 @@ function collectPip(workspaceRoot) {
|
|
|
6567
6884
|
}
|
|
6568
6885
|
const requirementsPaths = [
|
|
6569
6886
|
"requirements-dev.txt",
|
|
6570
|
-
...(0,
|
|
6887
|
+
...(0, import_node_fs29.globSync)("apps/*/requirements.txt", { cwd: workspaceRoot })
|
|
6571
6888
|
];
|
|
6572
6889
|
for (const relativePath of requirementsPaths) {
|
|
6573
|
-
if (!fileExists((0,
|
|
6890
|
+
if (!fileExists((0, import_node_path31.join)(workspaceRoot, relativePath))) {
|
|
6574
6891
|
continue;
|
|
6575
6892
|
}
|
|
6576
6893
|
const section = relativePath === "requirements-dev.txt" ? "devDep" : "dep";
|
|
6577
|
-
const lines = (0,
|
|
6894
|
+
const lines = (0, import_node_fs29.readFileSync)((0, import_node_path31.join)(workspaceRoot, relativePath), "utf8").split(/\r?\n/);
|
|
6578
6895
|
for (const line of lines) {
|
|
6579
6896
|
push(relativePath, section, line);
|
|
6580
6897
|
}
|
|
@@ -6612,11 +6929,11 @@ function pyprojectDependencies(content) {
|
|
|
6612
6929
|
}
|
|
6613
6930
|
function collectPub(workspaceRoot) {
|
|
6614
6931
|
const sites = [];
|
|
6615
|
-
const pubspecPaths = (0,
|
|
6932
|
+
const pubspecPaths = (0, import_node_fs29.globSync)(MANIFEST_GLOBS.pub, { cwd: workspaceRoot });
|
|
6616
6933
|
for (const relativePath of pubspecPaths) {
|
|
6617
6934
|
let content;
|
|
6618
6935
|
try {
|
|
6619
|
-
content = (0,
|
|
6936
|
+
content = (0, import_node_fs29.readFileSync)((0, import_node_path31.join)(workspaceRoot, relativePath), "utf8");
|
|
6620
6937
|
} catch {
|
|
6621
6938
|
continue;
|
|
6622
6939
|
}
|
|
@@ -6626,7 +6943,7 @@ function collectPub(workspaceRoot) {
|
|
|
6626
6943
|
name: entry.name,
|
|
6627
6944
|
ecosystem: "pub",
|
|
6628
6945
|
project: projectOf(relativePath),
|
|
6629
|
-
manifestPath: (0,
|
|
6946
|
+
manifestPath: (0, import_node_path31.join)(workspaceRoot, relativePath),
|
|
6630
6947
|
section: block === "dependencies" ? "dep" : "devDep",
|
|
6631
6948
|
spec: entry.spec,
|
|
6632
6949
|
rewritable: entry.spec !== ""
|
|
@@ -6676,11 +6993,11 @@ function stripQuotes(value) {
|
|
|
6676
6993
|
}
|
|
6677
6994
|
function collectNuget(workspaceRoot) {
|
|
6678
6995
|
const sites = [];
|
|
6679
|
-
const csprojPaths = (0,
|
|
6996
|
+
const csprojPaths = (0, import_node_fs29.globSync)(MANIFEST_GLOBS.nuget, { cwd: workspaceRoot });
|
|
6680
6997
|
for (const relativePath of csprojPaths) {
|
|
6681
6998
|
let content;
|
|
6682
6999
|
try {
|
|
6683
|
-
content = (0,
|
|
7000
|
+
content = (0, import_node_fs29.readFileSync)((0, import_node_path31.join)(workspaceRoot, relativePath), "utf8");
|
|
6684
7001
|
} catch {
|
|
6685
7002
|
continue;
|
|
6686
7003
|
}
|
|
@@ -6689,7 +7006,7 @@ function collectNuget(workspaceRoot) {
|
|
|
6689
7006
|
name: entry.name,
|
|
6690
7007
|
ecosystem: "nuget",
|
|
6691
7008
|
project: projectOf(relativePath),
|
|
6692
|
-
manifestPath: (0,
|
|
7009
|
+
manifestPath: (0, import_node_path31.join)(workspaceRoot, relativePath),
|
|
6693
7010
|
section: "dep",
|
|
6694
7011
|
spec: entry.spec,
|
|
6695
7012
|
// A plain SemVer string is rewritable; an MSBuild property reference
|
|
@@ -6714,13 +7031,13 @@ function csprojPackageReferences(content) {
|
|
|
6714
7031
|
return entries;
|
|
6715
7032
|
}
|
|
6716
7033
|
function collectGo(workspaceRoot) {
|
|
6717
|
-
const manifestPath = (0,
|
|
7034
|
+
const manifestPath = (0, import_node_path31.join)(workspaceRoot, "go.mod");
|
|
6718
7035
|
if (!fileExists(manifestPath)) {
|
|
6719
7036
|
return [];
|
|
6720
7037
|
}
|
|
6721
7038
|
let content;
|
|
6722
7039
|
try {
|
|
6723
|
-
content = (0,
|
|
7040
|
+
content = (0, import_node_fs29.readFileSync)(manifestPath, "utf8");
|
|
6724
7041
|
} catch {
|
|
6725
7042
|
return [];
|
|
6726
7043
|
}
|
|
@@ -6769,7 +7086,7 @@ var PROJECT_GLOBS = {
|
|
|
6769
7086
|
function locateProjects(workspaceRoot) {
|
|
6770
7087
|
const locations = [];
|
|
6771
7088
|
for (const ecosystem of ECOSYSTEMS) {
|
|
6772
|
-
const relativePaths = (0,
|
|
7089
|
+
const relativePaths = (0, import_node_fs29.globSync)(PROJECT_GLOBS[ecosystem], { cwd: workspaceRoot });
|
|
6773
7090
|
for (const relativePath of relativePaths) {
|
|
6774
7091
|
const posix = toPosix(relativePath);
|
|
6775
7092
|
const dir = posix.slice(0, posix.lastIndexOf("/"));
|
|
@@ -6777,7 +7094,7 @@ function locateProjects(workspaceRoot) {
|
|
|
6777
7094
|
ecosystem,
|
|
6778
7095
|
dir,
|
|
6779
7096
|
name: dir.slice(dir.lastIndexOf("/") + 1),
|
|
6780
|
-
manifestPath: (0,
|
|
7097
|
+
manifestPath: (0, import_node_path31.join)(workspaceRoot, relativePath)
|
|
6781
7098
|
});
|
|
6782
7099
|
}
|
|
6783
7100
|
}
|
|
@@ -6798,7 +7115,7 @@ function rewriteSpec(site, spec) {
|
|
|
6798
7115
|
writeFileEnsured(site.manifestPath, toJson(manifest));
|
|
6799
7116
|
return true;
|
|
6800
7117
|
}
|
|
6801
|
-
const before = (0,
|
|
7118
|
+
const before = (0, import_node_fs29.readFileSync)(site.manifestPath, "utf8");
|
|
6802
7119
|
const after = (() => {
|
|
6803
7120
|
switch (site.ecosystem) {
|
|
6804
7121
|
case "pip": {
|
|
@@ -6889,13 +7206,13 @@ function escapeForRegex(value) {
|
|
|
6889
7206
|
function isWorkspaceProject(workspaceRoot, name) {
|
|
6890
7207
|
const short = name.includes("/") ? name.split("/").at(-1) : name;
|
|
6891
7208
|
return ["apps", "libs", "packages"].some(
|
|
6892
|
-
(directory) => fileExists((0,
|
|
7209
|
+
(directory) => fileExists((0, import_node_path31.join)(workspaceRoot, directory, short ?? name, "package.json"))
|
|
6893
7210
|
);
|
|
6894
7211
|
}
|
|
6895
7212
|
function isAliasedInstall(workspaceRoot, name) {
|
|
6896
7213
|
try {
|
|
6897
7214
|
const installed = readJson(
|
|
6898
|
-
(0,
|
|
7215
|
+
(0, import_node_path31.join)(workspaceRoot, "node_modules", name, "package.json")
|
|
6899
7216
|
);
|
|
6900
7217
|
return installed.name !== void 0 && installed.name !== name;
|
|
6901
7218
|
} catch {
|
|
@@ -6906,14 +7223,14 @@ function resolvedVersion(workspaceRoot, ecosystem, name) {
|
|
|
6906
7223
|
if (ecosystem === "npm") {
|
|
6907
7224
|
try {
|
|
6908
7225
|
return readJson(
|
|
6909
|
-
(0,
|
|
7226
|
+
(0, import_node_path31.join)(workspaceRoot, "node_modules", name, "package.json")
|
|
6910
7227
|
).version;
|
|
6911
7228
|
} catch {
|
|
6912
7229
|
return void 0;
|
|
6913
7230
|
}
|
|
6914
7231
|
}
|
|
6915
7232
|
if (ecosystem === "pub") {
|
|
6916
|
-
const lockPath = (0,
|
|
7233
|
+
const lockPath = (0, import_node_path31.join)(workspaceRoot, "pubspec.lock");
|
|
6917
7234
|
if (!fileExists(lockPath)) {
|
|
6918
7235
|
return void 0;
|
|
6919
7236
|
}
|
|
@@ -6921,7 +7238,7 @@ function resolvedVersion(workspaceRoot, ecosystem, name) {
|
|
|
6921
7238
|
const match = new RegExp(
|
|
6922
7239
|
String.raw`^\s{2}${escapeForRegex(name)}:[^]*?^\s+version:\s*["']?([^"'\s]+)`,
|
|
6923
7240
|
"m"
|
|
6924
|
-
).exec((0,
|
|
7241
|
+
).exec((0, import_node_fs29.readFileSync)(lockPath, "utf8"));
|
|
6925
7242
|
return match?.[1];
|
|
6926
7243
|
} catch {
|
|
6927
7244
|
return void 0;
|
|
@@ -6987,7 +7304,7 @@ function resolveTarget(locations, target) {
|
|
|
6987
7304
|
return byName[0];
|
|
6988
7305
|
}
|
|
6989
7306
|
function installInto(workspaceRoot, location, packages, saveDev) {
|
|
6990
|
-
const projectDir = (0,
|
|
7307
|
+
const projectDir = (0, import_node_path32.join)(workspaceRoot, location.dir);
|
|
6991
7308
|
switch (location.ecosystem) {
|
|
6992
7309
|
case "npm": {
|
|
6993
7310
|
const flags = saveDev ? ["--save-dev"] : [];
|
|
@@ -7040,7 +7357,7 @@ function installInto(workspaceRoot, location, packages, saveDev) {
|
|
|
7040
7357
|
function addPythonDependency(manifestPath, specifier) {
|
|
7041
7358
|
let content;
|
|
7042
7359
|
try {
|
|
7043
|
-
content = (0,
|
|
7360
|
+
content = (0, import_node_fs30.readFileSync)(manifestPath, "utf8");
|
|
7044
7361
|
} catch {
|
|
7045
7362
|
logger.warn(`Could not read ${manifestPath} \u2014 skipped ${specifier}`);
|
|
7046
7363
|
return;
|
|
@@ -7069,7 +7386,7 @@ function installEverything(workspaceRoot, only) {
|
|
|
7069
7386
|
}
|
|
7070
7387
|
function ecosystemPresent(workspaceRoot, ecosystem) {
|
|
7071
7388
|
if (ecosystem === "go") {
|
|
7072
|
-
return fileExists((0,
|
|
7389
|
+
return fileExists((0, import_node_path32.join)(workspaceRoot, "go.work")) || fileExists((0, import_node_path32.join)(workspaceRoot, "go.mod"));
|
|
7073
7390
|
}
|
|
7074
7391
|
return hasEcosystem(workspaceRoot, ecosystem);
|
|
7075
7392
|
}
|
|
@@ -7088,7 +7405,7 @@ function splitAtLast(value, separator) {
|
|
|
7088
7405
|
}
|
|
7089
7406
|
|
|
7090
7407
|
// src/dependency-management/sync-dependencies.use-case.ts
|
|
7091
|
-
var
|
|
7408
|
+
var import_node_path33 = require("path");
|
|
7092
7409
|
|
|
7093
7410
|
// src/dependency-management/semver.algorithm.ts
|
|
7094
7411
|
var UPDATE_KINDS = ["patch", "minor", "major", "non-semver"];
|
|
@@ -7265,7 +7582,7 @@ function describe(finding) {
|
|
|
7265
7582
|
return `${finding.name} \u2192 ${finding.target} (${finding.reason}); disagreeing: ${sites}`;
|
|
7266
7583
|
}
|
|
7267
7584
|
function runSync(workspaceRoot, options) {
|
|
7268
|
-
if (!fileExists((0,
|
|
7585
|
+
if (!fileExists((0, import_node_path33.join)(workspaceRoot, "nx.json"))) {
|
|
7269
7586
|
throw new Error(
|
|
7270
7587
|
`No nx.json found in ${workspaceRoot} \u2014 run 'mnci sync' from the workspace root.`
|
|
7271
7588
|
);
|
|
@@ -7315,7 +7632,7 @@ function runSync(workspaceRoot, options) {
|
|
|
7315
7632
|
}
|
|
7316
7633
|
|
|
7317
7634
|
// src/dependency-management/update-dependencies.use-case.ts
|
|
7318
|
-
var
|
|
7635
|
+
var import_node_path34 = require("path");
|
|
7319
7636
|
var import_prompts2 = require("@inquirer/prompts");
|
|
7320
7637
|
|
|
7321
7638
|
// src/dependency-management/registry.client.ts
|
|
@@ -7598,7 +7915,7 @@ function reinstall(workspaceRoot, ecosystems) {
|
|
|
7598
7915
|
function hasPythonInstallScript(workspaceRoot) {
|
|
7599
7916
|
try {
|
|
7600
7917
|
const manifest = readJson(
|
|
7601
|
-
(0,
|
|
7918
|
+
(0, import_node_path34.join)(workspaceRoot, "package.json")
|
|
7602
7919
|
);
|
|
7603
7920
|
return manifest.scripts?.["python:install"] !== void 0;
|
|
7604
7921
|
} catch {
|
|
@@ -7614,7 +7931,7 @@ function applyGoUpdates(workspaceRoot, entries) {
|
|
|
7614
7931
|
}
|
|
7615
7932
|
}
|
|
7616
7933
|
async function runUp(workspaceRoot, options) {
|
|
7617
|
-
if (!fileExists((0,
|
|
7934
|
+
if (!fileExists((0, import_node_path34.join)(workspaceRoot, "nx.json"))) {
|
|
7618
7935
|
throw new Error(`No nx.json found in ${workspaceRoot} \u2014 run 'mnci up' from the workspace root.`);
|
|
7619
7936
|
}
|
|
7620
7937
|
const ecosystems = resolveEcosystems(options.ecosystem);
|
|
@@ -7686,12 +8003,13 @@ var PROJECT_KINDS = [
|
|
|
7686
8003
|
"csharp-function-app",
|
|
7687
8004
|
"csharp-lib",
|
|
7688
8005
|
"csharp-internal-lib",
|
|
7689
|
-
"vscode-extension"
|
|
8006
|
+
"vscode-extension",
|
|
8007
|
+
"container"
|
|
7690
8008
|
];
|
|
7691
8009
|
var EMPTY_KINDS = /* @__PURE__ */ new Set(["npm-lib", "internal-lib", "react-lib", "react-internal-lib", "node-function-app"]);
|
|
7692
8010
|
async function runAdd(kind, name, options) {
|
|
7693
8011
|
const workspaceRoot = process.cwd();
|
|
7694
|
-
if (!fileExists((0,
|
|
8012
|
+
if (!fileExists((0, import_node_path35.join)(workspaceRoot, "nx.json"))) {
|
|
7695
8013
|
throw new Error("No nx.json found here. Run `add` from the workspace root.");
|
|
7696
8014
|
}
|
|
7697
8015
|
const stack = readWorkspaceStack(workspaceRoot);
|
|
@@ -7712,13 +8030,35 @@ async function runAdd(kind, name, options) {
|
|
|
7712
8030
|
if (options.empty === true && !EMPTY_KINDS.has(resolvedKind)) {
|
|
7713
8031
|
throw new Error(`--empty applies to ${[...EMPTY_KINDS].join(", ")}, not ${resolvedKind}.`);
|
|
7714
8032
|
}
|
|
8033
|
+
if (options.esm === true) {
|
|
8034
|
+
if (resolvedKind !== "node-app" && resolvedKind !== "node-function-app") {
|
|
8035
|
+
throw new Error(`--esm applies to node-app and node-function-app, not ${resolvedKind}.`);
|
|
8036
|
+
}
|
|
8037
|
+
if (options.framework === "fastify" || options.framework === "nest") {
|
|
8038
|
+
throw new Error(`--esm is not supported with --framework ${options.framework}: its layout (autoloaded routes, decorators) is mandated by the framework. Use express, koa or none.`);
|
|
8039
|
+
}
|
|
8040
|
+
}
|
|
8041
|
+
if (resolvedKind === "container" && options.app === void 0) {
|
|
8042
|
+
throw new Error("container needs --app <project>: the app to put in an image, for example `mnci add container api-image --app api`.");
|
|
8043
|
+
}
|
|
8044
|
+
for (const [flag, requested] of [["--app", options.app !== void 0], ["--port", options.port !== void 0]]) {
|
|
8045
|
+
if (resolvedKind !== "container" && requested) {
|
|
8046
|
+
throw new Error(`${flag} applies to container, not ${resolvedKind}.`);
|
|
8047
|
+
}
|
|
8048
|
+
}
|
|
8049
|
+
if (options.port !== void 0 && !/^\d+$/.test(options.port)) {
|
|
8050
|
+
throw new Error(`--port ${options.port}: a port is a whole number.`);
|
|
8051
|
+
}
|
|
8052
|
+
if (resolvedKind !== "react-app" && options.e2e === true) {
|
|
8053
|
+
throw new Error(`--e2e applies to react-app, not ${resolvedKind}.`);
|
|
8054
|
+
}
|
|
7715
8055
|
const resolvedName = name ?? await promptText("Project name");
|
|
7716
8056
|
assertValidProjectName(resolvedName, "Project name");
|
|
7717
8057
|
const rootDependenciesBefore = rootRuntimeDependencies(workspaceRoot);
|
|
7718
8058
|
ensureNxPeerOverrides(workspaceRoot);
|
|
7719
8059
|
switch (resolvedKind) {
|
|
7720
8060
|
case "react-app": {
|
|
7721
|
-
addReactApp(workspaceRoot, resolvedName, stack);
|
|
8061
|
+
addReactApp(workspaceRoot, resolvedName, stack, options.e2e === true);
|
|
7722
8062
|
break;
|
|
7723
8063
|
}
|
|
7724
8064
|
case "react-lib": {
|
|
@@ -7730,11 +8070,11 @@ async function runAdd(kind, name, options) {
|
|
|
7730
8070
|
break;
|
|
7731
8071
|
}
|
|
7732
8072
|
case "node-app": {
|
|
7733
|
-
addNodeApp(workspaceRoot, resolvedName, stack, options.framework);
|
|
8073
|
+
addNodeApp(workspaceRoot, resolvedName, stack, options.framework, options.esm === true);
|
|
7734
8074
|
break;
|
|
7735
8075
|
}
|
|
7736
8076
|
case "node-function-app": {
|
|
7737
|
-
addNodeFunctionApp(workspaceRoot, resolvedName, stack, options.empty === true);
|
|
8077
|
+
addNodeFunctionApp(workspaceRoot, resolvedName, stack, options.empty === true, options.esm === true);
|
|
7738
8078
|
break;
|
|
7739
8079
|
}
|
|
7740
8080
|
case "npm-lib": {
|
|
@@ -7754,8 +8094,8 @@ async function runAdd(kind, name, options) {
|
|
|
7754
8094
|
],
|
|
7755
8095
|
workspaceRoot
|
|
7756
8096
|
);
|
|
7757
|
-
markPrivate((0,
|
|
7758
|
-
renameScaffoldPlaceholder((0,
|
|
8097
|
+
markPrivate((0, import_node_path35.join)(workspaceRoot, "libs", resolvedName, "package.json"));
|
|
8098
|
+
renameScaffoldPlaceholder((0, import_node_path35.join)(workspaceRoot, "libs", resolvedName), resolvedName, options.empty === true);
|
|
7759
8099
|
removeGeneratedEslintConfig(workspaceRoot, `libs/${resolvedName}`);
|
|
7760
8100
|
registerProjectCommands(workspaceRoot, resolvedName, { build: true });
|
|
7761
8101
|
break;
|
|
@@ -7776,6 +8116,10 @@ async function runAdd(kind, name, options) {
|
|
|
7776
8116
|
addPythonInternalLib(workspaceRoot, resolvedName);
|
|
7777
8117
|
break;
|
|
7778
8118
|
}
|
|
8119
|
+
case "container": {
|
|
8120
|
+
addContainer(workspaceRoot, resolvedName, { app: options.app, port: options.port === void 0 ? void 0 : Number(options.port) });
|
|
8121
|
+
break;
|
|
8122
|
+
}
|
|
7779
8123
|
case "go-app": {
|
|
7780
8124
|
addGoApp(workspaceRoot, resolvedName, { release: options.release, cgo: options.cgo, web: options.web });
|
|
7781
8125
|
break;
|
|
@@ -7847,7 +8191,7 @@ async function runAdd(kind, name, options) {
|
|
|
7847
8191
|
}
|
|
7848
8192
|
function readWorkspaceStack(workspaceRoot) {
|
|
7849
8193
|
const nxJson = readJson(
|
|
7850
|
-
(0,
|
|
8194
|
+
(0, import_node_path35.join)(workspaceRoot, "nx.json")
|
|
7851
8195
|
);
|
|
7852
8196
|
const stack = nxJson.mnci?.stack;
|
|
7853
8197
|
return {
|
|
@@ -7857,13 +8201,14 @@ function readWorkspaceStack(workspaceRoot) {
|
|
|
7857
8201
|
|
|
7858
8202
|
// src/project-scaffolding/project-kind-catalog.config.ts
|
|
7859
8203
|
var PROJECT_KIND_CATALOG = [
|
|
7860
|
-
{ kind: "react-app", language: "typescript", label: "React app", description: "A Vite React app, built per environment", flags: [], requiredFlags: [] },
|
|
8204
|
+
{ kind: "react-app", language: "typescript", label: "React app", description: "A Vite React app, built per environment", flags: ["e2e"], requiredFlags: [] },
|
|
7861
8205
|
{ kind: "react-lib", language: "typescript", label: "React library", description: "A publishable React component library", flags: ["scope", "empty"], requiredFlags: [] },
|
|
7862
8206
|
{ kind: "react-internal-lib", language: "typescript", label: "React internal library", description: "A private React library for apps in this workspace", flags: ["empty"], requiredFlags: [] },
|
|
7863
|
-
{ kind: "node-app", language: "typescript", label: "Node app", description: "A Node service, with Express, Fastify, Koa or Nest if you choose one", flags: ["framework"], requiredFlags: [] },
|
|
7864
|
-
{ kind: "node-function-app", language: "typescript", label: "Node function app", description: "An Azure Functions (v4) app in TypeScript", flags: ["empty"], requiredFlags: [] },
|
|
8207
|
+
{ kind: "node-app", language: "typescript", label: "Node app", description: "A Node service, with Express, Fastify, Koa or Nest if you choose one", flags: ["framework", "esm"], requiredFlags: [] },
|
|
8208
|
+
{ kind: "node-function-app", language: "typescript", label: "Node function app", description: "An Azure Functions (v4) app in TypeScript", flags: ["empty", "esm"], requiredFlags: [] },
|
|
7865
8209
|
{ kind: "npm-lib", language: "typescript", label: "npm library", description: "A library published to npm, bundled with Rollup", flags: ["scope", "empty"], requiredFlags: [] },
|
|
7866
8210
|
{ kind: "internal-lib", language: "typescript", label: "Internal library", description: "A private TypeScript library for apps in this workspace", flags: ["empty"], requiredFlags: [] },
|
|
8211
|
+
{ kind: "container", language: "container", label: "Container image", description: "A Dockerfile and image targets for an existing Node, React or Go app", flags: ["app", "port"], requiredFlags: ["app"] },
|
|
7867
8212
|
{ kind: "vscode-extension", language: "typescript", label: "VS Code extension", description: "A bundled Marketplace extension, optionally shipping a Go sidecar", flags: ["publisher", "sidecar"], requiredFlags: [] },
|
|
7868
8213
|
{ kind: "python-app", language: "python", label: "Python app", description: "A pip-native Python application (Ruff, pytest)", flags: [], requiredFlags: [] },
|
|
7869
8214
|
{ kind: "python-function-app", language: "python", label: "Python function app", description: "An Azure Functions (v2 model) app in Python", flags: [], requiredFlags: [] },
|
|
@@ -7896,12 +8241,12 @@ function runKinds(options) {
|
|
|
7896
8241
|
|
|
7897
8242
|
// src/workspace-diagnostics/check-invariants.use-case.ts
|
|
7898
8243
|
var import_node_child_process = require("child_process");
|
|
7899
|
-
var
|
|
7900
|
-
var
|
|
8244
|
+
var import_node_fs32 = require("fs");
|
|
8245
|
+
var import_node_path37 = require("path");
|
|
7901
8246
|
|
|
7902
8247
|
// src/workspace-diagnostics/locate-stranded-release-tags.use-case.ts
|
|
7903
|
-
var
|
|
7904
|
-
var
|
|
8248
|
+
var import_node_fs31 = require("fs");
|
|
8249
|
+
var import_node_path36 = require("path");
|
|
7905
8250
|
|
|
7906
8251
|
// src/workspace-diagnostics/stranded-release-tags.algorithm.ts
|
|
7907
8252
|
function compareVersions2(left, right) {
|
|
@@ -7938,7 +8283,7 @@ function locateStrandedReleaseTags(workspaceRoot, tagPattern) {
|
|
|
7938
8283
|
if (listed.status !== 0) {
|
|
7939
8284
|
return [];
|
|
7940
8285
|
}
|
|
7941
|
-
const projects = (0,
|
|
8286
|
+
const projects = (0, import_node_fs31.globSync)("{apps,libs,packages}/*/package.json", { cwd: workspaceRoot }).map((path) => readJson((0, import_node_path36.join)(workspaceRoot, path))).filter((manifest) => manifest.private !== true && manifest.name !== void 0).map((manifest) => manifest.name);
|
|
7942
8287
|
return findStrandedReleaseTags(projects, listed.stdout.split(/\r?\n/).filter(Boolean));
|
|
7943
8288
|
}
|
|
7944
8289
|
|
|
@@ -7948,8 +8293,8 @@ function toPosix2(path) {
|
|
|
7948
8293
|
return path.replaceAll("\\", "/");
|
|
7949
8294
|
}
|
|
7950
8295
|
function checkEslintConfigs(workspaceRoot) {
|
|
7951
|
-
const rootConfigs = (0,
|
|
7952
|
-
const projectConfigs = (0,
|
|
8296
|
+
const rootConfigs = (0, import_node_fs32.globSync)("eslint.config.{js,mjs,cjs,ts,mts,cts}", { cwd: workspaceRoot });
|
|
8297
|
+
const projectConfigs = (0, import_node_fs32.globSync)("{apps,libs,packages}/*/eslint.config.{js,mjs,cjs,ts,mts,cts}", {
|
|
7953
8298
|
cwd: workspaceRoot
|
|
7954
8299
|
}).map((config) => toPosix2(config));
|
|
7955
8300
|
return [
|
|
@@ -7969,10 +8314,10 @@ function checkEslintConfigs(workspaceRoot) {
|
|
|
7969
8314
|
];
|
|
7970
8315
|
}
|
|
7971
8316
|
function checkEslintEntryPointReachesTheRules(workspaceRoot) {
|
|
7972
|
-
const rules = (0,
|
|
7973
|
-
if (!(0,
|
|
7974
|
-
const entryPoint = (0,
|
|
7975
|
-
const source = (0,
|
|
8317
|
+
const rules = (0, import_node_path37.join)(workspaceRoot, ESLINT_MNCI_FILENAME);
|
|
8318
|
+
if (!(0, import_node_fs32.existsSync)(rules)) return [];
|
|
8319
|
+
const entryPoint = (0, import_node_path37.join)(workspaceRoot, ESLINT_USER_FILENAME);
|
|
8320
|
+
const source = (0, import_node_fs32.existsSync)(entryPoint) ? (0, import_node_fs32.readFileSync)(entryPoint, "utf8") : "";
|
|
7976
8321
|
return [
|
|
7977
8322
|
{
|
|
7978
8323
|
check: `${ESLINT_USER_FILENAME} imports the mnci rules`,
|
|
@@ -7985,7 +8330,7 @@ function checkEslintEntryPointReachesTheRules(workspaceRoot) {
|
|
|
7985
8330
|
function declaredDevDependencies(workspaceRoot) {
|
|
7986
8331
|
try {
|
|
7987
8332
|
const manifest = readJson(
|
|
7988
|
-
(0,
|
|
8333
|
+
(0, import_node_path37.join)(workspaceRoot, "package.json")
|
|
7989
8334
|
);
|
|
7990
8335
|
return manifest.devDependencies ?? {};
|
|
7991
8336
|
} catch {
|
|
@@ -7993,7 +8338,7 @@ function declaredDevDependencies(workspaceRoot) {
|
|
|
7993
8338
|
}
|
|
7994
8339
|
}
|
|
7995
8340
|
function checkNoRetiredFormatter(workspaceRoot) {
|
|
7996
|
-
const files = RETIRED_FORMATTER_FILES.filter((file) => fileExists((0,
|
|
8341
|
+
const files = RETIRED_FORMATTER_FILES.filter((file) => fileExists((0, import_node_path37.join)(workspaceRoot, file)));
|
|
7997
8342
|
const declared = ["prettier", "eslint-config-prettier", "oxlint", "oxfmt", "@mnci/oxlint-config"].filter((name) => declaredDevDependencies(workspaceRoot)[name] !== void 0);
|
|
7998
8343
|
const stale = [...files, ...declared];
|
|
7999
8344
|
if (stale.length === 0) {
|
|
@@ -8019,7 +8364,7 @@ function checkEslintPlugin(nxJson) {
|
|
|
8019
8364
|
};
|
|
8020
8365
|
}
|
|
8021
8366
|
function checkResolvedEslint(workspaceRoot) {
|
|
8022
|
-
const manifestPath = (0,
|
|
8367
|
+
const manifestPath = (0, import_node_path37.join)(workspaceRoot, "node_modules/eslint/package.json");
|
|
8023
8368
|
if (!fileExists(manifestPath)) {
|
|
8024
8369
|
return void 0;
|
|
8025
8370
|
}
|
|
@@ -8037,11 +8382,11 @@ function checkResolvedEslint(workspaceRoot) {
|
|
|
8037
8382
|
}
|
|
8038
8383
|
}
|
|
8039
8384
|
function checkNpmrc(workspaceRoot, registry, scope) {
|
|
8040
|
-
const npmrcPath = (0,
|
|
8385
|
+
const npmrcPath = (0, import_node_path37.join)(workspaceRoot, ".npmrc");
|
|
8041
8386
|
if (!registry || !fileExists(npmrcPath)) {
|
|
8042
8387
|
return void 0;
|
|
8043
8388
|
}
|
|
8044
|
-
const npmrc = (0,
|
|
8389
|
+
const npmrc = (0, import_node_fs32.readFileSync)(npmrcPath, "utf8");
|
|
8045
8390
|
if (registry.kind === "npm") {
|
|
8046
8391
|
return {
|
|
8047
8392
|
check: ".npmrc authenticates the public registry",
|
|
@@ -8058,11 +8403,11 @@ function checkNpmrc(workspaceRoot, registry, scope) {
|
|
|
8058
8403
|
};
|
|
8059
8404
|
}
|
|
8060
8405
|
function checkNpmrcCredentialResolves(workspaceRoot, environment = process.env) {
|
|
8061
|
-
const npmrcPath = (0,
|
|
8406
|
+
const npmrcPath = (0, import_node_path37.join)(workspaceRoot, ".npmrc");
|
|
8062
8407
|
if (!fileExists(npmrcPath)) {
|
|
8063
8408
|
return void 0;
|
|
8064
8409
|
}
|
|
8065
|
-
const npmrc = (0,
|
|
8410
|
+
const npmrc = (0, import_node_fs32.readFileSync)(npmrcPath, "utf8");
|
|
8066
8411
|
const credentials = npmrc.split("\n").filter((line) => !line.trimStart().startsWith(";") && !line.trimStart().startsWith("#")).filter((line) => /(?:_authToken|_password|_auth)\s*=/u.test(line));
|
|
8067
8412
|
const referenced = [
|
|
8068
8413
|
...new Set(
|
|
@@ -8086,13 +8431,13 @@ function checkNpmrcCredentialResolves(workspaceRoot, environment = process.env)
|
|
|
8086
8431
|
};
|
|
8087
8432
|
}
|
|
8088
8433
|
function checkNpmAuthMatchesPipeline(workspaceRoot, registry) {
|
|
8089
|
-
const npmrcPath = (0,
|
|
8090
|
-
const pipelinePath = (0,
|
|
8434
|
+
const npmrcPath = (0, import_node_path37.join)(workspaceRoot, ".npmrc");
|
|
8435
|
+
const pipelinePath = (0, import_node_path37.join)(workspaceRoot, "azure-pipelines.yml");
|
|
8091
8436
|
if (registry?.kind !== "azure-artifacts" || !fileExists(npmrcPath) || !fileExists(pipelinePath)) {
|
|
8092
8437
|
return void 0;
|
|
8093
8438
|
}
|
|
8094
|
-
const holdsCredentials = (0,
|
|
8095
|
-
const runsTask = (0,
|
|
8439
|
+
const holdsCredentials = (0, import_node_fs32.readFileSync)(npmrcPath, "utf8").split("\n").filter((line) => !line.trimStart().startsWith(";") && !line.trimStart().startsWith("#")).some((line) => /(?:_authToken|_password|_auth)\s*=/u.test(line));
|
|
8440
|
+
const runsTask = (0, import_node_fs32.readFileSync)(pipelinePath, "utf8").includes("npmAuthenticate@0");
|
|
8096
8441
|
if (!holdsCredentials && !runsTask) {
|
|
8097
8442
|
return {
|
|
8098
8443
|
check: "npm auth: .npmrc and azure-pipelines.yml agree",
|
|
@@ -8137,13 +8482,13 @@ function npmjsCredentialShape(credentials, environment) {
|
|
|
8137
8482
|
}
|
|
8138
8483
|
function checkVersionActions(workspaceRoot) {
|
|
8139
8484
|
const candidates = [
|
|
8140
|
-
...(0,
|
|
8141
|
-
...(0,
|
|
8142
|
-
...(0,
|
|
8485
|
+
...(0, import_node_fs32.globSync)("packages/*/pubspec.yaml", { cwd: workspaceRoot }),
|
|
8486
|
+
...(0, import_node_fs32.globSync)("packages/*/*.csproj", { cwd: workspaceRoot }),
|
|
8487
|
+
...(0, import_node_fs32.globSync)("python-packages/*/pyproject.toml", { cwd: workspaceRoot })
|
|
8143
8488
|
].map((manifest) => toPosix2(manifest));
|
|
8144
8489
|
return candidates.flatMap((manifest) => {
|
|
8145
8490
|
const projectRoot = manifest.slice(0, manifest.lastIndexOf("/"));
|
|
8146
|
-
const projectJsonPath = (0,
|
|
8491
|
+
const projectJsonPath = (0, import_node_path37.join)(workspaceRoot, projectRoot, "project.json");
|
|
8147
8492
|
let hasOverride = false;
|
|
8148
8493
|
try {
|
|
8149
8494
|
const projectJson = readJson(projectJsonPath);
|
|
@@ -8172,7 +8517,7 @@ function declaredTargets(workspaceRoot, projectRoot) {
|
|
|
8172
8517
|
]) {
|
|
8173
8518
|
try {
|
|
8174
8519
|
const targets = extract(
|
|
8175
|
-
readJson((0,
|
|
8520
|
+
readJson((0, import_node_path37.join)(workspaceRoot, projectRoot, file))
|
|
8176
8521
|
);
|
|
8177
8522
|
if (targets && typeof targets === "object") {
|
|
8178
8523
|
sources.push({
|
|
@@ -8188,8 +8533,8 @@ function declaredTargets(workspaceRoot, projectRoot) {
|
|
|
8188
8533
|
function checkTargetFilesExist(workspaceRoot) {
|
|
8189
8534
|
const projectRoots = new Set(
|
|
8190
8535
|
[
|
|
8191
|
-
...(0,
|
|
8192
|
-
...(0,
|
|
8536
|
+
...(0, import_node_fs32.globSync)("{apps,libs,packages}/*/project.json", { cwd: workspaceRoot }),
|
|
8537
|
+
...(0, import_node_fs32.globSync)("{apps,libs,packages}/*/package.json", { cwd: workspaceRoot })
|
|
8193
8538
|
].map((manifest) => toPosix2(manifest).split("/").slice(0, 2).join("/"))
|
|
8194
8539
|
);
|
|
8195
8540
|
return [...projectRoots].flatMap(
|
|
@@ -8204,7 +8549,7 @@ function checkOneTargetsFiles(workspaceRoot, source, targetName, target) {
|
|
|
8204
8549
|
return TARGET_FILE_OPTIONS.flatMap((option) => {
|
|
8205
8550
|
const value = target?.options?.[option];
|
|
8206
8551
|
const checkable = typeof value === "string" && !value.includes("{");
|
|
8207
|
-
if (!checkable || fileExists((0,
|
|
8552
|
+
if (!checkable || fileExists((0, import_node_path37.join)(workspaceRoot, value))) {
|
|
8208
8553
|
return [];
|
|
8209
8554
|
}
|
|
8210
8555
|
return [
|
|
@@ -8243,15 +8588,15 @@ function checkGoPluginRegistered(workspaceRoot) {
|
|
|
8243
8588
|
};
|
|
8244
8589
|
}
|
|
8245
8590
|
function checkGoWorkInSync(workspaceRoot) {
|
|
8246
|
-
const goWorkPath = (0,
|
|
8591
|
+
const goWorkPath = (0, import_node_path37.join)(workspaceRoot, "go.work");
|
|
8247
8592
|
if (!fileExists(goWorkPath)) {
|
|
8248
8593
|
return void 0;
|
|
8249
8594
|
}
|
|
8250
|
-
const contents = (0,
|
|
8595
|
+
const contents = (0, import_node_fs32.existsSync)(goWorkPath) ? (0, import_node_fs32.readFileSync)(goWorkPath, "utf8") : "";
|
|
8251
8596
|
const blockEntries = Array.from(contents.matchAll(/(?:^|\n)\s*use\s+\(([^)]*)\)/g), (match) => match[1].split("\n")).flat();
|
|
8252
8597
|
const singleEntries = Array.from(contents.matchAll(/(?:^|\n)\s*use\s+(\.\S+)/g), (match) => match[1]);
|
|
8253
8598
|
const uses = [...blockEntries, ...singleEntries].map((entry) => entry.trim()).filter(Boolean);
|
|
8254
|
-
const stale = uses.filter((entry) => !(0,
|
|
8599
|
+
const stale = uses.filter((entry) => !(0, import_node_fs32.existsSync)((0, import_node_path37.join)(workspaceRoot, entry, "go.mod")));
|
|
8255
8600
|
return {
|
|
8256
8601
|
check: "every go.work `use` entry points to a module that still exists",
|
|
8257
8602
|
ok: stale.length === 0,
|
|
@@ -8267,9 +8612,9 @@ function checkNativeApps(workspaceRoot) {
|
|
|
8267
8612
|
{ file: ".github/workflows/ci.yml", marker: "native (${{ matrix.os }})" },
|
|
8268
8613
|
{ file: "azure-pipelines.yml", marker: "- job: native" }
|
|
8269
8614
|
];
|
|
8270
|
-
const findings = pipelines.filter(({ file }) => fileExists((0,
|
|
8615
|
+
const findings = pipelines.filter(({ file }) => fileExists((0, import_node_path37.join)(workspaceRoot, file))).map(({ file, marker }) => ({
|
|
8271
8616
|
check: `${file} builds the native apps on every OS`,
|
|
8272
|
-
ok: (0,
|
|
8617
|
+
ok: (0, import_node_fs32.readFileSync)((0, import_node_path37.join)(workspaceRoot, file), "utf8").includes(marker),
|
|
8273
8618
|
detail: `${file} has no native job: CI would verify a cgo app on the one agent that cannot build it`,
|
|
8274
8619
|
remedy: "run `mnci upgrade`"
|
|
8275
8620
|
}));
|
|
@@ -8282,7 +8627,7 @@ function checkNativeApps(workspaceRoot) {
|
|
|
8282
8627
|
return findings;
|
|
8283
8628
|
}
|
|
8284
8629
|
function checkNoRootRuntimeDependencies(workspaceRoot) {
|
|
8285
|
-
const manifestPath = (0,
|
|
8630
|
+
const manifestPath = (0, import_node_path37.join)(workspaceRoot, "package.json");
|
|
8286
8631
|
if (!fileExists(manifestPath)) {
|
|
8287
8632
|
return void 0;
|
|
8288
8633
|
}
|
|
@@ -8302,14 +8647,14 @@ function checkNoRootRuntimeDependencies(workspaceRoot) {
|
|
|
8302
8647
|
};
|
|
8303
8648
|
}
|
|
8304
8649
|
function checkRollupSourceMaps(workspaceRoot) {
|
|
8305
|
-
const configs = (0,
|
|
8650
|
+
const configs = (0, import_node_fs32.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
|
|
8306
8651
|
cwd: workspaceRoot
|
|
8307
8652
|
}).map((config) => toPosix2(config));
|
|
8308
8653
|
return configs.flatMap((relativePath) => {
|
|
8309
|
-
const configPath = (0,
|
|
8654
|
+
const configPath = (0, import_node_path37.join)(workspaceRoot, relativePath);
|
|
8310
8655
|
let config;
|
|
8311
8656
|
try {
|
|
8312
|
-
config = (0,
|
|
8657
|
+
config = (0, import_node_fs32.readFileSync)(configPath, "utf8");
|
|
8313
8658
|
} catch {
|
|
8314
8659
|
return [];
|
|
8315
8660
|
}
|
|
@@ -8324,11 +8669,11 @@ function checkRollupSourceMaps(workspaceRoot) {
|
|
|
8324
8669
|
});
|
|
8325
8670
|
}
|
|
8326
8671
|
function checkDeclarationSpecifiers(workspaceRoot) {
|
|
8327
|
-
const configs = (0,
|
|
8672
|
+
const configs = (0, import_node_fs32.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
|
|
8328
8673
|
cwd: workspaceRoot
|
|
8329
8674
|
}).map((config) => toPosix2(config));
|
|
8330
8675
|
return configs.flatMap((relativePath) => {
|
|
8331
|
-
const configPath = (0,
|
|
8676
|
+
const configPath = (0, import_node_path37.join)(workspaceRoot, relativePath);
|
|
8332
8677
|
if (!fileExists(configPath)) {
|
|
8333
8678
|
return [];
|
|
8334
8679
|
}
|
|
@@ -8343,7 +8688,7 @@ function checkDeclarationSpecifiers(workspaceRoot) {
|
|
|
8343
8688
|
// `plugins` array (what @nx/react:library writes). For any other shape it would no-op, and
|
|
8344
8689
|
// naming a command that silently does nothing is the failure mode the source-map check
|
|
8345
8690
|
// above goes out of its way to avoid, so the remedy depends on the shape.
|
|
8346
|
-
remedy: canAddDeclarationSpecifierPlugin((0,
|
|
8691
|
+
remedy: canAddDeclarationSpecifierPlugin((0, import_node_fs32.readFileSync)(configPath, "utf8")) ? "run `mnci upgrade`, which adds the plugin to the plugins array of withNx's second argument" : "add the plugin to withNx's second argument by hand (copy it from a freshly `mnci add npm-lib`'d project) \u2014 mnci does not recognise the shape of this config, so `mnci upgrade` cannot add it"
|
|
8347
8692
|
}
|
|
8348
8693
|
];
|
|
8349
8694
|
}
|
|
@@ -8359,8 +8704,8 @@ function checkDeclarationSpecifiers(workspaceRoot) {
|
|
|
8359
8704
|
}
|
|
8360
8705
|
function checkPipelinePhases(workspaceRoot) {
|
|
8361
8706
|
const files = ["azure-pipelines.yml", ".github/workflows/ci.yml"];
|
|
8362
|
-
return files.filter((file) => fileExists((0,
|
|
8363
|
-
const { verifyActive, switchedOff } = inspectPipeline((0,
|
|
8707
|
+
return files.filter((file) => fileExists((0, import_node_path37.join)(workspaceRoot, file))).flatMap((file) => {
|
|
8708
|
+
const { verifyActive, switchedOff } = inspectPipeline((0, import_node_fs32.readFileSync)((0, import_node_path37.join)(workspaceRoot, file), "utf8"));
|
|
8364
8709
|
const verify = {
|
|
8365
8710
|
check: `${file} runs the enforced verify phase`,
|
|
8366
8711
|
ok: verifyActive,
|
|
@@ -8401,7 +8746,7 @@ function checkDependencyRangesNotPreserved(nxJson) {
|
|
|
8401
8746
|
};
|
|
8402
8747
|
}
|
|
8403
8748
|
function checkLockfileHasNoLocalRegistry(workspaceRoot) {
|
|
8404
|
-
if (!fileExists((0,
|
|
8749
|
+
if (!fileExists((0, import_node_path37.join)(workspaceRoot, "package-lock.json"))) {
|
|
8405
8750
|
return void 0;
|
|
8406
8751
|
}
|
|
8407
8752
|
return {
|
|
@@ -8421,7 +8766,7 @@ function checkReleaseTagsResolve(workspaceRoot, nxJson) {
|
|
|
8421
8766
|
};
|
|
8422
8767
|
}
|
|
8423
8768
|
function collectFindings(workspaceRoot) {
|
|
8424
|
-
const nxJsonPath = (0,
|
|
8769
|
+
const nxJsonPath = (0, import_node_path37.join)(workspaceRoot, "nx.json");
|
|
8425
8770
|
if (!fileExists(nxJsonPath)) {
|
|
8426
8771
|
throw new Error(
|
|
8427
8772
|
`No nx.json found in ${workspaceRoot} \u2014 run 'mnci doctor' from the workspace root.`
|
|
@@ -8486,8 +8831,8 @@ function runDoctor(workspaceRoot, options = {}) {
|
|
|
8486
8831
|
}
|
|
8487
8832
|
|
|
8488
8833
|
// src/repository-adoption/adopt-dependencies.use-case.ts
|
|
8489
|
-
var
|
|
8490
|
-
var
|
|
8834
|
+
var import_node_fs33 = require("fs");
|
|
8835
|
+
var import_node_path38 = require("path");
|
|
8491
8836
|
|
|
8492
8837
|
// src/repository-adoption/clean-working-tree.validator.ts
|
|
8493
8838
|
function requireCleanWorkingTree(repositoryRoot, capture = runCapture) {
|
|
@@ -8558,7 +8903,7 @@ var SOURCE_FILE = /\.(?:[cm]?[jt]s|[jt]sx)$/;
|
|
|
8558
8903
|
var TEST_FILE = /\.(?:spec|test)\.[^.]+$|[\\/](?:__tests__|tests?|e2e)[\\/]/;
|
|
8559
8904
|
var SKIPPED_DIRECTORIES = /* @__PURE__ */ new Set(["node_modules", "dist", "build", "coverage", "out", ".git", ".nx", "tmp"]);
|
|
8560
8905
|
function sourceFiles(directory, relative = "") {
|
|
8561
|
-
const entries = (0,
|
|
8906
|
+
const entries = (0, import_node_fs33.readdirSync)((0, import_node_path38.join)(directory, relative), { withFileTypes: true });
|
|
8562
8907
|
const found = [];
|
|
8563
8908
|
for (const entry of entries) {
|
|
8564
8909
|
const path = relative === "" ? entry.name : `${relative}/${entry.name}`;
|
|
@@ -8574,7 +8919,7 @@ function sourceFiles(directory, relative = "") {
|
|
|
8574
8919
|
}
|
|
8575
8920
|
function wantedImportsOf(path, wanted) {
|
|
8576
8921
|
try {
|
|
8577
|
-
const imported = [...extractImportedPackages((0,
|
|
8922
|
+
const imported = [...extractImportedPackages((0, import_node_fs33.readFileSync)(path, "utf8"))];
|
|
8578
8923
|
return imported.filter((name) => wanted.has(name));
|
|
8579
8924
|
} catch {
|
|
8580
8925
|
return [];
|
|
@@ -8585,7 +8930,7 @@ function importsOfProject(projectDirectory, wanted) {
|
|
|
8585
8930
|
const tested = /* @__PURE__ */ new Set();
|
|
8586
8931
|
const files = sourceFiles(projectDirectory);
|
|
8587
8932
|
for (const file of files) {
|
|
8588
|
-
const names = wantedImportsOf((0,
|
|
8933
|
+
const names = wantedImportsOf((0, import_node_path38.join)(projectDirectory, file), wanted);
|
|
8589
8934
|
const target = TEST_FILE.test(file) ? tested : shipped;
|
|
8590
8935
|
for (const name of names) {
|
|
8591
8936
|
target.add(name);
|
|
@@ -8597,7 +8942,7 @@ function importsOfProject(projectDirectory, wanted) {
|
|
|
8597
8942
|
function findUsage(repositoryRoot, projectDirectories, wanted) {
|
|
8598
8943
|
const usage = {};
|
|
8599
8944
|
for (const dir of projectDirectories) {
|
|
8600
|
-
const { shipped, testsOnly } = importsOfProject((0,
|
|
8945
|
+
const { shipped, testsOnly } = importsOfProject((0, import_node_path38.join)(repositoryRoot, dir), wanted);
|
|
8601
8946
|
for (const name of shipped) {
|
|
8602
8947
|
usage[name] ??= { runtime: [], testsOnly: [] };
|
|
8603
8948
|
usage[name].runtime.push(dir);
|
|
@@ -8612,7 +8957,7 @@ function findUsage(repositoryRoot, projectDirectories, wanted) {
|
|
|
8612
8957
|
function adoptDependencies(repositoryRoot, dependencies = {}) {
|
|
8613
8958
|
const run = dependencies.run ?? runShell;
|
|
8614
8959
|
requireCleanWorkingTree(repositoryRoot, dependencies.capture ?? runCapture);
|
|
8615
|
-
const rootPath = (0,
|
|
8960
|
+
const rootPath = (0, import_node_path38.join)(repositoryRoot, "package.json");
|
|
8616
8961
|
if (!fileExists(rootPath)) {
|
|
8617
8962
|
throw new Error("No package.json at the repository root.");
|
|
8618
8963
|
}
|
|
@@ -8647,8 +8992,8 @@ function adoptDependencies(repositoryRoot, dependencies = {}) {
|
|
|
8647
8992
|
}
|
|
8648
8993
|
|
|
8649
8994
|
// src/repository-adoption/adopt-kinds.use-case.ts
|
|
8650
|
-
var
|
|
8651
|
-
var
|
|
8995
|
+
var import_node_fs34 = require("fs");
|
|
8996
|
+
var import_node_path39 = require("path");
|
|
8652
8997
|
|
|
8653
8998
|
// src/repository-adoption/infer-project-kind.algorithm.ts
|
|
8654
8999
|
var SERVER_FRAMEWORKS = ["express", "koa", "fastify", "@nestjs/core"];
|
|
@@ -8749,32 +9094,32 @@ function inferProjectKind(evidence) {
|
|
|
8749
9094
|
// src/repository-adoption/adopt-kinds.use-case.ts
|
|
8750
9095
|
var TYPE_TAG = "type:";
|
|
8751
9096
|
function readEvidence(repositoryRoot, location) {
|
|
8752
|
-
const directory = (0,
|
|
8753
|
-
const files = (0,
|
|
9097
|
+
const directory = (0, import_node_path39.join)(repositoryRoot, location.dir);
|
|
9098
|
+
const files = (0, import_node_fs34.readdirSync)(directory);
|
|
8754
9099
|
const manifest = location.ecosystem === "npm" ? readJson(location.manifestPath) : {};
|
|
8755
|
-
const text = location.ecosystem === "npm" ? "" : (0,
|
|
9100
|
+
const text = location.ecosystem === "npm" ? "" : (0, import_node_fs34.readFileSync)(location.manifestPath, "utf8");
|
|
8756
9101
|
let hasProgram = false;
|
|
8757
9102
|
if (location.ecosystem === "go") {
|
|
8758
|
-
hasProgram = files.filter((file) => file.endsWith(".go")).some((file) => /^package main\b/m.test((0,
|
|
9103
|
+
hasProgram = files.filter((file) => file.endsWith(".go")).some((file) => /^package main\b/m.test((0, import_node_fs34.readFileSync)((0, import_node_path39.join)(directory, file), "utf8")));
|
|
8759
9104
|
} else if (location.ecosystem === "pub") {
|
|
8760
|
-
hasProgram = (0,
|
|
9105
|
+
hasProgram = (0, import_node_fs34.existsSync)((0, import_node_path39.join)(directory, "lib", "main.dart"));
|
|
8761
9106
|
}
|
|
8762
9107
|
return { ecosystem: location.ecosystem, manifest, text, files, hasProgram };
|
|
8763
9108
|
}
|
|
8764
9109
|
function existingKind(directory) {
|
|
8765
9110
|
const sources = [];
|
|
8766
|
-
if (fileExists((0,
|
|
8767
|
-
sources.push(readJson((0,
|
|
9111
|
+
if (fileExists((0, import_node_path39.join)(directory, "project.json"))) {
|
|
9112
|
+
sources.push(readJson((0, import_node_path39.join)(directory, "project.json")).tags ?? []);
|
|
8768
9113
|
}
|
|
8769
|
-
if (fileExists((0,
|
|
8770
|
-
sources.push(readJson((0,
|
|
9114
|
+
if (fileExists((0, import_node_path39.join)(directory, "package.json"))) {
|
|
9115
|
+
sources.push(readJson((0, import_node_path39.join)(directory, "package.json")).nx?.tags ?? []);
|
|
8771
9116
|
}
|
|
8772
9117
|
return sources.flat().find((tag) => tag.startsWith(TYPE_TAG))?.slice(TYPE_TAG.length);
|
|
8773
9118
|
}
|
|
8774
9119
|
function writeKindTag(directory, name, kind) {
|
|
8775
9120
|
const tag = `${TYPE_TAG}${kind}`;
|
|
8776
|
-
const projectJson = (0,
|
|
8777
|
-
const packageJson = (0,
|
|
9121
|
+
const projectJson = (0, import_node_path39.join)(directory, "project.json");
|
|
9122
|
+
const packageJson = (0, import_node_path39.join)(directory, "package.json");
|
|
8778
9123
|
if (fileExists(projectJson)) {
|
|
8779
9124
|
const project = readJson(projectJson);
|
|
8780
9125
|
writeFileEnsured(projectJson, toJson({ ...project, tags: [...project.tags ?? [], tag] }));
|
|
@@ -8798,7 +9143,7 @@ function adoptKinds(repositoryRoot, overrides = {}, dependencies = {}) {
|
|
|
8798
9143
|
}
|
|
8799
9144
|
}
|
|
8800
9145
|
return locations.map((location) => {
|
|
8801
|
-
const directory = (0,
|
|
9146
|
+
const directory = (0, import_node_path39.join)(repositoryRoot, location.dir);
|
|
8802
9147
|
const present = existingKind(directory);
|
|
8803
9148
|
if (present !== void 0) {
|
|
8804
9149
|
return { dir: location.dir, outcome: "already", kind: present, reason: PROJECT_KINDS.includes(present) ? "it already has a type tag" : "it already has a type tag of its own, which is not an mnci kind name; left as it is" };
|
|
@@ -8814,12 +9159,12 @@ function adoptKinds(repositoryRoot, overrides = {}, dependencies = {}) {
|
|
|
8814
9159
|
}
|
|
8815
9160
|
|
|
8816
9161
|
// src/repository-adoption/adopt-overlay.use-case.ts
|
|
8817
|
-
var
|
|
8818
|
-
var
|
|
9162
|
+
var import_node_fs36 = require("fs");
|
|
9163
|
+
var import_node_path41 = require("path");
|
|
8819
9164
|
|
|
8820
9165
|
// src/workspace-upgrade/upgrade-workspace.use-case.ts
|
|
8821
|
-
var
|
|
8822
|
-
var
|
|
9166
|
+
var import_node_fs35 = require("fs");
|
|
9167
|
+
var import_node_path40 = require("path");
|
|
8823
9168
|
function resolveRegistry(options, persisted) {
|
|
8824
9169
|
if (options.registry === "azure-artifacts" || options.organization && options.artifactsFeed) {
|
|
8825
9170
|
const persistedAzure = persisted?.kind === "azure-artifacts" ? persisted : void 0;
|
|
@@ -8848,7 +9193,7 @@ function resolveWorkspaceName(workspaceRoot, persisted) {
|
|
|
8848
9193
|
return persisted.workspaceName;
|
|
8849
9194
|
}
|
|
8850
9195
|
try {
|
|
8851
|
-
const existing = (0,
|
|
9196
|
+
const existing = (0, import_node_fs35.readdirSync)(workspaceRoot).find(
|
|
8852
9197
|
(file) => file.endsWith(".code-workspace") && file !== "undefined.code-workspace"
|
|
8853
9198
|
);
|
|
8854
9199
|
if (existing) {
|
|
@@ -8856,11 +9201,11 @@ function resolveWorkspaceName(workspaceRoot, persisted) {
|
|
|
8856
9201
|
}
|
|
8857
9202
|
} catch {
|
|
8858
9203
|
}
|
|
8859
|
-
return (0,
|
|
9204
|
+
return (0, import_node_path40.basename)(workspaceRoot);
|
|
8860
9205
|
}
|
|
8861
9206
|
function detectNpmAuth(workspaceRoot) {
|
|
8862
9207
|
try {
|
|
8863
|
-
return (0,
|
|
9208
|
+
return (0, import_node_fs35.readFileSync)((0, import_node_path40.join)(workspaceRoot, "azure-pipelines.yml"), "utf8").includes("npmAuthenticate@0") ? "build-identity" : void 0;
|
|
8864
9209
|
} catch {
|
|
8865
9210
|
return void 0;
|
|
8866
9211
|
}
|
|
@@ -8907,7 +9252,7 @@ function resolveOverlayOptions(workspaceRoot, options, persisted) {
|
|
|
8907
9252
|
};
|
|
8908
9253
|
}
|
|
8909
9254
|
function runUpgrade(workspaceRoot, options) {
|
|
8910
|
-
if (!fileExists((0,
|
|
9255
|
+
if (!fileExists((0, import_node_path40.join)(workspaceRoot, "nx.json"))) {
|
|
8911
9256
|
throw new Error(
|
|
8912
9257
|
`No nx.json found in ${workspaceRoot} \u2014 this does not look like an Nx workspace. Run 'mnci upgrade' from the workspace root.`
|
|
8913
9258
|
);
|
|
@@ -8955,6 +9300,10 @@ function runUpgrade(workspaceRoot, options) {
|
|
|
8955
9300
|
logger.step("Updating the VS Code extension packaging script");
|
|
8956
9301
|
logger.detail(`updated ${VSCODE_EXTENSION_SCRIPT_PATH}`);
|
|
8957
9302
|
}
|
|
9303
|
+
if (refreshContainerScript(workspaceRoot)) {
|
|
9304
|
+
logger.step("Updating the container image script");
|
|
9305
|
+
logger.detail("updated tools/container-image.cjs");
|
|
9306
|
+
}
|
|
8958
9307
|
if (refreshGoReleaseScript(workspaceRoot)) {
|
|
8959
9308
|
logger.step("Updating the releasable Go app script");
|
|
8960
9309
|
logger.detail(`updated ${GO_RELEASE_SCRIPT_PATH}`);
|
|
@@ -8981,7 +9330,7 @@ function runUpgrade(workspaceRoot, options) {
|
|
|
8981
9330
|
"Formatting the workspace (eslint --fix) \u2014 the slowest step, minutes on a large workspace"
|
|
8982
9331
|
);
|
|
8983
9332
|
runFormatter(workspaceRoot);
|
|
8984
|
-
const nxJson = readJson((0,
|
|
9333
|
+
const nxJson = readJson((0, import_node_path40.join)(workspaceRoot, "nx.json"));
|
|
8985
9334
|
const stranded = locateStrandedReleaseTags(workspaceRoot, nxJson.release?.releaseTag?.pattern);
|
|
8986
9335
|
for (const entry of stranded) {
|
|
8987
9336
|
logger.warn(`${entry.project} has release tags only under ${entry.oldTag}: nx release would restart it from its disk version. Run \`mnci adopt --tags\` before the next release to create ${entry.newTag} locally (\`mnci doctor\` lists them all).`);
|
|
@@ -8992,9 +9341,9 @@ function runUpgrade(workspaceRoot, options) {
|
|
|
8992
9341
|
|
|
8993
9342
|
// src/repository-adoption/adopt-overlay.use-case.ts
|
|
8994
9343
|
function detectCiProvider(repositoryRoot) {
|
|
8995
|
-
const azure = (0,
|
|
8996
|
-
const workflows = (0,
|
|
8997
|
-
const github = (0,
|
|
9344
|
+
const azure = (0, import_node_fs36.existsSync)((0, import_node_path41.join)(repositoryRoot, "azure-pipelines.yml"));
|
|
9345
|
+
const workflows = (0, import_node_path41.join)(repositoryRoot, ".github", "workflows");
|
|
9346
|
+
const github = (0, import_node_fs36.existsSync)(workflows) && (0, import_node_fs36.readdirSync)(workflows).some((file) => /\.ya?ml$/.test(file));
|
|
8998
9347
|
if (azure && github) {
|
|
8999
9348
|
return "both";
|
|
9000
9349
|
}
|
|
@@ -9004,7 +9353,7 @@ function detectCiProvider(repositoryRoot) {
|
|
|
9004
9353
|
return github ? "github" : void 0;
|
|
9005
9354
|
}
|
|
9006
9355
|
function detectTestRunner(repositoryRoot) {
|
|
9007
|
-
const manifestPath = (0,
|
|
9356
|
+
const manifestPath = (0, import_node_path41.join)(repositoryRoot, "package.json");
|
|
9008
9357
|
if (!fileExists(manifestPath)) {
|
|
9009
9358
|
return void 0;
|
|
9010
9359
|
}
|
|
@@ -9017,7 +9366,7 @@ function detectTestRunner(repositoryRoot) {
|
|
|
9017
9366
|
}
|
|
9018
9367
|
function adoptOverlay(repositoryRoot, options, dependencies = {}) {
|
|
9019
9368
|
requireCleanWorkingTree(repositoryRoot, dependencies.capture ?? runCapture);
|
|
9020
|
-
if (!fileExists((0,
|
|
9369
|
+
if (!fileExists((0, import_node_path41.join)(repositoryRoot, "nx.json"))) {
|
|
9021
9370
|
throw new Error("There is no nx.json, so Nx is not set up here. Set it up first (`npx nx@latest init`); adopt does not install Nx yet.");
|
|
9022
9371
|
}
|
|
9023
9372
|
const persisted = readMnciConfig(repositoryRoot);
|
|
@@ -9030,7 +9379,7 @@ function adoptOverlay(repositoryRoot, options, dependencies = {}) {
|
|
|
9030
9379
|
}
|
|
9031
9380
|
|
|
9032
9381
|
// src/repository-adoption/adopt-toolchain.use-case.ts
|
|
9033
|
-
var
|
|
9382
|
+
var import_node_path43 = require("path");
|
|
9034
9383
|
|
|
9035
9384
|
// src/repository-adoption/align-nx-family.algorithm.ts
|
|
9036
9385
|
var VERSION = /^[\^~]?(\d+)\.(\d+)\.(\d+)$/;
|
|
@@ -9068,24 +9417,24 @@ function alignNxFamily(dependencies, version) {
|
|
|
9068
9417
|
}
|
|
9069
9418
|
|
|
9070
9419
|
// src/repository-adoption/retire-tooling.use-case.ts
|
|
9071
|
-
var
|
|
9072
|
-
var
|
|
9420
|
+
var import_node_fs37 = require("fs");
|
|
9421
|
+
var import_node_path42 = require("path");
|
|
9073
9422
|
var RETIRED_COMMAND = /\b(?:prettier|oxfmt|oxlint)\b/;
|
|
9074
9423
|
function retireTooling(repositoryRoot) {
|
|
9075
9424
|
const removed = [];
|
|
9076
9425
|
for (const file of RETIRED_FORMATTER_FILES) {
|
|
9077
|
-
if (!fileExists((0,
|
|
9426
|
+
if (!fileExists((0, import_node_path42.join)(repositoryRoot, file))) {
|
|
9078
9427
|
continue;
|
|
9079
9428
|
}
|
|
9080
|
-
(0,
|
|
9429
|
+
(0, import_node_fs37.rmSync)((0, import_node_path42.join)(repositoryRoot, file), { force: true });
|
|
9081
9430
|
removed.push(file);
|
|
9082
9431
|
}
|
|
9083
|
-
const hadRegistry = fileExists((0,
|
|
9432
|
+
const hadRegistry = fileExists((0, import_node_path42.join)(repositoryRoot, ".verdaccio"));
|
|
9084
9433
|
removeLocalRegistryScaffolding(repositoryRoot);
|
|
9085
9434
|
if (hadRegistry) {
|
|
9086
9435
|
removed.push(".verdaccio, its dependency and the local-registry target");
|
|
9087
9436
|
}
|
|
9088
|
-
const manifestPath = (0,
|
|
9437
|
+
const manifestPath = (0, import_node_path42.join)(repositoryRoot, "package.json");
|
|
9089
9438
|
if (!fileExists(manifestPath)) {
|
|
9090
9439
|
return removed;
|
|
9091
9440
|
}
|
|
@@ -9132,7 +9481,7 @@ function adoptToolchain(repositoryRoot, options = {}, dependencies = {}) {
|
|
|
9132
9481
|
console.log(message);
|
|
9133
9482
|
});
|
|
9134
9483
|
requireCleanWorkingTree(repositoryRoot, capture);
|
|
9135
|
-
const manifestPath = (0,
|
|
9484
|
+
const manifestPath = (0, import_node_path43.join)(repositoryRoot, "package.json");
|
|
9136
9485
|
if (!fileExists(manifestPath)) {
|
|
9137
9486
|
throw new Error("No package.json at the repository root.");
|
|
9138
9487
|
}
|
|
@@ -9182,8 +9531,8 @@ function createBaselineTags(repositoryRoot, stranded) {
|
|
|
9182
9531
|
}
|
|
9183
9532
|
|
|
9184
9533
|
// src/repository-adoption/inspect-repository.use-case.ts
|
|
9185
|
-
var
|
|
9186
|
-
var
|
|
9534
|
+
var import_node_fs38 = require("fs");
|
|
9535
|
+
var import_node_path44 = require("path");
|
|
9187
9536
|
var LOCKFILES = [
|
|
9188
9537
|
["package-lock.json", "npm"],
|
|
9189
9538
|
["pnpm-lock.yaml", "pnpm"],
|
|
@@ -9204,25 +9553,25 @@ function inspectRepository(repositoryRoot) {
|
|
|
9204
9553
|
const isGitRepo = inside.status === 0 && inside.stdout.trim() === "true";
|
|
9205
9554
|
const dirty = isGitRepo && runCapture("git", ["status", "--porcelain"], repositoryRoot).stdout.trim() !== "";
|
|
9206
9555
|
const tags = isGitRepo ? runCapture("git", ["tag", "--list"], repositoryRoot).stdout.split(/\r?\n/).filter(Boolean) : [];
|
|
9207
|
-
const manifestPath = (0,
|
|
9556
|
+
const manifestPath = (0, import_node_path44.join)(repositoryRoot, "package.json");
|
|
9208
9557
|
const manifest = fileExists(manifestPath) ? readJson(manifestPath) : {};
|
|
9209
|
-
const nxJsonPath = (0,
|
|
9558
|
+
const nxJsonPath = (0, import_node_path44.join)(repositoryRoot, "nx.json");
|
|
9210
9559
|
const nxJson = fileExists(nxJsonPath) ? readJson(nxJsonPath) : {};
|
|
9211
9560
|
const ci = [];
|
|
9212
9561
|
const pipelines = [];
|
|
9213
|
-
if ((0,
|
|
9562
|
+
if ((0, import_node_fs38.existsSync)((0, import_node_path44.join)(repositoryRoot, "azure-pipelines.yml"))) {
|
|
9214
9563
|
ci.push("azure");
|
|
9215
|
-
pipelines.push((0,
|
|
9564
|
+
pipelines.push((0, import_node_path44.join)(repositoryRoot, "azure-pipelines.yml"));
|
|
9216
9565
|
}
|
|
9217
|
-
const workflows = (0,
|
|
9218
|
-
if ((0,
|
|
9219
|
-
const files = (0,
|
|
9566
|
+
const workflows = (0, import_node_path44.join)(repositoryRoot, ".github", "workflows");
|
|
9567
|
+
if ((0, import_node_fs38.existsSync)(workflows)) {
|
|
9568
|
+
const files = (0, import_node_fs38.readdirSync)(workflows).filter((file) => /\.ya?ml$/.test(file));
|
|
9220
9569
|
if (files.length > 0) {
|
|
9221
9570
|
ci.push("github");
|
|
9222
|
-
pipelines.push(...files.map((file) => (0,
|
|
9571
|
+
pipelines.push(...files.map((file) => (0, import_node_path44.join)(workflows, file)));
|
|
9223
9572
|
}
|
|
9224
9573
|
}
|
|
9225
|
-
const rootFiles = (0,
|
|
9574
|
+
const rootFiles = (0, import_node_fs38.readdirSync)(repositoryRoot);
|
|
9226
9575
|
return {
|
|
9227
9576
|
isGitRepo,
|
|
9228
9577
|
dirty,
|
|
@@ -9233,7 +9582,7 @@ function inspectRepository(repositoryRoot) {
|
|
|
9233
9582
|
tagCount: tags.length,
|
|
9234
9583
|
strandedTags: isGitRepo ? locateStrandedReleaseTags(repositoryRoot, nxJson.release?.releaseTag?.pattern) : [],
|
|
9235
9584
|
ci,
|
|
9236
|
-
pipelineUsesMnci: pipelines.some((file) => /\bmnci ci\b/.test((0,
|
|
9585
|
+
pipelineUsesMnci: pipelines.some((file) => /\bmnci ci\b/.test((0, import_node_fs38.readFileSync)(file, "utf8"))),
|
|
9237
9586
|
retiredTooling: [.../* @__PURE__ */ new Set([...rootFiles.filter((file) => RETIRED_FILE_PATTERN.test(file) || file === ".verdaccio"), ...retiredNamesIn(manifest)])],
|
|
9238
9587
|
personalFiles: PERSONAL_FILES.filter((file) => rootFiles.includes(file))
|
|
9239
9588
|
};
|
|
@@ -9530,13 +9879,13 @@ function runCommands(program, options) {
|
|
|
9530
9879
|
}
|
|
9531
9880
|
|
|
9532
9881
|
// src/workspace-info/list-projects.use-case.ts
|
|
9533
|
-
var
|
|
9882
|
+
var import_node_path45 = require("path");
|
|
9534
9883
|
var TYPE_TAG_PREFIX = "type:";
|
|
9535
9884
|
function listProjects(workspaceRoot) {
|
|
9536
9885
|
return locateProjects(workspaceRoot).map((location) => {
|
|
9537
|
-
const projectJsonPath = (0,
|
|
9886
|
+
const projectJsonPath = (0, import_node_path45.join)(workspaceRoot, location.dir, "project.json");
|
|
9538
9887
|
const project = fileExists(projectJsonPath) ? readJson(projectJsonPath) : {};
|
|
9539
|
-
const manifestPath = (0,
|
|
9888
|
+
const manifestPath = (0, import_node_path45.join)(workspaceRoot, location.dir, "package.json");
|
|
9540
9889
|
const manifestTags = fileExists(manifestPath) ? readJson(manifestPath).nx?.tags ?? [] : [];
|
|
9541
9890
|
const typeTag = [...project.tags ?? [], ...manifestTags].find((tag) => tag.startsWith(TYPE_TAG_PREFIX));
|
|
9542
9891
|
return {
|
|
@@ -9549,7 +9898,7 @@ function listProjects(workspaceRoot) {
|
|
|
9549
9898
|
}).toSorted((a, b) => a.dir.localeCompare(b.dir));
|
|
9550
9899
|
}
|
|
9551
9900
|
function runProjects(workspaceRoot, options) {
|
|
9552
|
-
if (!fileExists((0,
|
|
9901
|
+
if (!fileExists((0, import_node_path45.join)(workspaceRoot, "nx.json"))) {
|
|
9553
9902
|
throw new Error("No nx.json found here. Run `projects` from the workspace root.");
|
|
9554
9903
|
}
|
|
9555
9904
|
const projects = listProjects(workspaceRoot);
|
|
@@ -9563,11 +9912,11 @@ function runProjects(workspaceRoot, options) {
|
|
|
9563
9912
|
}
|
|
9564
9913
|
|
|
9565
9914
|
// src/workspace-info/read-workspace-info.use-case.ts
|
|
9566
|
-
var
|
|
9915
|
+
var import_node_path47 = require("path");
|
|
9567
9916
|
|
|
9568
9917
|
// src/cli-version/check-for-update.use-case.ts
|
|
9569
|
-
var
|
|
9570
|
-
var
|
|
9918
|
+
var import_node_fs39 = require("fs");
|
|
9919
|
+
var import_node_path46 = require("path");
|
|
9571
9920
|
var import_cross_spawn3 = __toESM(require("cross-spawn"));
|
|
9572
9921
|
var PACKAGE_NAME2 = "@mnci/cli";
|
|
9573
9922
|
var REGISTRY_TIMEOUT_MS = 2e3;
|
|
@@ -9626,8 +9975,8 @@ function releaseTriple(version) {
|
|
|
9626
9975
|
}
|
|
9627
9976
|
function readCliVersion(packageDirectory) {
|
|
9628
9977
|
try {
|
|
9629
|
-
const manifestPath = (0,
|
|
9630
|
-
const manifest = JSON.parse((0,
|
|
9978
|
+
const manifestPath = (0, import_node_path46.join)(packageDirectory, "..", "package.json");
|
|
9979
|
+
const manifest = JSON.parse((0, import_node_fs39.readFileSync)(manifestPath, "utf8"));
|
|
9631
9980
|
return manifest.version ?? "0.0.0";
|
|
9632
9981
|
} catch {
|
|
9633
9982
|
return "0.0.0";
|
|
@@ -9637,7 +9986,7 @@ function readCliVersion(packageDirectory) {
|
|
|
9637
9986
|
// src/workspace-info/read-workspace-info.use-case.ts
|
|
9638
9987
|
function readWorkspaceInfo(workspaceRoot, cliVersion) {
|
|
9639
9988
|
const latest = fetchLatestVersion() ?? null;
|
|
9640
|
-
const isWorkspace = fileExists((0,
|
|
9989
|
+
const isWorkspace = fileExists((0, import_node_path47.join)(workspaceRoot, "nx.json"));
|
|
9641
9990
|
return {
|
|
9642
9991
|
cli: {
|
|
9643
9992
|
version: cliVersion,
|
|
@@ -9658,7 +10007,7 @@ function runInfo(workspaceRoot, cliVersion, options) {
|
|
|
9658
10007
|
}
|
|
9659
10008
|
|
|
9660
10009
|
// src/interactive-wizard/interactive-wizard.use-case.ts
|
|
9661
|
-
var
|
|
10010
|
+
var import_node_path48 = require("path");
|
|
9662
10011
|
|
|
9663
10012
|
// src/interactive-wizard/adopt-steps.config.ts
|
|
9664
10013
|
var ADOPT_GLOBAL_OPTIONS = ["json"];
|
|
@@ -9839,7 +10188,7 @@ function wizardMenu(commands, inWorkspace) {
|
|
|
9839
10188
|
}
|
|
9840
10189
|
async function runInteractive(program, prompter = createInquirerPrompter(), workingDirectory = process.cwd()) {
|
|
9841
10190
|
const commands = describeCommands(program);
|
|
9842
|
-
const inWorkspace = fileExists((0,
|
|
10191
|
+
const inWorkspace = fileExists((0, import_node_path48.join)(workingDirectory, "nx.json"));
|
|
9843
10192
|
const name = await prompter.select("What would you like to do?", wizardMenu(commands, inWorkspace));
|
|
9844
10193
|
const command = commands.find((candidate) => candidate.name === name);
|
|
9845
10194
|
const argv = buildArgv(command, await askCommand(command, prompter));
|
|
@@ -9852,8 +10201,8 @@ async function runInteractive(program, prompter = createInquirerPrompter(), work
|
|
|
9852
10201
|
}
|
|
9853
10202
|
|
|
9854
10203
|
// src/workspace-creation/adopt-directory.use-case.ts
|
|
9855
|
-
var
|
|
9856
|
-
var
|
|
10204
|
+
var import_node_fs40 = require("fs");
|
|
10205
|
+
var import_node_path49 = require("path");
|
|
9857
10206
|
var NEVER_COPIED = /* @__PURE__ */ new Set([".git", "node_modules"]);
|
|
9858
10207
|
var AGENT_AND_CI_ENTRIES = [
|
|
9859
10208
|
"AGENTS.md",
|
|
@@ -9884,13 +10233,13 @@ var PREFLIGHT_BLOCKERS = [
|
|
|
9884
10233
|
"packages"
|
|
9885
10234
|
];
|
|
9886
10235
|
function assertAdoptableDirectory(target) {
|
|
9887
|
-
if (!(0,
|
|
10236
|
+
if (!(0, import_node_fs40.existsSync)(target)) {
|
|
9888
10237
|
throw new Error(`--into '${target}' does not exist. Create or clone it first.`);
|
|
9889
10238
|
}
|
|
9890
|
-
if (!(0,
|
|
10239
|
+
if (!(0, import_node_fs40.statSync)(target).isDirectory()) {
|
|
9891
10240
|
throw new Error(`--into '${target}' is not a directory.`);
|
|
9892
10241
|
}
|
|
9893
|
-
const blockers = PREFLIGHT_BLOCKERS.filter((entry) => (0,
|
|
10242
|
+
const blockers = PREFLIGHT_BLOCKERS.filter((entry) => (0, import_node_fs40.existsSync)((0, import_node_path49.join)(target, entry)));
|
|
9894
10243
|
if (blockers.length > 0) {
|
|
9895
10244
|
throw new Error(
|
|
9896
10245
|
`--into '${target}' already holds ${blockers.join(", ")}, so it is a project already. Use \`mnci upgrade\` to re-apply the overlay to an existing workspace, or point --into at an empty checkout.`
|
|
@@ -9898,15 +10247,15 @@ function assertAdoptableDirectory(target) {
|
|
|
9898
10247
|
}
|
|
9899
10248
|
}
|
|
9900
10249
|
function mergeGitignore(generatedFile, targetFile) {
|
|
9901
|
-
const existing = (0,
|
|
10250
|
+
const existing = (0, import_node_fs40.readFileSync)(targetFile, "utf8");
|
|
9902
10251
|
const present = new Set(existing.split("\n").map((line) => line.trim()));
|
|
9903
|
-
const additions = (0,
|
|
10252
|
+
const additions = (0, import_node_fs40.readFileSync)(generatedFile, "utf8").split("\n").map((line) => line.trimEnd()).filter((line) => {
|
|
9904
10253
|
const trimmed = line.trim();
|
|
9905
10254
|
return trimmed !== "" && !trimmed.startsWith("#") && !present.has(trimmed);
|
|
9906
10255
|
});
|
|
9907
10256
|
if (additions.length === 0) return false;
|
|
9908
10257
|
const separator = existing.endsWith("\n") ? "" : "\n";
|
|
9909
|
-
(0,
|
|
10258
|
+
(0, import_node_fs40.writeFileSync)(
|
|
9910
10259
|
targetFile,
|
|
9911
10260
|
`${existing}${separator}
|
|
9912
10261
|
# Added by mnci (Nx workspace)
|
|
@@ -9916,9 +10265,9 @@ ${additions.join("\n")}
|
|
|
9916
10265
|
return true;
|
|
9917
10266
|
}
|
|
9918
10267
|
function adoptGeneratedWorkspace(generatedRoot, target) {
|
|
9919
|
-
const entries = (0,
|
|
10268
|
+
const entries = (0, import_node_fs40.readdirSync)(generatedRoot).filter((entry) => !NEVER_COPIED.has(entry));
|
|
9920
10269
|
const collisions = entries.filter(
|
|
9921
|
-
(entry) => (0,
|
|
10270
|
+
(entry) => (0, import_node_fs40.existsSync)((0, import_node_path49.join)(target, entry)) && !EXISTING_WINS.has(entry) && entry !== ".gitignore"
|
|
9922
10271
|
);
|
|
9923
10272
|
if (collisions.length > 0) {
|
|
9924
10273
|
throw new Error(
|
|
@@ -9927,28 +10276,28 @@ function adoptGeneratedWorkspace(generatedRoot, target) {
|
|
|
9927
10276
|
}
|
|
9928
10277
|
const result = { copied: [], kept: [], mergedGitignore: false };
|
|
9929
10278
|
for (const entry of entries) {
|
|
9930
|
-
const from = (0,
|
|
9931
|
-
const to = (0,
|
|
9932
|
-
if (entry === ".gitignore" && (0,
|
|
10279
|
+
const from = (0, import_node_path49.join)(generatedRoot, entry);
|
|
10280
|
+
const to = (0, import_node_path49.join)(target, entry);
|
|
10281
|
+
if (entry === ".gitignore" && (0, import_node_fs40.existsSync)(to)) {
|
|
9933
10282
|
result.mergedGitignore = mergeGitignore(from, to);
|
|
9934
10283
|
result.kept.push(entry);
|
|
9935
10284
|
continue;
|
|
9936
10285
|
}
|
|
9937
|
-
if ((0,
|
|
10286
|
+
if ((0, import_node_fs40.existsSync)(to)) {
|
|
9938
10287
|
result.kept.push(entry);
|
|
9939
10288
|
continue;
|
|
9940
10289
|
}
|
|
9941
|
-
(0,
|
|
10290
|
+
(0, import_node_fs40.cpSync)(from, to, { recursive: true });
|
|
9942
10291
|
result.copied.push(entry);
|
|
9943
10292
|
}
|
|
9944
|
-
(0,
|
|
10293
|
+
(0, import_node_fs40.rmSync)(generatedRoot, { recursive: true, force: true });
|
|
9945
10294
|
return result;
|
|
9946
10295
|
}
|
|
9947
10296
|
|
|
9948
10297
|
// src/workspace-creation/create-workspace.use-case.ts
|
|
9949
|
-
var
|
|
10298
|
+
var import_node_fs41 = require("fs");
|
|
9950
10299
|
var import_node_os2 = require("os");
|
|
9951
|
-
var
|
|
10300
|
+
var import_node_path50 = require("path");
|
|
9952
10301
|
function nxCloudProviderValue(ci) {
|
|
9953
10302
|
return ci === "azure" ? "azure" : "github";
|
|
9954
10303
|
}
|
|
@@ -9991,9 +10340,9 @@ async function resolveRegistry2(options) {
|
|
|
9991
10340
|
return await promptRegistry();
|
|
9992
10341
|
}
|
|
9993
10342
|
async function runNew(name, options) {
|
|
9994
|
-
const adoptTarget = options.into === void 0 ? void 0 : (0,
|
|
10343
|
+
const adoptTarget = options.into === void 0 ? void 0 : (0, import_node_path50.resolve)(process.cwd(), options.into);
|
|
9995
10344
|
if (adoptTarget !== void 0) assertAdoptableDirectory(adoptTarget);
|
|
9996
|
-
const workspaceName = name ?? (adoptTarget === void 0 ? await promptText("Workspace name") : (0,
|
|
10345
|
+
const workspaceName = name ?? (adoptTarget === void 0 ? await promptText("Workspace name") : (0, import_node_path50.basename)(adoptTarget));
|
|
9997
10346
|
assertValidProjectName(workspaceName, "Workspace name");
|
|
9998
10347
|
const scope = options.scope ?? (options.yes ? `@${workspaceName}` : await promptText("npm scope for publishable packages", `@${workspaceName}`));
|
|
9999
10348
|
const registry = await resolveRegistry2(options);
|
|
@@ -10006,8 +10355,8 @@ async function runNew(name, options) {
|
|
|
10006
10355
|
const npmAuth = resolveNpmAuth(options.npmAuth, registry, ci);
|
|
10007
10356
|
const stack = await resolveStack(options);
|
|
10008
10357
|
const nxCloud = options.nxCloud ?? (options.yes ? false : await promptNxCloud());
|
|
10009
|
-
const stagingParent = adoptTarget === void 0 ? process.cwd() : (0,
|
|
10010
|
-
let workspaceRoot = (0,
|
|
10358
|
+
const stagingParent = adoptTarget === void 0 ? process.cwd() : (0, import_node_fs41.mkdtempSync)((0, import_node_path50.join)((0, import_node_os2.tmpdir)(), "mnci-new-"));
|
|
10359
|
+
let workspaceRoot = (0, import_node_path50.join)(stagingParent, workspaceName);
|
|
10011
10360
|
try {
|
|
10012
10361
|
logger.step(`Creating Nx workspace '${workspaceName}' (preset: ts)`);
|
|
10013
10362
|
runNpx(
|
|
@@ -10030,7 +10379,7 @@ async function runNew(name, options) {
|
|
|
10030
10379
|
workspaceRoot = adoptTarget;
|
|
10031
10380
|
}
|
|
10032
10381
|
} finally {
|
|
10033
|
-
if (adoptTarget !== void 0) (0,
|
|
10382
|
+
if (adoptTarget !== void 0) (0, import_node_fs41.rmSync)(stagingParent, { recursive: true, force: true });
|
|
10034
10383
|
}
|
|
10035
10384
|
logger.step(
|
|
10036
10385
|
"Applying MoNecromanCI overlay (VS Code workspace, release config, .npmrc, commitlint, pipeline, stack)"
|
|
@@ -10040,8 +10389,8 @@ async function runNew(name, options) {
|
|
|
10040
10389
|
{ workspaceName, scope, registry, agent, variableGroup, ci, stack, ...npmAuth && { npmAuth } },
|
|
10041
10390
|
logger.detail
|
|
10042
10391
|
);
|
|
10043
|
-
(0,
|
|
10044
|
-
(0,
|
|
10392
|
+
(0, import_node_fs41.rmSync)((0, import_node_path50.join)(workspaceRoot, "node_modules"), { recursive: true, force: true });
|
|
10393
|
+
(0, import_node_fs41.rmSync)((0, import_node_path50.join)(workspaceRoot, "package-lock.json"), { force: true });
|
|
10045
10394
|
logger.step("Installing the toolchain (commitlint + husky + linting/formatting)");
|
|
10046
10395
|
const installStatus = runShell(
|
|
10047
10396
|
"npm",
|
|
@@ -10143,6 +10492,12 @@ function buildProgram(cliVersion) {
|
|
|
10143
10492
|
).option(
|
|
10144
10493
|
"--empty",
|
|
10145
10494
|
"npm-lib, internal-lib, react-lib, react-internal-lib, node-function-app: scaffold the slice skeleton only, with no sample code or spec"
|
|
10495
|
+
).option("--app <project>", "container only: the app to put in an image (a node-app, react-app or go-app)").option("--port <port>", "container only: the port the app listens on, exposed by the image and published by start").option(
|
|
10496
|
+
"--e2e",
|
|
10497
|
+
"react-app only: also scaffold a Playwright end-to-end project, <name>-e2e, that runs the app and checks its greeting; its e2e target needs a browser (npx playwright install) and is not part of CI verify"
|
|
10498
|
+
).option(
|
|
10499
|
+
"--esm",
|
|
10500
|
+
'node-app, node-function-app: ES module output ("type": "module", explicit .js import specifiers, Jest mapped to match); not with fastify or nest'
|
|
10146
10501
|
).option(
|
|
10147
10502
|
"--lib <name>",
|
|
10148
10503
|
"python-vendor only: the internal Python library (libs/<name>) to vendor into <name>"
|