@lenne.tech/cli 1.50.6 → 1.51.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/build/commands/claude/plugins.js +29 -16
- package/build/commands/cli/create.js +11 -3
- package/build/commands/cli/rename.js +10 -2
- package/build/commands/dev/up.js +9 -0
- package/build/commands/directus/docker-setup.js +2 -2
- package/build/commands/directus/remove.js +1 -1
- package/build/commands/directus/typegen.js +31 -4
- package/build/commands/frontend/convert-mode.js +16 -0
- package/build/commands/frontend/nuxt.js +1 -1
- package/build/commands/fullstack/add-api.js +1 -2
- package/build/commands/fullstack/add-app.js +1 -1
- package/build/commands/fullstack/convert-mode.js +20 -0
- package/build/commands/fullstack/init.js +9 -6
- package/build/commands/git/clean.js +3 -2
- package/build/commands/git/create.js +7 -2
- package/build/commands/git/force-pull.js +4 -2
- package/build/commands/git/get.js +19 -6
- package/build/commands/git/rebase.js +13 -3
- package/build/commands/git/rename.js +5 -4
- package/build/commands/git/reset.js +18 -10
- package/build/commands/git/squash.js +4 -2
- package/build/commands/git/update.js +2 -1
- package/build/commands/npm/reinit.js +3 -3
- package/build/commands/server/add-property.js +10 -0
- package/build/commands/server/convert-mode.js +16 -0
- package/build/commands/server/permissions.js +10 -10
- package/build/commands/starter/chrome-extension.js +8 -2
- package/build/commands/typescript/create.js +3 -2
- package/build/extensions/api-mode.js +1 -1
- package/build/extensions/frontend-helper.js +25 -13
- package/build/extensions/git.js +25 -14
- package/build/extensions/server.js +14 -5
- package/build/extensions/template.js +8 -5
- package/build/extensions/typescript.js +4 -3
- package/build/lib/caddy.js +72 -2
- package/build/lib/claude-cli.js +17 -2
- package/build/lib/exec-args.js +117 -0
- package/build/lib/plugin-permissions.js +201 -0
- package/build/lib/plugin-utils.js +96 -36
- package/build/lib/safe-paths.js +57 -0
- package/build/lib/unknown-options.js +53 -0
- package/build/lib/workspace-integration.js +4 -2
- package/docs/commands.md +12 -0
- package/package.json +6 -6
|
@@ -9,6 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const exec_args_1 = require("../../lib/exec-args");
|
|
12
13
|
/**
|
|
13
14
|
* Rename branch
|
|
14
15
|
*/
|
|
@@ -20,7 +21,7 @@ const NewCommand = {
|
|
|
20
21
|
run: (toolbox) => __awaiter(void 0, void 0, void 0, function* () {
|
|
21
22
|
var _a, _b, _c;
|
|
22
23
|
// Retrieve the tools we need
|
|
23
|
-
const { config, git, helper, parameters, print: { error, info, spin, success, warning }, prompt: { confirm }, system: {
|
|
24
|
+
const { config, git, helper, parameters, print: { error, info, spin, success, warning }, prompt: { confirm }, system: { startTimer }, } = toolbox;
|
|
24
25
|
// Load configuration
|
|
25
26
|
const ltConfig = config.loadConfig();
|
|
26
27
|
// Parse CLI arguments
|
|
@@ -85,10 +86,10 @@ const NewCommand = {
|
|
|
85
86
|
const remote = yield git.getBranch(name, { exact: true, remote: true });
|
|
86
87
|
// Rename branch
|
|
87
88
|
const renameSpin = spin(`Rename ${branch} into ${name}`);
|
|
88
|
-
yield
|
|
89
|
+
yield (0, exec_args_1.execArgs)('git', ['branch', '-m', (0, exec_args_1.safeRef)(name)]);
|
|
89
90
|
// Ask to push branch
|
|
90
91
|
if (remote && (noConfirm || (yield confirm(`Push ${name} to remote?`)))) {
|
|
91
|
-
yield
|
|
92
|
+
yield (0, exec_args_1.execArgs)('git', ['push', 'origin', (0, exec_args_1.safeRef)(name)]);
|
|
92
93
|
}
|
|
93
94
|
renameSpin.succeed();
|
|
94
95
|
// Save time
|
|
@@ -98,7 +99,7 @@ const NewCommand = {
|
|
|
98
99
|
(parameters.options.deleteRemote || (!noConfirm && (yield confirm(`Delete remote branch ${branch}?`))))) {
|
|
99
100
|
timer = startTimer();
|
|
100
101
|
const deleteSpin = spin(`Delete remote branch ${branch}`);
|
|
101
|
-
yield
|
|
102
|
+
yield (0, exec_args_1.execArgs)('git', ['push', 'origin', `:${(0, exec_args_1.safeRef)(branch)}`]);
|
|
102
103
|
deleteSpin.succeed();
|
|
103
104
|
time += timer();
|
|
104
105
|
}
|
|
@@ -10,6 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
const path_1 = require("path");
|
|
13
|
+
const exec_args_1 = require("../../lib/exec-args");
|
|
13
14
|
const git_env_1 = require("../../lib/git-env");
|
|
14
15
|
/**
|
|
15
16
|
* Environment that keeps the `git ls-remote` below non-interactive.
|
|
@@ -66,7 +67,9 @@ const NewCommand = {
|
|
|
66
67
|
// Check remote (use short SSH timeout so ls-remote doesn't hang in offline environments)
|
|
67
68
|
let remoteBranch = '';
|
|
68
69
|
try {
|
|
69
|
-
remoteBranch = yield
|
|
70
|
+
remoteBranch = yield (0, exec_args_1.execArgs)('git', ['ls-remote', '--heads', 'origin', (0, exec_args_1.safeRef)(branch)], {
|
|
71
|
+
env: (0, git_env_1.nonInteractiveGitEnv)(),
|
|
72
|
+
});
|
|
70
73
|
}
|
|
71
74
|
catch (_d) {
|
|
72
75
|
// ignore - unreachable remote is reported as "no remote branch" below
|
|
@@ -95,7 +98,7 @@ const NewCommand = {
|
|
|
95
98
|
// Show commits that would be lost (none listed when the upstream ref is unknown locally)
|
|
96
99
|
let localCommits = '';
|
|
97
100
|
try {
|
|
98
|
-
localCommits = yield
|
|
101
|
+
localCommits = yield (0, exec_args_1.execArgs)('git', ['log', `origin/${(0, exec_args_1.safeRef)(branch)}..HEAD`, '--oneline']);
|
|
99
102
|
}
|
|
100
103
|
catch (_e) {
|
|
101
104
|
// ignore - no upstream ref, so nothing ahead to report
|
|
@@ -124,14 +127,19 @@ const NewCommand = {
|
|
|
124
127
|
}
|
|
125
128
|
// Reset
|
|
126
129
|
const resetSpin = spin(`Reset ${branch}`);
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
'
|
|
130
|
-
'
|
|
131
|
-
'
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
'
|
|
130
|
+
// Argument lists, no shell: the current branch name can come from a remote (see exec-args.ts).
|
|
131
|
+
for (const args of [
|
|
132
|
+
['clean', '-fd'],
|
|
133
|
+
['reset', 'HEAD', '--hard'],
|
|
134
|
+
['checkout', 'main'],
|
|
135
|
+
['fetch'],
|
|
136
|
+
['pull'],
|
|
137
|
+
['branch', '-D', (0, exec_args_1.safeRef)(branch)],
|
|
138
|
+
['checkout', (0, exec_args_1.safeRef)(branch)],
|
|
139
|
+
['pull'],
|
|
140
|
+
]) {
|
|
141
|
+
yield (0, exec_args_1.execArgs)('git', args);
|
|
142
|
+
}
|
|
135
143
|
resetSpin.succeed();
|
|
136
144
|
// Install packages with correctly detected package manager (supports monorepo lockfiles)
|
|
137
145
|
const { path: pkgPath } = yield npm.getPackageJson();
|
|
@@ -9,6 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const exec_args_1 = require("../../lib/exec-args");
|
|
12
13
|
/**
|
|
13
14
|
* Squash branch
|
|
14
15
|
*/
|
|
@@ -74,7 +75,7 @@ const NewCommand = {
|
|
|
74
75
|
return `dry-run squash branch ${branch} (no merge base)`;
|
|
75
76
|
}
|
|
76
77
|
// Show commits that would be squashed
|
|
77
|
-
const commitsToSquash = yield
|
|
78
|
+
const commitsToSquash = yield (0, exec_args_1.execArgs)('git', ['log', `${(0, exec_args_1.safeRef)(mergeBase)}..HEAD`, '--oneline']);
|
|
78
79
|
if (commitsToSquash === null || commitsToSquash === void 0 ? void 0 : commitsToSquash.trim()) {
|
|
79
80
|
const commitCount = commitsToSquash.trim().split('\n').length;
|
|
80
81
|
info(`Would squash ${commitCount} commit(s) on branch "${branch}" into base "${base}":`);
|
|
@@ -201,7 +202,8 @@ const NewCommand = {
|
|
|
201
202
|
// Start spinner
|
|
202
203
|
const commitSpin = spin('Commit');
|
|
203
204
|
// Commit and push
|
|
204
|
-
|
|
205
|
+
// Argument list, no shell: message and author are free text from the user or lt.config.
|
|
206
|
+
yield (0, exec_args_1.execArgs)('git', ['commit', '-am', message, `--author=${author}`]);
|
|
205
207
|
commitSpin.succeed();
|
|
206
208
|
if (!noConfirm && !(yield confirm('Push force?'))) {
|
|
207
209
|
return;
|
|
@@ -10,6 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
const path_1 = require("path");
|
|
13
|
+
const exec_args_1 = require("../../lib/exec-args");
|
|
13
14
|
const git_env_1 = require("../../lib/git-env");
|
|
14
15
|
/**
|
|
15
16
|
* Environment that keeps the `git` calls below non-interactive.
|
|
@@ -74,7 +75,7 @@ const NewCommand = {
|
|
|
74
75
|
// Check for incoming commits (none yet when the upstream ref is unknown locally)
|
|
75
76
|
let incomingCommits = '';
|
|
76
77
|
try {
|
|
77
|
-
incomingCommits = yield
|
|
78
|
+
incomingCommits = yield (0, exec_args_1.execArgs)('git', ['log', `${(0, exec_args_1.safeRef)(branch)}..origin/${branch}`, '--oneline']);
|
|
78
79
|
}
|
|
79
80
|
catch (_e) {
|
|
80
81
|
// ignore - no upstream ref, so nothing incoming to report
|
|
@@ -76,7 +76,7 @@ const NewCommand = {
|
|
|
76
76
|
const detectedPm = pm.detect((0, path_1.dirname)(path));
|
|
77
77
|
if (data.scripts && data.scripts.reinit) {
|
|
78
78
|
const ownReinitSpin = spin('Reinitialize packages');
|
|
79
|
-
yield system.run(
|
|
79
|
+
yield system.run(pm.run('reinit', detectedPm), { cwd: (0, path_1.dirname)(path) });
|
|
80
80
|
ownReinitSpin.succeed();
|
|
81
81
|
}
|
|
82
82
|
else {
|
|
@@ -92,12 +92,12 @@ const NewCommand = {
|
|
|
92
92
|
reinitSpin.succeed();
|
|
93
93
|
if (data.scripts && data.scripts['test:e2e']) {
|
|
94
94
|
const testE2eSpin = spin('Run tests');
|
|
95
|
-
yield system.run(
|
|
95
|
+
yield system.run(pm.run('test:e2e', detectedPm), { cwd: (0, path_1.dirname)(path) });
|
|
96
96
|
testE2eSpin.succeed();
|
|
97
97
|
}
|
|
98
98
|
else if (data.scripts && data.scripts && data.scripts.test) {
|
|
99
99
|
const testSpin = spin('Run tests');
|
|
100
|
-
yield system.run(
|
|
100
|
+
yield system.run(pm.run('test', detectedPm), { cwd: (0, path_1.dirname)(path) });
|
|
101
101
|
testSpin.succeed();
|
|
102
102
|
}
|
|
103
103
|
}
|
|
@@ -15,7 +15,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
exports.help = void 0;
|
|
16
16
|
const path_1 = require("path");
|
|
17
17
|
const ts_morph_1 = require("ts-morph");
|
|
18
|
+
const fail_run_1 = require("../../lib/fail-run");
|
|
18
19
|
const framework_detection_1 = require("../../lib/framework-detection");
|
|
20
|
+
const safe_paths_1 = require("../../lib/safe-paths");
|
|
19
21
|
const module_1 = __importDefault(require("./module"));
|
|
20
22
|
const object_1 = __importDefault(require("./object"));
|
|
21
23
|
/**
|
|
@@ -121,6 +123,14 @@ const NewCommand = {
|
|
|
121
123
|
error(`No src directory in "${path}".`);
|
|
122
124
|
return;
|
|
123
125
|
}
|
|
126
|
+
// One directory name, nothing else: `--element ../../../other-project/src/server/modules/x`
|
|
127
|
+
// passed the existence check below and edited another project.
|
|
128
|
+
if (!(0, safe_paths_1.isSafePathSegment)(String(elementToEdit))) {
|
|
129
|
+
info('');
|
|
130
|
+
error(`"${elementToEdit}" is not a ${String(objectOrModule).toLowerCase()} name: no "/", "\\" or "..".`);
|
|
131
|
+
(0, fail_run_1.failRun)(toolbox);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
124
134
|
// Verify the target module/object directory exists
|
|
125
135
|
const targetDir = objectOrModule === 'Module'
|
|
126
136
|
? (0, path_1.join)(path, 'src', 'server', 'modules', elementToEdit)
|
|
@@ -10,7 +10,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.help = void 0;
|
|
13
|
+
const fail_run_1 = require("../../lib/fail-run");
|
|
13
14
|
const framework_detection_1 = require("../../lib/framework-detection");
|
|
15
|
+
const unknown_options_1 = require("../../lib/unknown-options");
|
|
16
|
+
/** The flag names `lt fullstack convert-mode` uses for the same thing, mapped to the real ones for the error message. */
|
|
17
|
+
const RENAMED_FLAGS = {
|
|
18
|
+
'framework-upstream-branch': 'upstream-branch',
|
|
19
|
+
'framework-version': 'version',
|
|
20
|
+
};
|
|
14
21
|
/**
|
|
15
22
|
* Convert an existing API project between npm mode and vendor mode.
|
|
16
23
|
*
|
|
@@ -67,6 +74,15 @@ const ConvertModeCommand = {
|
|
|
67
74
|
if (toolbox.tools.helpJson(exports.help)) {
|
|
68
75
|
return;
|
|
69
76
|
}
|
|
77
|
+
// Refuse flags this command does not know: a misspelt --skip-* would otherwise be ignored
|
|
78
|
+
// and the conversion would touch what the caller asked to leave alone (see unknown-options.ts).
|
|
79
|
+
const declaredFlags = exports.help.options.map((option) => option.flag);
|
|
80
|
+
const unknownFlags = (0, unknown_options_1.findUnknownOptions)(parameters.options, declaredFlags);
|
|
81
|
+
if (unknownFlags.length > 0) {
|
|
82
|
+
error((0, unknown_options_1.formatUnknownOptions)(unknownFlags, declaredFlags, RENAMED_FLAGS));
|
|
83
|
+
(0, fail_run_1.failRun)(toolbox);
|
|
84
|
+
return 'convert-mode: unknown option';
|
|
85
|
+
}
|
|
70
86
|
const targetMode = parameters.options.to;
|
|
71
87
|
if (!targetMode || !['npm', 'vendor'].includes(targetMode)) {
|
|
72
88
|
error('Missing or invalid --to flag. Use: --to vendor or --to npm');
|
|
@@ -10,10 +10,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.help = void 0;
|
|
13
|
-
const child_process_1 = require("child_process");
|
|
14
13
|
const fs_1 = require("fs");
|
|
15
14
|
const path_1 = require("path");
|
|
16
15
|
const framework_detection_1 = require("../../lib/framework-detection");
|
|
16
|
+
const safe_paths_1 = require("../../lib/safe-paths");
|
|
17
17
|
// ────────────────────────────────────────────────────────────────────────────
|
|
18
18
|
// Helper functions (alphabetically sorted per ESLint rules)
|
|
19
19
|
// ────────────────────────────────────────────────────────────────────────────
|
|
@@ -132,14 +132,6 @@ function loadScanner(projectPath) {
|
|
|
132
132
|
return null;
|
|
133
133
|
});
|
|
134
134
|
}
|
|
135
|
-
/**
|
|
136
|
-
* Open a file in the default browser/application
|
|
137
|
-
*/
|
|
138
|
-
function openFile(filePath) {
|
|
139
|
-
const platform = process.platform;
|
|
140
|
-
const cmd = platform === 'darwin' ? 'open' : platform === 'win32' ? 'start' : 'xdg-open';
|
|
141
|
-
(0, child_process_1.exec)(`${cmd} "${filePath}"`);
|
|
142
|
-
}
|
|
143
135
|
/**
|
|
144
136
|
* Print console summary
|
|
145
137
|
*/
|
|
@@ -313,6 +305,13 @@ const PermissionsCommand = {
|
|
|
313
305
|
defaultValue: defaultOutputName,
|
|
314
306
|
}) || defaultOutputName;
|
|
315
307
|
const outputPath = (0, path_1.join)(projectPath, outputFile);
|
|
308
|
+
// --output and lt.config's `output` must not write outside the project (`../../x`).
|
|
309
|
+
if (!(0, safe_paths_1.isPathInside)(projectPath, outputPath)) {
|
|
310
|
+
error(`Output ${outputFile} lies outside the project ${projectPath}. Use a path inside the project.`);
|
|
311
|
+
if (!parameters.options.fromGluegunMenu)
|
|
312
|
+
process.exit(1);
|
|
313
|
+
return 'permissions: output outside project';
|
|
314
|
+
}
|
|
316
315
|
// Load scanner from project's @lenne.tech/nest-server
|
|
317
316
|
const spinner = spin('Loading permissions scanner...');
|
|
318
317
|
const scanner = yield loadScanner(projectPath);
|
|
@@ -374,7 +373,8 @@ const PermissionsCommand = {
|
|
|
374
373
|
}
|
|
375
374
|
// Open in browser
|
|
376
375
|
if (shouldOpen && (format === 'html' || format === 'md')) {
|
|
377
|
-
|
|
376
|
+
// No shell: the file name comes from --output or lt.config (see safe-paths.ts).
|
|
377
|
+
(0, safe_paths_1.openFileWithDefaultApp)(outputPath);
|
|
378
378
|
info(`Report opened in default application`);
|
|
379
379
|
}
|
|
380
380
|
// Summary line (always shown)
|
|
@@ -9,6 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const exec_args_1 = require("../../lib/exec-args");
|
|
12
13
|
/**
|
|
13
14
|
* Create a new TypeScript project
|
|
14
15
|
*/
|
|
@@ -46,7 +47,12 @@ const NewCommand = {
|
|
|
46
47
|
}
|
|
47
48
|
// Clone git repository
|
|
48
49
|
const cloneSpinner = spin('Clone https://github.com/lenneTech/chrome-extension-angular-starter.git');
|
|
49
|
-
yield
|
|
50
|
+
yield (0, exec_args_1.execArgs)('git', [
|
|
51
|
+
'clone',
|
|
52
|
+
'--',
|
|
53
|
+
'https://github.com/lenneTech/chrome-extension-angular-starter.git',
|
|
54
|
+
projectDir,
|
|
55
|
+
]);
|
|
50
56
|
if (filesystem.isDirectory(`./${projectDir}`)) {
|
|
51
57
|
filesystem.remove(`./${projectDir}/.git`);
|
|
52
58
|
cloneSpinner.succeed('Repository cloned from https://github.com/lenneTech/chrome-extension-angular-starter.git');
|
|
@@ -102,7 +108,7 @@ const NewCommand = {
|
|
|
102
108
|
prepareSpinner.succeed('Files prepared');
|
|
103
109
|
// Install packages
|
|
104
110
|
const installSpinner = spin('Install packages');
|
|
105
|
-
yield system.run(
|
|
111
|
+
yield system.run(toolbox.pm.install(toolbox.pm.detect(projectDir)), { cwd: projectDir });
|
|
106
112
|
installSpinner.succeed('Packages installed');
|
|
107
113
|
// Init git
|
|
108
114
|
const initGitSpinner = spin('Initialize git');
|
|
@@ -10,6 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
const path_1 = require("path");
|
|
13
|
+
const exec_args_1 = require("../../lib/exec-args");
|
|
13
14
|
/**
|
|
14
15
|
* Create a new TypeScript project
|
|
15
16
|
*/
|
|
@@ -61,7 +62,7 @@ const NewCommand = {
|
|
|
61
62
|
// Clone git repository
|
|
62
63
|
const cloneSpinner = spin('Clone https://github.com/lenneTech/typescript-starter.git');
|
|
63
64
|
try {
|
|
64
|
-
yield
|
|
65
|
+
yield (0, exec_args_1.execArgs)('git', ['clone', '--', 'https://github.com/lenneTech/typescript-starter.git', projectDir]);
|
|
65
66
|
if (filesystem.isDirectory(`./${projectDir}`)) {
|
|
66
67
|
filesystem.remove(`./${projectDir}/.git`);
|
|
67
68
|
cloneSpinner.succeed('Repository cloned from https://github.com/lenneTech/typescript-starter.git');
|
|
@@ -153,7 +154,7 @@ const NewCommand = {
|
|
|
153
154
|
// Install packages
|
|
154
155
|
const installSpinner = spin('Install packages');
|
|
155
156
|
try {
|
|
156
|
-
yield system.run(
|
|
157
|
+
yield system.run(toolbox.pm.install(toolbox.pm.detect(projectDir)), { cwd: projectDir });
|
|
157
158
|
installSpinner.succeed('Packages installed');
|
|
158
159
|
}
|
|
159
160
|
catch (err) {
|
|
@@ -103,7 +103,7 @@ class ApiMode {
|
|
|
103
103
|
const { pm, system } = this.toolbox;
|
|
104
104
|
const runner = (_c = (_b = pm === null || pm === void 0 ? void 0 : pm.run) === null || _b === void 0 ? void 0 : _b.call(pm, formatScript, pm.detect(projectPath))) !== null && _c !== void 0 ? _c : `pnpm run ${formatScript}`;
|
|
105
105
|
try {
|
|
106
|
-
yield system.run(
|
|
106
|
+
yield system.run(runner, { cwd: projectPath });
|
|
107
107
|
}
|
|
108
108
|
catch (_e) {
|
|
109
109
|
// Non-fatal: the user can run format manually if this misbehaves.
|
|
@@ -11,6 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.FrontendHelper = void 0;
|
|
13
13
|
const check_freshness_hooks_1 = require("../lib/check-freshness-hooks");
|
|
14
|
+
const exec_args_1 = require("../lib/exec-args");
|
|
14
15
|
const markdown_table_1 = require("../lib/markdown-table");
|
|
15
16
|
const module_specifiers_1 = require("../lib/module-specifiers");
|
|
16
17
|
const strip_vendor_schema_augmentation_1 = require("../lib/strip-vendor-schema-augmentation");
|
|
@@ -184,7 +185,8 @@ class FrontendHelper {
|
|
|
184
185
|
if (!skipInstall && result.method !== 'link') {
|
|
185
186
|
try {
|
|
186
187
|
const { pm } = this.toolbox;
|
|
187
|
-
|
|
188
|
+
// `cwd` instead of `cd "<dest>" &&`: the directory name must not be shell syntax.
|
|
189
|
+
yield system.run(pm.install(pm.detect(dest)), { cwd: dest });
|
|
188
190
|
}
|
|
189
191
|
catch (_a) {
|
|
190
192
|
return { method: result.method, path: dest, success: false };
|
|
@@ -223,7 +225,8 @@ class FrontendHelper {
|
|
|
223
225
|
if (!skipInstall) {
|
|
224
226
|
try {
|
|
225
227
|
const { pm } = this.toolbox;
|
|
226
|
-
|
|
228
|
+
// `cwd` instead of `cd "<dest>" &&`: the directory name must not be shell syntax.
|
|
229
|
+
yield system.run(pm.install(pm.detect(dest)), { cwd: dest });
|
|
227
230
|
}
|
|
228
231
|
catch (err) {
|
|
229
232
|
return { method: result.method, path: dest, success: false };
|
|
@@ -232,12 +235,13 @@ class FrontendHelper {
|
|
|
232
235
|
// Initialize git
|
|
233
236
|
if (!skipGitInit) {
|
|
234
237
|
try {
|
|
235
|
-
|
|
238
|
+
// Argument lists, no shell: gitLink comes from a CLI flag or lt.config (see exec-args.ts).
|
|
239
|
+
yield (0, exec_args_1.execArgs)('git', ['init', '--initial-branch=main'], { cwd: dest });
|
|
236
240
|
if (gitLink) {
|
|
237
|
-
yield
|
|
238
|
-
yield
|
|
239
|
-
yield
|
|
240
|
-
yield
|
|
241
|
+
yield (0, exec_args_1.execArgs)('git', ['remote', 'add', '--', 'origin', gitLink], { cwd: dest });
|
|
242
|
+
yield (0, exec_args_1.execArgs)('git', ['add', '.'], { cwd: dest });
|
|
243
|
+
yield (0, exec_args_1.execArgs)('git', ['commit', '-m', 'Initial commit'], { cwd: dest });
|
|
244
|
+
yield (0, exec_args_1.execArgs)('git', ['push', '-u', 'origin', 'main'], { cwd: dest });
|
|
241
245
|
}
|
|
242
246
|
}
|
|
243
247
|
catch (err) {
|
|
@@ -260,7 +264,7 @@ class FrontendHelper {
|
|
|
260
264
|
// Add localize
|
|
261
265
|
if (localize) {
|
|
262
266
|
try {
|
|
263
|
-
yield system.run(
|
|
267
|
+
yield system.run('ng add @angular/localize --skip-confirmation', { cwd: dest });
|
|
264
268
|
}
|
|
265
269
|
catch (_a) {
|
|
266
270
|
// Localize failure is not fatal
|
|
@@ -270,7 +274,7 @@ class FrontendHelper {
|
|
|
270
274
|
if (!skipInstall) {
|
|
271
275
|
try {
|
|
272
276
|
const { pm: pmHelper } = this.toolbox;
|
|
273
|
-
yield system.run(
|
|
277
|
+
yield system.run(pmHelper.run('init', pmHelper.detect(dest)), { cwd: dest });
|
|
274
278
|
}
|
|
275
279
|
catch (_b) {
|
|
276
280
|
// Init script failure is not fatal
|
|
@@ -421,13 +425,21 @@ class FrontendHelper {
|
|
|
421
425
|
return __awaiter(this, void 0, void 0, function* () {
|
|
422
426
|
const { dest, upstreamBranch, upstreamRepoUrl = 'https://github.com/lenneTech/nuxt-extensions.git' } = options;
|
|
423
427
|
const path = require('node:path');
|
|
424
|
-
const { filesystem
|
|
428
|
+
const { filesystem } = this.toolbox;
|
|
425
429
|
const coreDir = path.join(dest, 'app', 'core');
|
|
426
430
|
// ── 1. Clone @lenne.tech/nuxt-extensions into temp dir ──────────────
|
|
427
431
|
const tmpClone = path.join(require('os').tmpdir(), `lt-vendor-nuxt-ext-${Date.now()}`);
|
|
428
|
-
const branchArg = upstreamBranch ? `--branch ${upstreamBranch} ` : '';
|
|
429
432
|
try {
|
|
430
|
-
|
|
433
|
+
// Argument list, no shell: the branch comes from a CLI flag or lt.config (see exec-args.ts).
|
|
434
|
+
yield (0, exec_args_1.execArgs)('git', [
|
|
435
|
+
'clone',
|
|
436
|
+
'--depth',
|
|
437
|
+
'1',
|
|
438
|
+
...(upstreamBranch ? ['--branch', upstreamBranch] : []),
|
|
439
|
+
'--',
|
|
440
|
+
upstreamRepoUrl,
|
|
441
|
+
tmpClone,
|
|
442
|
+
]);
|
|
431
443
|
}
|
|
432
444
|
catch (err) {
|
|
433
445
|
const raw = err.message || '';
|
|
@@ -476,7 +488,7 @@ class FrontendHelper {
|
|
|
476
488
|
}
|
|
477
489
|
let upstreamCommit = '';
|
|
478
490
|
try {
|
|
479
|
-
const sha = yield
|
|
491
|
+
const sha = yield (0, exec_args_1.execArgs)('git', ['-C', tmpClone, 'rev-parse', 'HEAD']);
|
|
480
492
|
upstreamCommit = (sha || '').trim();
|
|
481
493
|
}
|
|
482
494
|
catch (_c) {
|
package/build/extensions/git.js
CHANGED
|
@@ -10,6 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.Git = void 0;
|
|
13
|
+
const exec_args_1 = require("../lib/exec-args");
|
|
13
14
|
const git_env_1 = require("../lib/git-env");
|
|
14
15
|
/**
|
|
15
16
|
* Git functions
|
|
@@ -96,10 +97,18 @@ class Git {
|
|
|
96
97
|
showWarning: false,
|
|
97
98
|
}, options);
|
|
98
99
|
// Toolbox features
|
|
99
|
-
const { print: { warning },
|
|
100
|
+
const { print: { warning }, } = this.toolbox;
|
|
100
101
|
// Get diff
|
|
101
102
|
try {
|
|
102
|
-
|
|
103
|
+
// Every git call in this file that carries a value runs as an argument list, no shell:
|
|
104
|
+
// branch names come from the user, from lt.config and from the remote (see exec-args.ts).
|
|
105
|
+
const diff = yield (0, exec_args_1.execArgs)('git', [
|
|
106
|
+
'--no-pager',
|
|
107
|
+
'diff',
|
|
108
|
+
'--name-only',
|
|
109
|
+
(0, exec_args_1.safeRef)(branch),
|
|
110
|
+
(0, exec_args_1.safeRef)(opts.otherBranch),
|
|
111
|
+
]);
|
|
103
112
|
// Return relative file paths as array
|
|
104
113
|
return diff.split(/\r?\n/).filter((item) => item);
|
|
105
114
|
}
|
|
@@ -147,8 +156,8 @@ class Git {
|
|
|
147
156
|
getMergeBase() {
|
|
148
157
|
return __awaiter(this, arguments, void 0, function* (baseBranch = 'dev') {
|
|
149
158
|
// Toolbox features
|
|
150
|
-
const { helper: { trim },
|
|
151
|
-
return trim(yield
|
|
159
|
+
const { helper: { trim }, } = this.toolbox;
|
|
160
|
+
return trim(yield (0, exec_args_1.execArgs)('git', ['merge-base', 'HEAD', (0, exec_args_1.safeRef)(baseBranch)]));
|
|
152
161
|
});
|
|
153
162
|
}
|
|
154
163
|
/**
|
|
@@ -163,10 +172,9 @@ class Git {
|
|
|
163
172
|
throw new Error('Missing branch');
|
|
164
173
|
}
|
|
165
174
|
// Toolbox features
|
|
166
|
-
const { helper: { trim },
|
|
175
|
+
const { helper: { trim }, } = this.toolbox;
|
|
167
176
|
try {
|
|
168
|
-
const
|
|
169
|
-
const output = yield run(logCommand);
|
|
177
|
+
const output = yield (0, exec_args_1.execArgs)('git', ['log', `${(0, exec_args_1.safeRef)(baseBranch)}..${(0, exec_args_1.safeRef)(branch)}`, '--oneline']);
|
|
170
178
|
if (!output) {
|
|
171
179
|
throw new Error('No commits found');
|
|
172
180
|
}
|
|
@@ -277,14 +285,18 @@ class Git {
|
|
|
277
285
|
}
|
|
278
286
|
// Search branch
|
|
279
287
|
if (opts.exact) {
|
|
280
|
-
if (
|
|
281
|
-
|
|
288
|
+
if (!(0, exec_args_1.isSafeRef)(branch)) {
|
|
289
|
+
// Cannot be a branch name; report it as not found instead of handing it to git.
|
|
290
|
+
branch = null;
|
|
291
|
+
}
|
|
292
|
+
else if (opts.remote) {
|
|
293
|
+
if (!(yield (0, exec_args_1.execArgs)('git', ['ls-remote', '--heads', 'origin', (0, exec_args_1.safeRef)(branch)]))) {
|
|
282
294
|
branch = null;
|
|
283
295
|
}
|
|
284
296
|
}
|
|
285
297
|
else {
|
|
286
298
|
try {
|
|
287
|
-
yield
|
|
299
|
+
yield (0, exec_args_1.execArgs)('git', ['rev-parse', '--verify', (0, exec_args_1.safeRef)(branch)]);
|
|
288
300
|
}
|
|
289
301
|
catch (e) {
|
|
290
302
|
branch = null;
|
|
@@ -310,7 +322,7 @@ class Git {
|
|
|
310
322
|
branch = trim(branch);
|
|
311
323
|
// Check remote, if not done before
|
|
312
324
|
if (opts.remote && !opts.exact) {
|
|
313
|
-
const remoteBranch = trim(yield
|
|
325
|
+
const remoteBranch = trim(yield (0, exec_args_1.execArgs)('git', ['ls-remote', '--heads', 'origin', (0, exec_args_1.safeRef)(branch)]));
|
|
314
326
|
if (!remoteBranch) {
|
|
315
327
|
if (opts.spin) {
|
|
316
328
|
searchSpin.fail();
|
|
@@ -323,7 +335,7 @@ class Git {
|
|
|
323
335
|
}
|
|
324
336
|
// Check local
|
|
325
337
|
if (opts.local) {
|
|
326
|
-
const remoteBranch = trim(yield
|
|
338
|
+
const remoteBranch = trim(yield (0, exec_args_1.execArgs)('git', ['rev-parse', '--verify', '--quiet', (0, exec_args_1.safeRef)(branch)]));
|
|
327
339
|
if (!remoteBranch) {
|
|
328
340
|
if (opts.spin) {
|
|
329
341
|
searchSpin.fail();
|
|
@@ -357,8 +369,7 @@ class Git {
|
|
|
357
369
|
*/
|
|
358
370
|
reset(mergeBase, soft = false) {
|
|
359
371
|
// Toolbox features
|
|
360
|
-
|
|
361
|
-
return run(soft ? `git reset --soft ${mergeBase}` : `git reset ${mergeBase}`);
|
|
372
|
+
return (0, exec_args_1.execArgs)('git', soft ? ['reset', '--soft', (0, exec_args_1.safeRef)(mergeBase)] : ['reset', (0, exec_args_1.safeRef)(mergeBase)]);
|
|
362
373
|
}
|
|
363
374
|
/**
|
|
364
375
|
* Select a branch
|
|
@@ -50,6 +50,7 @@ const ts = __importStar(require("typescript"));
|
|
|
50
50
|
const adopt_upstream_build_allowlist_1 = require("../lib/adopt-upstream-build-allowlist");
|
|
51
51
|
const check_freshness_hooks_1 = require("../lib/check-freshness-hooks");
|
|
52
52
|
const cross_env_1 = require("../lib/cross-env");
|
|
53
|
+
const exec_args_1 = require("../lib/exec-args");
|
|
53
54
|
const express_type_imports_1 = require("../lib/express-type-imports");
|
|
54
55
|
const markdown_table_1 = require("../lib/markdown-table");
|
|
55
56
|
const migrate_scripts_1 = require("../lib/migrate-scripts");
|
|
@@ -762,7 +763,7 @@ class Server {
|
|
|
762
763
|
if (!skipInstall && !experimental) {
|
|
763
764
|
try {
|
|
764
765
|
const { pm } = this.toolbox;
|
|
765
|
-
yield system.run(
|
|
766
|
+
yield system.run(pm.install(pm.detect(dest)), { cwd: dest });
|
|
766
767
|
}
|
|
767
768
|
catch (err) {
|
|
768
769
|
return { method: result.method, path: dest, success: false };
|
|
@@ -958,7 +959,6 @@ class Server {
|
|
|
958
959
|
var _a;
|
|
959
960
|
const { dest, upstreamBranch, upstreamRepoUrl = 'https://github.com/lenneTech/nest-server.git' } = options;
|
|
960
961
|
const filesystem = this.filesystem;
|
|
961
|
-
const { system } = this.toolbox;
|
|
962
962
|
const os = require('os');
|
|
963
963
|
const path = require('path');
|
|
964
964
|
const { Project, SyntaxKind } = require('ts-morph');
|
|
@@ -970,9 +970,18 @@ class Server {
|
|
|
970
970
|
// `bin/migrate.js`, and associated meta files. The clone lives in a
|
|
971
971
|
// throw-away tmp dir that gets cleaned up at the end.
|
|
972
972
|
const tmpClone = path.join(os.tmpdir(), `lt-vendor-nest-server-${Date.now()}`);
|
|
973
|
-
const branchArg = upstreamBranch ? `--branch ${upstreamBranch} ` : '';
|
|
974
973
|
try {
|
|
975
|
-
|
|
974
|
+
// Argument list, no shell: the branch comes from --framework-upstream-branch or
|
|
975
|
+
// lt.config (see exec-args.ts).
|
|
976
|
+
yield (0, exec_args_1.execArgs)('git', [
|
|
977
|
+
'clone',
|
|
978
|
+
'--depth',
|
|
979
|
+
'1',
|
|
980
|
+
...(upstreamBranch ? ['--branch', upstreamBranch] : []),
|
|
981
|
+
'--',
|
|
982
|
+
upstreamRepoUrl,
|
|
983
|
+
tmpClone,
|
|
984
|
+
]);
|
|
976
985
|
}
|
|
977
986
|
catch (err) {
|
|
978
987
|
// Clone failures usually boil down to one of four causes — network,
|
|
@@ -1067,7 +1076,7 @@ class Server {
|
|
|
1067
1076
|
// Snapshot the upstream commit SHA for traceability in VENDOR.md.
|
|
1068
1077
|
let upstreamCommit = '';
|
|
1069
1078
|
try {
|
|
1070
|
-
const sha = yield
|
|
1079
|
+
const sha = yield (0, exec_args_1.execArgs)('git', ['-C', tmpClone, 'rev-parse', 'HEAD']);
|
|
1071
1080
|
upstreamCommit = (sha || '').trim();
|
|
1072
1081
|
}
|
|
1073
1082
|
catch (_f) {
|