@rs-x/cli 2.0.0-next.0 → 2.0.0-next.10
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 +10 -4
- package/bin/rsx.cjs +493 -149
- package/package.json +14 -1
- package/{rs-x-vscode-extension-2.0.0-next.0.vsix → rs-x-vscode-extension-2.0.0-next.10.vsix} +0 -0
- package/templates/angular-demo/README.md +115 -0
- package/templates/angular-demo/src/app/app.component.css +97 -0
- package/templates/angular-demo/src/app/app.component.html +58 -0
- package/templates/angular-demo/src/app/app.component.ts +52 -0
- package/templates/angular-demo/src/app/virtual-table/row-data.ts +35 -0
- package/templates/angular-demo/src/app/virtual-table/row-model.ts +45 -0
- package/templates/angular-demo/src/app/virtual-table/virtual-table-data.service.ts +136 -0
- package/templates/angular-demo/src/app/virtual-table/virtual-table-model.ts +224 -0
- package/templates/angular-demo/src/app/virtual-table/virtual-table.component.css +174 -0
- package/templates/angular-demo/src/app/virtual-table/virtual-table.component.html +50 -0
- package/templates/angular-demo/src/app/virtual-table/virtual-table.component.ts +83 -0
- package/templates/angular-demo/src/index.html +11 -0
- package/templates/angular-demo/src/main.ts +16 -0
- package/templates/angular-demo/src/styles.css +261 -0
package/bin/rsx.cjs
CHANGED
|
@@ -5,8 +5,22 @@ const path = require('node:path');
|
|
|
5
5
|
const readline = require('node:readline/promises');
|
|
6
6
|
const { spawnSync } = require('node:child_process');
|
|
7
7
|
|
|
8
|
-
const CLI_VERSION =
|
|
8
|
+
const CLI_VERSION = (() => {
|
|
9
|
+
try {
|
|
10
|
+
const packageJsonPath = path.join(__dirname, '..', 'package.json');
|
|
11
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
12
|
+
return packageJson.version ?? '0.0.0';
|
|
13
|
+
} catch {
|
|
14
|
+
return '0.0.0';
|
|
15
|
+
}
|
|
16
|
+
})();
|
|
9
17
|
const VS_CODE_EXTENSION_ID = 'rs-x.rs-x-vscode-extension';
|
|
18
|
+
const ANGULAR_DEMO_TEMPLATE_DIR = path.join(
|
|
19
|
+
__dirname,
|
|
20
|
+
'..',
|
|
21
|
+
'templates',
|
|
22
|
+
'angular-demo',
|
|
23
|
+
);
|
|
10
24
|
const RUNTIME_PACKAGES = [
|
|
11
25
|
'@rs-x/core',
|
|
12
26
|
'@rs-x/state-manager',
|
|
@@ -178,15 +192,38 @@ function detectPackageManager(explicitPm) {
|
|
|
178
192
|
return 'npm';
|
|
179
193
|
}
|
|
180
194
|
|
|
195
|
+
function applyTagToPackages(packages, tag) {
|
|
196
|
+
return packages.map((pkg) => {
|
|
197
|
+
const lastAt = pkg.lastIndexOf('@');
|
|
198
|
+
const slashIndex = pkg.indexOf('/');
|
|
199
|
+
const hasVersion = pkg.startsWith('@') ? lastAt > slashIndex : lastAt > 0;
|
|
200
|
+
if (hasVersion) {
|
|
201
|
+
return pkg;
|
|
202
|
+
}
|
|
203
|
+
return `${pkg}@${tag}`;
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function resolveInstallTag(flags) {
|
|
208
|
+
return parseBooleanFlag(flags.next, false) ? 'next' : undefined;
|
|
209
|
+
}
|
|
210
|
+
|
|
181
211
|
function installPackages(pm, packages, options = {}) {
|
|
182
|
-
const { dev = false, dryRun = false, label = 'packages' } = options;
|
|
212
|
+
const { dev = false, dryRun = false, label = 'packages', tag } = options;
|
|
213
|
+
const resolvedPackages = tag ? applyTagToPackages(packages, tag) : packages;
|
|
183
214
|
const argsByPm = {
|
|
184
|
-
pnpm: dev
|
|
215
|
+
pnpm: dev
|
|
216
|
+
? ['add', '-D', ...resolvedPackages]
|
|
217
|
+
: ['add', ...resolvedPackages],
|
|
185
218
|
npm: dev
|
|
186
|
-
? ['install', '--save-dev', ...
|
|
187
|
-
: ['install', '--save', ...
|
|
188
|
-
yarn: dev
|
|
189
|
-
|
|
219
|
+
? ['install', '--save-dev', ...resolvedPackages]
|
|
220
|
+
: ['install', '--save', ...resolvedPackages],
|
|
221
|
+
yarn: dev
|
|
222
|
+
? ['add', '--dev', ...resolvedPackages]
|
|
223
|
+
: ['add', ...resolvedPackages],
|
|
224
|
+
bun: dev
|
|
225
|
+
? ['add', '--dev', ...resolvedPackages]
|
|
226
|
+
: ['add', ...resolvedPackages],
|
|
190
227
|
};
|
|
191
228
|
|
|
192
229
|
const installArgs = argsByPm[pm];
|
|
@@ -195,23 +232,26 @@ function installPackages(pm, packages, options = {}) {
|
|
|
195
232
|
process.exit(1);
|
|
196
233
|
}
|
|
197
234
|
|
|
198
|
-
|
|
235
|
+
const tagInfo = tag ? ` (tag: ${tag})` : '';
|
|
236
|
+
logInfo(`Installing ${label} with ${pm}${tagInfo}...`);
|
|
199
237
|
run(pm, installArgs, { dryRun });
|
|
200
238
|
logOk(`Installed ${label}.`);
|
|
201
239
|
}
|
|
202
240
|
|
|
203
|
-
function installRuntimePackages(pm, dryRun) {
|
|
241
|
+
function installRuntimePackages(pm, dryRun, tag) {
|
|
204
242
|
installPackages(pm, RUNTIME_PACKAGES, {
|
|
205
243
|
dev: false,
|
|
206
244
|
dryRun,
|
|
245
|
+
tag,
|
|
207
246
|
label: 'runtime RS-X packages',
|
|
208
247
|
});
|
|
209
248
|
}
|
|
210
249
|
|
|
211
|
-
function installCompilerPackages(pm, dryRun) {
|
|
250
|
+
function installCompilerPackages(pm, dryRun, tag) {
|
|
212
251
|
installPackages(pm, COMPILER_PACKAGES, {
|
|
213
252
|
dev: true,
|
|
214
253
|
dryRun,
|
|
254
|
+
tag,
|
|
215
255
|
label: 'compiler tooling',
|
|
216
256
|
});
|
|
217
257
|
}
|
|
@@ -236,14 +276,50 @@ function installVsCodeExtension(flags) {
|
|
|
236
276
|
return;
|
|
237
277
|
}
|
|
238
278
|
|
|
239
|
-
|
|
279
|
+
installBundledVsix(dryRun, force);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function resolveBundledVsix() {
|
|
283
|
+
const packageRoot = path.resolve(__dirname, '..');
|
|
284
|
+
const candidates = fs
|
|
285
|
+
.readdirSync(packageRoot)
|
|
286
|
+
.filter((name) => /^rs-x-vscode-extension-.*\.vsix$/u.test(name))
|
|
287
|
+
.map((name) => path.join(packageRoot, name));
|
|
288
|
+
|
|
289
|
+
if (candidates.length === 0) {
|
|
290
|
+
return null;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const latest = candidates
|
|
294
|
+
.map((fullPath) => ({
|
|
295
|
+
fullPath,
|
|
296
|
+
mtimeMs: fs.statSync(fullPath).mtimeMs,
|
|
297
|
+
}))
|
|
298
|
+
.sort((a, b) => b.mtimeMs - a.mtimeMs)[0];
|
|
299
|
+
|
|
300
|
+
return latest?.fullPath ?? null;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
function installBundledVsix(dryRun, force) {
|
|
304
|
+
const bundledVsix = resolveBundledVsix();
|
|
305
|
+
if (!bundledVsix) {
|
|
306
|
+
logWarn(
|
|
307
|
+
'No bundled VSIX found in @rs-x/cli. Skipping VS Code extension install.',
|
|
308
|
+
);
|
|
309
|
+
logInfo(
|
|
310
|
+
'If you are developing in the rs-x repo, use `rsx install vscode --local` instead.',
|
|
311
|
+
);
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
const args = ['--install-extension', bundledVsix];
|
|
240
316
|
if (force) {
|
|
241
317
|
args.push('--force');
|
|
242
318
|
}
|
|
243
319
|
|
|
244
|
-
logInfo(`Installing ${
|
|
320
|
+
logInfo(`Installing bundled VSIX from ${bundledVsix}...`);
|
|
245
321
|
run('code', args, { dryRun });
|
|
246
|
-
logOk('VS Code extension installed.');
|
|
322
|
+
logOk('VS Code extension installed from bundled VSIX.');
|
|
247
323
|
}
|
|
248
324
|
|
|
249
325
|
function installLocalVsix(dryRun, force) {
|
|
@@ -559,6 +635,51 @@ function writeFileWithDryRun(filePath, content, dryRun) {
|
|
|
559
635
|
fs.writeFileSync(filePath, content, 'utf8');
|
|
560
636
|
}
|
|
561
637
|
|
|
638
|
+
function copyPathWithDryRun(sourcePath, targetPath, dryRun) {
|
|
639
|
+
if (dryRun) {
|
|
640
|
+
logInfo(`[dry-run] copy ${sourcePath} -> ${targetPath}`);
|
|
641
|
+
return;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
const stat = fs.statSync(sourcePath);
|
|
645
|
+
if (stat.isDirectory()) {
|
|
646
|
+
fs.mkdirSync(targetPath, { recursive: true });
|
|
647
|
+
for (const entry of fs.readdirSync(sourcePath, { withFileTypes: true })) {
|
|
648
|
+
copyPathWithDryRun(
|
|
649
|
+
path.join(sourcePath, entry.name),
|
|
650
|
+
path.join(targetPath, entry.name),
|
|
651
|
+
false,
|
|
652
|
+
);
|
|
653
|
+
}
|
|
654
|
+
return;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
fs.mkdirSync(path.dirname(targetPath), { recursive: true });
|
|
658
|
+
fs.copyFileSync(sourcePath, targetPath);
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
function removeFileOrDirectoryWithDryRun(targetPath, dryRun) {
|
|
662
|
+
if (!fs.existsSync(targetPath)) {
|
|
663
|
+
return;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
if (dryRun) {
|
|
667
|
+
logInfo(`[dry-run] remove ${targetPath}`);
|
|
668
|
+
return;
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
fs.rmSync(targetPath, { recursive: true, force: true });
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
function resolveAngularProjectTsConfig(projectRoot) {
|
|
675
|
+
const appTsConfigPath = path.join(projectRoot, 'tsconfig.app.json');
|
|
676
|
+
if (fs.existsSync(appTsConfigPath)) {
|
|
677
|
+
return appTsConfigPath;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
return path.join(projectRoot, 'tsconfig.json');
|
|
681
|
+
}
|
|
682
|
+
|
|
562
683
|
function toFileDependencySpec(fromDir, targetPath) {
|
|
563
684
|
const relative = path.relative(fromDir, targetPath).replace(/\\/gu, '/');
|
|
564
685
|
const normalized = relative.startsWith('.') ? relative : `./${relative}`;
|
|
@@ -608,14 +729,15 @@ function resolveProjectRsxSpecs(
|
|
|
608
729
|
options = {},
|
|
609
730
|
) {
|
|
610
731
|
const includeAngularPackage = Boolean(options.includeAngularPackage);
|
|
732
|
+
const versionSpec = options.tag ? options.tag : RSX_PACKAGE_VERSION;
|
|
611
733
|
const defaults = {
|
|
612
|
-
'@rs-x/core':
|
|
613
|
-
'@rs-x/state-manager':
|
|
614
|
-
'@rs-x/expression-parser':
|
|
615
|
-
'@rs-x/compiler':
|
|
616
|
-
'@rs-x/typescript-plugin':
|
|
617
|
-
...(includeAngularPackage ? { '@rs-x/angular':
|
|
618
|
-
'@rs-x/cli':
|
|
734
|
+
'@rs-x/core': versionSpec,
|
|
735
|
+
'@rs-x/state-manager': versionSpec,
|
|
736
|
+
'@rs-x/expression-parser': versionSpec,
|
|
737
|
+
'@rs-x/compiler': versionSpec,
|
|
738
|
+
'@rs-x/typescript-plugin': versionSpec,
|
|
739
|
+
...(includeAngularPackage ? { '@rs-x/angular': versionSpec } : {}),
|
|
740
|
+
'@rs-x/cli': versionSpec,
|
|
619
741
|
};
|
|
620
742
|
|
|
621
743
|
const tarballSlugs = {
|
|
@@ -919,6 +1041,7 @@ async function runProject(flags) {
|
|
|
919
1041
|
const dryRun = Boolean(flags['dry-run']);
|
|
920
1042
|
const skipInstall = Boolean(flags['skip-install']);
|
|
921
1043
|
const pm = detectPackageManager(flags.pm);
|
|
1044
|
+
const tag = resolveInstallTag(flags);
|
|
922
1045
|
let projectName = typeof flags.name === 'string' ? flags.name.trim() : '';
|
|
923
1046
|
|
|
924
1047
|
if (!projectName) {
|
|
@@ -946,6 +1069,7 @@ async function runProject(flags) {
|
|
|
946
1069
|
projectRoot,
|
|
947
1070
|
workspaceRoot,
|
|
948
1071
|
tarballsDir,
|
|
1072
|
+
{ tag },
|
|
949
1073
|
);
|
|
950
1074
|
if (fs.existsSync(projectRoot) && fs.readdirSync(projectRoot).length > 0) {
|
|
951
1075
|
logError(`Target directory is not empty: ${projectRoot}`);
|
|
@@ -1153,6 +1277,183 @@ function scaffoldProjectTemplate(template, projectName, pm, flags) {
|
|
|
1153
1277
|
process.exit(1);
|
|
1154
1278
|
}
|
|
1155
1279
|
|
|
1280
|
+
function applyAngularDemoStarter(projectRoot, projectName, pm, flags) {
|
|
1281
|
+
const dryRun = Boolean(flags['dry-run']);
|
|
1282
|
+
const tag = resolveInstallTag(flags);
|
|
1283
|
+
const tarballsDir =
|
|
1284
|
+
typeof flags['tarballs-dir'] === 'string'
|
|
1285
|
+
? path.resolve(process.cwd(), flags['tarballs-dir'])
|
|
1286
|
+
: typeof process.env.RSX_TARBALLS_DIR === 'string' &&
|
|
1287
|
+
process.env.RSX_TARBALLS_DIR.trim().length > 0
|
|
1288
|
+
? path.resolve(process.cwd(), process.env.RSX_TARBALLS_DIR)
|
|
1289
|
+
: null;
|
|
1290
|
+
const workspaceRoot = findRepoRoot(projectRoot);
|
|
1291
|
+
const rsxSpecs = resolveProjectRsxSpecs(
|
|
1292
|
+
projectRoot,
|
|
1293
|
+
workspaceRoot,
|
|
1294
|
+
tarballsDir,
|
|
1295
|
+
{ tag, includeAngularPackage: true },
|
|
1296
|
+
);
|
|
1297
|
+
|
|
1298
|
+
const templateFiles = ['README.md', 'src'];
|
|
1299
|
+
for (const entry of templateFiles) {
|
|
1300
|
+
copyPathWithDryRun(
|
|
1301
|
+
path.join(ANGULAR_DEMO_TEMPLATE_DIR, entry),
|
|
1302
|
+
path.join(projectRoot, entry),
|
|
1303
|
+
dryRun,
|
|
1304
|
+
);
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
const staleAngularFiles = [
|
|
1308
|
+
path.join(projectRoot, 'src/app/app.ts'),
|
|
1309
|
+
path.join(projectRoot, 'src/app/app.spec.ts'),
|
|
1310
|
+
path.join(projectRoot, 'src/app/app.html'),
|
|
1311
|
+
path.join(projectRoot, 'src/app/app.css'),
|
|
1312
|
+
path.join(projectRoot, 'src/app/app.routes.ts'),
|
|
1313
|
+
path.join(projectRoot, 'src/app/app.config.ts'),
|
|
1314
|
+
];
|
|
1315
|
+
for (const stalePath of staleAngularFiles) {
|
|
1316
|
+
removeFileOrDirectoryWithDryRun(stalePath, dryRun);
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
const readmePath = path.join(projectRoot, 'README.md');
|
|
1320
|
+
if (fs.existsSync(readmePath)) {
|
|
1321
|
+
const readmeSource = fs.readFileSync(readmePath, 'utf8');
|
|
1322
|
+
const nextReadme = readmeSource.replace(
|
|
1323
|
+
/^#\s+rsx-angular-example/mu,
|
|
1324
|
+
`# ${projectName}`,
|
|
1325
|
+
);
|
|
1326
|
+
if (dryRun) {
|
|
1327
|
+
logInfo(`[dry-run] patch ${readmePath}`);
|
|
1328
|
+
} else {
|
|
1329
|
+
fs.writeFileSync(readmePath, nextReadme, 'utf8');
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
const packageJsonPath = path.join(projectRoot, 'package.json');
|
|
1334
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
1335
|
+
logError(
|
|
1336
|
+
`package.json not found in generated Angular app: ${packageJsonPath}`,
|
|
1337
|
+
);
|
|
1338
|
+
process.exit(1);
|
|
1339
|
+
}
|
|
1340
|
+
|
|
1341
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
1342
|
+
const angularTsConfigPath = resolveAngularProjectTsConfig(projectRoot);
|
|
1343
|
+
const angularTsConfigRelative = path
|
|
1344
|
+
.relative(projectRoot, angularTsConfigPath)
|
|
1345
|
+
.replace(/\\/gu, '/');
|
|
1346
|
+
packageJson.name = projectName;
|
|
1347
|
+
packageJson.private = true;
|
|
1348
|
+
packageJson.version = '0.1.0';
|
|
1349
|
+
packageJson.scripts = {
|
|
1350
|
+
'build:rsx': `rsx build --project ${angularTsConfigRelative} --no-emit --prod`,
|
|
1351
|
+
'typecheck:rsx': `rsx typecheck --project ${angularTsConfigRelative}`,
|
|
1352
|
+
prebuild: 'npm run build:rsx',
|
|
1353
|
+
start: 'npm run build:rsx && ng serve',
|
|
1354
|
+
build: 'ng build',
|
|
1355
|
+
};
|
|
1356
|
+
packageJson.rsx = {
|
|
1357
|
+
build: {
|
|
1358
|
+
preparse: true,
|
|
1359
|
+
preparseFile: 'src/rsx-generated/rsx-aot-preparsed.generated.ts',
|
|
1360
|
+
compiled: true,
|
|
1361
|
+
compiledFile: 'src/rsx-generated/rsx-aot-compiled.generated.ts',
|
|
1362
|
+
registrationFile: 'src/rsx-generated/rsx-aot-registration.generated.ts',
|
|
1363
|
+
compiledResolvedEvaluator: false,
|
|
1364
|
+
},
|
|
1365
|
+
};
|
|
1366
|
+
packageJson.dependencies = {
|
|
1367
|
+
...(packageJson.dependencies ?? {}),
|
|
1368
|
+
'@rs-x/angular': rsxSpecs['@rs-x/angular'],
|
|
1369
|
+
'@rs-x/core': rsxSpecs['@rs-x/core'],
|
|
1370
|
+
'@rs-x/state-manager': rsxSpecs['@rs-x/state-manager'],
|
|
1371
|
+
'@rs-x/expression-parser': rsxSpecs['@rs-x/expression-parser'],
|
|
1372
|
+
};
|
|
1373
|
+
packageJson.devDependencies = {
|
|
1374
|
+
...(packageJson.devDependencies ?? {}),
|
|
1375
|
+
'@rs-x/cli': rsxSpecs['@rs-x/cli'],
|
|
1376
|
+
'@rs-x/compiler': rsxSpecs['@rs-x/compiler'],
|
|
1377
|
+
'@rs-x/typescript-plugin': rsxSpecs['@rs-x/typescript-plugin'],
|
|
1378
|
+
};
|
|
1379
|
+
|
|
1380
|
+
if (dryRun) {
|
|
1381
|
+
logInfo(`[dry-run] patch ${packageJsonPath}`);
|
|
1382
|
+
} else {
|
|
1383
|
+
fs.writeFileSync(
|
|
1384
|
+
packageJsonPath,
|
|
1385
|
+
`${JSON.stringify(packageJson, null, 2)}\n`,
|
|
1386
|
+
'utf8',
|
|
1387
|
+
);
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1390
|
+
const angularJsonPath = path.join(projectRoot, 'angular.json');
|
|
1391
|
+
if (!fs.existsSync(angularJsonPath)) {
|
|
1392
|
+
logError(
|
|
1393
|
+
`angular.json not found in generated Angular app: ${angularJsonPath}`,
|
|
1394
|
+
);
|
|
1395
|
+
process.exit(1);
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1398
|
+
const angularJson = JSON.parse(fs.readFileSync(angularJsonPath, 'utf8'));
|
|
1399
|
+
const projects = angularJson.projects ?? {};
|
|
1400
|
+
const [angularProjectName] = Object.keys(projects);
|
|
1401
|
+
if (!angularProjectName) {
|
|
1402
|
+
logError('Generated angular.json does not define any projects.');
|
|
1403
|
+
process.exit(1);
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1406
|
+
const angularProject = projects[angularProjectName];
|
|
1407
|
+
const architect = angularProject.architect ?? angularProject.targets;
|
|
1408
|
+
const build = architect?.build;
|
|
1409
|
+
if (!build) {
|
|
1410
|
+
logError('Generated Angular project is missing a build target.');
|
|
1411
|
+
process.exit(1);
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1414
|
+
const buildOptions = build.options ?? {};
|
|
1415
|
+
const styles = Array.isArray(buildOptions.styles) ? buildOptions.styles : [];
|
|
1416
|
+
if (!styles.includes('src/styles.css')) {
|
|
1417
|
+
styles.push('src/styles.css');
|
|
1418
|
+
}
|
|
1419
|
+
buildOptions.styles = styles;
|
|
1420
|
+
buildOptions.preserveSymlinks = true;
|
|
1421
|
+
|
|
1422
|
+
const registrationFile =
|
|
1423
|
+
'src/rsx-generated/rsx-aot-registration.generated.ts';
|
|
1424
|
+
let polyfills = buildOptions.polyfills;
|
|
1425
|
+
if (typeof polyfills === 'string') {
|
|
1426
|
+
polyfills = [polyfills];
|
|
1427
|
+
} else if (!Array.isArray(polyfills)) {
|
|
1428
|
+
polyfills = [];
|
|
1429
|
+
}
|
|
1430
|
+
if (!polyfills.includes(registrationFile)) {
|
|
1431
|
+
polyfills.push(registrationFile);
|
|
1432
|
+
}
|
|
1433
|
+
buildOptions.polyfills = polyfills;
|
|
1434
|
+
build.options = buildOptions;
|
|
1435
|
+
|
|
1436
|
+
if (build.configurations?.production?.budgets) {
|
|
1437
|
+
delete build.configurations.production.budgets;
|
|
1438
|
+
}
|
|
1439
|
+
|
|
1440
|
+
if (dryRun) {
|
|
1441
|
+
logInfo(`[dry-run] patch ${angularJsonPath}`);
|
|
1442
|
+
} else {
|
|
1443
|
+
fs.writeFileSync(
|
|
1444
|
+
angularJsonPath,
|
|
1445
|
+
`${JSON.stringify(angularJson, null, 2)}\n`,
|
|
1446
|
+
'utf8',
|
|
1447
|
+
);
|
|
1448
|
+
}
|
|
1449
|
+
|
|
1450
|
+
if (!Boolean(flags['skip-install'])) {
|
|
1451
|
+
logInfo(`Refreshing ${pm} dependencies for the RS-X Angular starter...`);
|
|
1452
|
+
run(pm, ['install'], { dryRun });
|
|
1453
|
+
logOk('Angular starter dependencies are up to date.');
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1156
1457
|
async function runProjectWithTemplate(template, flags) {
|
|
1157
1458
|
const normalizedTemplate = normalizeProjectTemplate(template);
|
|
1158
1459
|
if (!normalizedTemplate) {
|
|
@@ -1184,7 +1485,7 @@ async function runProjectWithTemplate(template, flags) {
|
|
|
1184
1485
|
|
|
1185
1486
|
withWorkingDirectory(projectRoot, () => {
|
|
1186
1487
|
if (normalizedTemplate === 'angular') {
|
|
1187
|
-
|
|
1488
|
+
applyAngularDemoStarter(projectRoot, projectName, pm, flags);
|
|
1188
1489
|
return;
|
|
1189
1490
|
}
|
|
1190
1491
|
if (normalizedTemplate === 'react') {
|
|
@@ -1700,11 +2001,12 @@ function runInit(flags) {
|
|
|
1700
2001
|
const skipVscode = Boolean(flags['skip-vscode']);
|
|
1701
2002
|
const skipInstall = Boolean(flags['skip-install']);
|
|
1702
2003
|
const pm = detectPackageManager(flags.pm);
|
|
2004
|
+
const tag = resolveInstallTag(flags);
|
|
1703
2005
|
const projectRoot = process.cwd();
|
|
1704
2006
|
|
|
1705
2007
|
if (!skipInstall) {
|
|
1706
|
-
installRuntimePackages(pm, dryRun);
|
|
1707
|
-
installCompilerPackages(pm, dryRun);
|
|
2008
|
+
installRuntimePackages(pm, dryRun, tag);
|
|
2009
|
+
installCompilerPackages(pm, dryRun, tag);
|
|
1708
2010
|
} else {
|
|
1709
2011
|
logInfo('Skipping package installation (--skip-install).');
|
|
1710
2012
|
}
|
|
@@ -1758,11 +2060,112 @@ function runInit(flags) {
|
|
|
1758
2060
|
}
|
|
1759
2061
|
}
|
|
1760
2062
|
|
|
1761
|
-
|
|
1762
|
-
|
|
2063
|
+
logOk('RS-X init completed.');
|
|
2064
|
+
}
|
|
2065
|
+
|
|
2066
|
+
function upsertRsxBuildConfigInPackageJson(projectRoot, dryRun) {
|
|
2067
|
+
const packageJsonPath = path.join(projectRoot, 'package.json');
|
|
2068
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
2069
|
+
return false;
|
|
1763
2070
|
}
|
|
1764
2071
|
|
|
1765
|
-
|
|
2072
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
2073
|
+
const currentRsx = packageJson.rsx ?? {};
|
|
2074
|
+
const currentBuild = currentRsx.build ?? {};
|
|
2075
|
+
const nextBuild = {
|
|
2076
|
+
preparse: true,
|
|
2077
|
+
preparseFile: 'src/rsx-generated/rsx-aot-preparsed.generated.ts',
|
|
2078
|
+
compiled: true,
|
|
2079
|
+
compiledFile: 'src/rsx-generated/rsx-aot-compiled.generated.ts',
|
|
2080
|
+
registrationFile: 'src/rsx-generated/rsx-aot-registration.generated.ts',
|
|
2081
|
+
compiledResolvedEvaluator: false,
|
|
2082
|
+
...currentBuild,
|
|
2083
|
+
};
|
|
2084
|
+
|
|
2085
|
+
const nextPackageJson = {
|
|
2086
|
+
...packageJson,
|
|
2087
|
+
rsx: {
|
|
2088
|
+
...currentRsx,
|
|
2089
|
+
build: nextBuild,
|
|
2090
|
+
},
|
|
2091
|
+
};
|
|
2092
|
+
|
|
2093
|
+
if (dryRun) {
|
|
2094
|
+
logInfo(`[dry-run] patch ${packageJsonPath} (rsx.build)`);
|
|
2095
|
+
return true;
|
|
2096
|
+
}
|
|
2097
|
+
|
|
2098
|
+
fs.writeFileSync(
|
|
2099
|
+
packageJsonPath,
|
|
2100
|
+
`${JSON.stringify(nextPackageJson, null, 2)}\n`,
|
|
2101
|
+
'utf8',
|
|
2102
|
+
);
|
|
2103
|
+
logOk(`Patched ${packageJsonPath} (rsx.build)`);
|
|
2104
|
+
return true;
|
|
2105
|
+
}
|
|
2106
|
+
|
|
2107
|
+
function ensureAngularProvidersInEntry(entryFile, dryRun) {
|
|
2108
|
+
if (!fs.existsSync(entryFile)) {
|
|
2109
|
+
return false;
|
|
2110
|
+
}
|
|
2111
|
+
|
|
2112
|
+
const original = fs.readFileSync(entryFile, 'utf8');
|
|
2113
|
+
if (original.includes('providexRsx')) {
|
|
2114
|
+
logInfo(`Angular entry already includes providexRsx: ${entryFile}`);
|
|
2115
|
+
return true;
|
|
2116
|
+
}
|
|
2117
|
+
|
|
2118
|
+
if (!original.includes('bootstrapApplication(')) {
|
|
2119
|
+
logWarn(
|
|
2120
|
+
`Could not automatically patch Angular providers in ${entryFile}. Expected bootstrapApplication(...).`,
|
|
2121
|
+
);
|
|
2122
|
+
logInfo(
|
|
2123
|
+
"Manual setup: import { providexRsx } from '@rs-x/angular' and add providers: [...providexRsx()] to bootstrapApplication(...).",
|
|
2124
|
+
);
|
|
2125
|
+
return false;
|
|
2126
|
+
}
|
|
2127
|
+
|
|
2128
|
+
const sourceWithImport = injectImport(
|
|
2129
|
+
original,
|
|
2130
|
+
"import { providexRsx } from '@rs-x/angular';",
|
|
2131
|
+
);
|
|
2132
|
+
|
|
2133
|
+
let updated = sourceWithImport;
|
|
2134
|
+
if (
|
|
2135
|
+
/bootstrapApplication\([\s\S]*?,\s*\{[\s\S]*?providers\s*:/mu.test(updated)
|
|
2136
|
+
) {
|
|
2137
|
+
updated = updated.replace(
|
|
2138
|
+
/providers\s*:\s*\[/mu,
|
|
2139
|
+
'providers: [...providexRsx(), ',
|
|
2140
|
+
);
|
|
2141
|
+
} else if (/bootstrapApplication\([\s\S]*?,\s*\{/mu.test(updated)) {
|
|
2142
|
+
updated = updated.replace(
|
|
2143
|
+
/bootstrapApplication\(([\s\S]*?),\s*\{/mu,
|
|
2144
|
+
'bootstrapApplication($1, {\n providers: [...providexRsx()],',
|
|
2145
|
+
);
|
|
2146
|
+
} else {
|
|
2147
|
+
updated = updated.replace(
|
|
2148
|
+
/bootstrapApplication\(([\s\S]*?)\)\s*(?:\.catch\([\s\S]*?\))?\s*;/mu,
|
|
2149
|
+
'bootstrapApplication($1, {\n providers: [...providexRsx()],\n}).catch((error) => {\n console.error(error);\n});',
|
|
2150
|
+
);
|
|
2151
|
+
}
|
|
2152
|
+
|
|
2153
|
+
if (updated === sourceWithImport) {
|
|
2154
|
+
logWarn(`Could not automatically inject providexRsx into ${entryFile}.`);
|
|
2155
|
+
logInfo(
|
|
2156
|
+
"Manual setup: import { providexRsx } from '@rs-x/angular' and add providers: [...providexRsx()] to bootstrapApplication(...).",
|
|
2157
|
+
);
|
|
2158
|
+
return false;
|
|
2159
|
+
}
|
|
2160
|
+
|
|
2161
|
+
if (dryRun) {
|
|
2162
|
+
logInfo(`[dry-run] patch ${entryFile} (providexRsx)`);
|
|
2163
|
+
return true;
|
|
2164
|
+
}
|
|
2165
|
+
|
|
2166
|
+
fs.writeFileSync(entryFile, updated, 'utf8');
|
|
2167
|
+
logOk(`Patched ${entryFile} to include providexRsx.`);
|
|
2168
|
+
return true;
|
|
1766
2169
|
}
|
|
1767
2170
|
|
|
1768
2171
|
function upsertScriptInPackageJson(
|
|
@@ -2124,95 +2527,15 @@ ${patchBlock}
|
|
|
2124
2527
|
logOk(`Patched ${nextConfigJs} with RS-X webpack loader.`);
|
|
2125
2528
|
}
|
|
2126
2529
|
|
|
2127
|
-
function wireRsxAngularWebpack(projectRoot, dryRun) {
|
|
2128
|
-
const angularJsonPath = path.join(projectRoot, 'angular.json');
|
|
2129
|
-
if (!fs.existsSync(angularJsonPath)) {
|
|
2130
|
-
logWarn('angular.json not found. Skipping Angular build integration.');
|
|
2131
|
-
return;
|
|
2132
|
-
}
|
|
2133
|
-
|
|
2134
|
-
createRsxWebpackLoaderFile(projectRoot, dryRun);
|
|
2135
|
-
|
|
2136
|
-
const webpackConfigPath = path.join(projectRoot, 'rsx-angular-webpack.cjs');
|
|
2137
|
-
const webpackConfigSource = `const path = require('node:path');
|
|
2138
|
-
|
|
2139
|
-
module.exports = {
|
|
2140
|
-
module: {
|
|
2141
|
-
rules: [
|
|
2142
|
-
{
|
|
2143
|
-
test: /\\.[jt]sx?$/u,
|
|
2144
|
-
exclude: /node_modules/u,
|
|
2145
|
-
use: [
|
|
2146
|
-
{
|
|
2147
|
-
loader: path.resolve(__dirname, './rsx-webpack-loader.cjs'),
|
|
2148
|
-
},
|
|
2149
|
-
],
|
|
2150
|
-
},
|
|
2151
|
-
],
|
|
2152
|
-
},
|
|
2153
|
-
};
|
|
2154
|
-
`;
|
|
2155
|
-
|
|
2156
|
-
if (dryRun) {
|
|
2157
|
-
logInfo(`[dry-run] create ${webpackConfigPath}`);
|
|
2158
|
-
} else {
|
|
2159
|
-
fs.writeFileSync(webpackConfigPath, webpackConfigSource, 'utf8');
|
|
2160
|
-
logOk(`Created ${webpackConfigPath}`);
|
|
2161
|
-
}
|
|
2162
|
-
|
|
2163
|
-
const angularJson = JSON.parse(fs.readFileSync(angularJsonPath, 'utf8'));
|
|
2164
|
-
const projects = angularJson.projects ?? {};
|
|
2165
|
-
const projectNames = Object.keys(projects);
|
|
2166
|
-
if (projectNames.length === 0) {
|
|
2167
|
-
logWarn('No Angular projects found in angular.json.');
|
|
2168
|
-
return;
|
|
2169
|
-
}
|
|
2170
|
-
|
|
2171
|
-
const patchPath = 'rsx-angular-webpack.cjs';
|
|
2172
|
-
for (const projectName of projectNames) {
|
|
2173
|
-
const project = projects[projectName];
|
|
2174
|
-
const architect = project.architect ?? project.targets;
|
|
2175
|
-
if (!architect?.build) {
|
|
2176
|
-
continue;
|
|
2177
|
-
}
|
|
2178
|
-
|
|
2179
|
-
const build = architect.build;
|
|
2180
|
-
if (build.builder !== '@angular-builders/custom-webpack:browser') {
|
|
2181
|
-
build.builder = '@angular-builders/custom-webpack:browser';
|
|
2182
|
-
}
|
|
2183
|
-
build.options = build.options ?? {};
|
|
2184
|
-
build.options.customWebpackConfig = build.options.customWebpackConfig ?? {};
|
|
2185
|
-
build.options.customWebpackConfig.path = patchPath;
|
|
2186
|
-
|
|
2187
|
-
if (architect.serve) {
|
|
2188
|
-
const serve = architect.serve;
|
|
2189
|
-
if (serve.builder !== '@angular-builders/custom-webpack:dev-server') {
|
|
2190
|
-
serve.builder = '@angular-builders/custom-webpack:dev-server';
|
|
2191
|
-
}
|
|
2192
|
-
serve.options = serve.options ?? {};
|
|
2193
|
-
serve.options.buildTarget =
|
|
2194
|
-
serve.options.buildTarget ?? `${projectName}:build`;
|
|
2195
|
-
serve.options.browserTarget =
|
|
2196
|
-
serve.options.browserTarget ?? `${projectName}:build`;
|
|
2197
|
-
}
|
|
2198
|
-
}
|
|
2199
|
-
|
|
2200
|
-
if (dryRun) {
|
|
2201
|
-
logInfo(`[dry-run] patch ${angularJsonPath}`);
|
|
2202
|
-
} else {
|
|
2203
|
-
fs.writeFileSync(
|
|
2204
|
-
angularJsonPath,
|
|
2205
|
-
`${JSON.stringify(angularJson, null, 2)}\n`,
|
|
2206
|
-
'utf8',
|
|
2207
|
-
);
|
|
2208
|
-
logOk(`Patched ${angularJsonPath} for RS-X Angular webpack integration.`);
|
|
2209
|
-
}
|
|
2210
|
-
}
|
|
2211
|
-
|
|
2212
2530
|
function runSetupReact(flags) {
|
|
2213
2531
|
const dryRun = Boolean(flags['dry-run']);
|
|
2214
2532
|
const pm = detectPackageManager(flags.pm);
|
|
2533
|
+
const tag = resolveInstallTag(flags);
|
|
2215
2534
|
const projectRoot = process.cwd();
|
|
2535
|
+
const angularTsConfigPath = resolveAngularProjectTsConfig(projectRoot);
|
|
2536
|
+
const angularTsConfigRelative = path
|
|
2537
|
+
.relative(projectRoot, angularTsConfigPath)
|
|
2538
|
+
.replace(/\\/gu, '/');
|
|
2216
2539
|
const packageJsonPath = path.join(projectRoot, 'package.json');
|
|
2217
2540
|
if (!fs.existsSync(packageJsonPath)) {
|
|
2218
2541
|
logError(`package.json not found in ${projectRoot}`);
|
|
@@ -2238,21 +2561,20 @@ function runSetupReact(flags) {
|
|
|
2238
2561
|
installPackages(pm, ['@rs-x/react'], {
|
|
2239
2562
|
dev: false,
|
|
2240
2563
|
dryRun,
|
|
2564
|
+
tag,
|
|
2241
2565
|
label: 'RS-X React bindings',
|
|
2242
2566
|
});
|
|
2243
2567
|
} else {
|
|
2244
2568
|
logInfo('Skipping RS-X React bindings install (--skip-install).');
|
|
2245
2569
|
}
|
|
2246
2570
|
wireRsxVitePlugin(projectRoot, dryRun);
|
|
2247
|
-
if (!Boolean(flags['skip-vscode'])) {
|
|
2248
|
-
installVsCodeExtension(flags);
|
|
2249
|
-
}
|
|
2250
2571
|
logOk('RS-X React setup completed.');
|
|
2251
2572
|
}
|
|
2252
2573
|
|
|
2253
2574
|
function runSetupNext(flags) {
|
|
2254
2575
|
const dryRun = Boolean(flags['dry-run']);
|
|
2255
2576
|
const pm = detectPackageManager(flags.pm);
|
|
2577
|
+
const tag = resolveInstallTag(flags);
|
|
2256
2578
|
runInit({
|
|
2257
2579
|
...flags,
|
|
2258
2580
|
'skip-vscode': true,
|
|
@@ -2261,21 +2583,20 @@ function runSetupNext(flags) {
|
|
|
2261
2583
|
installPackages(pm, ['@rs-x/react'], {
|
|
2262
2584
|
dev: false,
|
|
2263
2585
|
dryRun,
|
|
2586
|
+
tag,
|
|
2264
2587
|
label: 'RS-X React bindings',
|
|
2265
2588
|
});
|
|
2266
2589
|
} else {
|
|
2267
2590
|
logInfo('Skipping RS-X React bindings install (--skip-install).');
|
|
2268
2591
|
}
|
|
2269
2592
|
wireRsxNextWebpack(process.cwd(), dryRun);
|
|
2270
|
-
if (!Boolean(flags['skip-vscode'])) {
|
|
2271
|
-
installVsCodeExtension(flags);
|
|
2272
|
-
}
|
|
2273
2593
|
logOk('RS-X Next.js setup completed.');
|
|
2274
2594
|
}
|
|
2275
2595
|
|
|
2276
2596
|
function runSetupVue(flags) {
|
|
2277
2597
|
const dryRun = Boolean(flags['dry-run']);
|
|
2278
2598
|
const pm = detectPackageManager(flags.pm);
|
|
2599
|
+
const tag = resolveInstallTag(flags);
|
|
2279
2600
|
runInit({
|
|
2280
2601
|
...flags,
|
|
2281
2602
|
'skip-vscode': true,
|
|
@@ -2284,67 +2605,79 @@ function runSetupVue(flags) {
|
|
|
2284
2605
|
installPackages(pm, ['@rs-x/vue'], {
|
|
2285
2606
|
dev: false,
|
|
2286
2607
|
dryRun,
|
|
2608
|
+
tag,
|
|
2287
2609
|
label: 'RS-X Vue bindings',
|
|
2288
2610
|
});
|
|
2289
2611
|
} else {
|
|
2290
2612
|
logInfo('Skipping RS-X Vue bindings install (--skip-install).');
|
|
2291
2613
|
}
|
|
2292
2614
|
wireRsxVitePlugin(process.cwd(), dryRun);
|
|
2293
|
-
if (!Boolean(flags['skip-vscode'])) {
|
|
2294
|
-
installVsCodeExtension(flags);
|
|
2295
|
-
}
|
|
2296
2615
|
logOk('RS-X Vue setup completed.');
|
|
2297
2616
|
}
|
|
2298
2617
|
|
|
2299
2618
|
function runSetupAngular(flags) {
|
|
2300
2619
|
const dryRun = Boolean(flags['dry-run']);
|
|
2301
2620
|
const pm = detectPackageManager(flags.pm);
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
...flags,
|
|
2305
|
-
'skip-vscode': true,
|
|
2306
|
-
});
|
|
2621
|
+
const tag = resolveInstallTag(flags);
|
|
2622
|
+
const projectRoot = process.cwd();
|
|
2307
2623
|
|
|
2308
2624
|
if (!Boolean(flags['skip-install'])) {
|
|
2625
|
+
installRuntimePackages(pm, dryRun, tag);
|
|
2626
|
+
installCompilerPackages(pm, dryRun, tag);
|
|
2309
2627
|
installPackages(pm, ['@rs-x/angular'], {
|
|
2310
2628
|
dev: false,
|
|
2311
2629
|
dryRun,
|
|
2630
|
+
tag,
|
|
2312
2631
|
label: 'RS-X Angular bindings',
|
|
2313
2632
|
});
|
|
2314
|
-
installPackages(pm, ['@angular-builders/custom-webpack'], {
|
|
2315
|
-
dev: true,
|
|
2316
|
-
dryRun,
|
|
2317
|
-
label: 'Angular custom webpack builder',
|
|
2318
|
-
});
|
|
2319
2633
|
} else {
|
|
2634
|
+
logInfo('Skipping package installation (--skip-install).');
|
|
2635
|
+
}
|
|
2636
|
+
|
|
2637
|
+
const entryFile = resolveEntryFile(projectRoot, 'angular', flags.entry);
|
|
2638
|
+
if (entryFile) {
|
|
2639
|
+
logInfo(`Using Angular entry file: ${entryFile}`);
|
|
2640
|
+
ensureAngularProvidersInEntry(entryFile, dryRun);
|
|
2641
|
+
} else {
|
|
2642
|
+
logWarn('Could not detect an Angular entry file automatically.');
|
|
2320
2643
|
logInfo(
|
|
2321
|
-
'
|
|
2644
|
+
'Manual setup: add providexRsx() to bootstrapApplication(...) in your main entry file.',
|
|
2322
2645
|
);
|
|
2323
2646
|
}
|
|
2324
2647
|
|
|
2325
|
-
|
|
2648
|
+
upsertRsxBuildConfigInPackageJson(projectRoot, dryRun);
|
|
2649
|
+
|
|
2326
2650
|
upsertScriptInPackageJson(
|
|
2327
|
-
|
|
2651
|
+
projectRoot,
|
|
2328
2652
|
'build:rsx',
|
|
2329
|
-
|
|
2653
|
+
`rsx build --project ${angularTsConfigRelative} --no-emit --prod`,
|
|
2330
2654
|
dryRun,
|
|
2331
2655
|
);
|
|
2332
2656
|
upsertScriptInPackageJson(
|
|
2333
|
-
|
|
2657
|
+
projectRoot,
|
|
2334
2658
|
'typecheck:rsx',
|
|
2335
|
-
|
|
2659
|
+
`rsx typecheck --project ${angularTsConfigRelative}`,
|
|
2336
2660
|
dryRun,
|
|
2337
2661
|
);
|
|
2338
2662
|
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2663
|
+
const rsxRegistrationFile = path.join(
|
|
2664
|
+
projectRoot,
|
|
2665
|
+
'src/rsx-generated/rsx-aot-registration.generated.ts',
|
|
2666
|
+
);
|
|
2667
|
+
ensureAngularPolyfillsContainsFile({
|
|
2668
|
+
projectRoot,
|
|
2669
|
+
configPath: angularTsConfigPath,
|
|
2670
|
+
filePath: rsxRegistrationFile,
|
|
2671
|
+
dryRun,
|
|
2672
|
+
});
|
|
2673
|
+
|
|
2342
2674
|
logOk('RS-X Angular setup completed.');
|
|
2343
2675
|
}
|
|
2344
2676
|
|
|
2345
2677
|
function runSetupAuto(flags) {
|
|
2346
2678
|
const projectRoot = process.cwd();
|
|
2347
2679
|
const context = detectProjectContext(projectRoot);
|
|
2680
|
+
const tag = resolveInstallTag(flags);
|
|
2348
2681
|
|
|
2349
2682
|
if (context === 'react') {
|
|
2350
2683
|
logInfo('Auto-detected framework: react');
|
|
@@ -2372,9 +2705,8 @@ function runSetupAuto(flags) {
|
|
|
2372
2705
|
|
|
2373
2706
|
logInfo('No framework-specific setup detected; running generic setup.');
|
|
2374
2707
|
const pm = detectPackageManager(flags.pm);
|
|
2375
|
-
installRuntimePackages(pm, Boolean(flags['dry-run']));
|
|
2376
|
-
installCompilerPackages(pm, Boolean(flags['dry-run']));
|
|
2377
|
-
installVsCodeExtension(flags);
|
|
2708
|
+
installRuntimePackages(pm, Boolean(flags['dry-run']), tag);
|
|
2709
|
+
installCompilerPackages(pm, Boolean(flags['dry-run']), tag);
|
|
2378
2710
|
}
|
|
2379
2711
|
|
|
2380
2712
|
function resolveProjectModule(projectRoot, moduleName) {
|
|
@@ -3142,24 +3474,27 @@ function printInstallHelp(target) {
|
|
|
3142
3474
|
if (target === 'compiler') {
|
|
3143
3475
|
console.log('Usage:');
|
|
3144
3476
|
console.log(
|
|
3145
|
-
' rsx install compiler [--pm <pnpm|npm|yarn|bun>] [--dry-run]',
|
|
3477
|
+
' rsx install compiler [--pm <pnpm|npm|yarn|bun>] [--next] [--dry-run]',
|
|
3146
3478
|
);
|
|
3147
3479
|
console.log('');
|
|
3148
3480
|
console.log('Options:');
|
|
3149
3481
|
console.log(' --pm Explicit package manager');
|
|
3482
|
+
console.log(' --next Install prerelease versions (dist-tag next)');
|
|
3150
3483
|
console.log(' --dry-run Print commands without executing them');
|
|
3151
3484
|
return;
|
|
3152
3485
|
}
|
|
3153
3486
|
|
|
3154
3487
|
console.log('Usage:');
|
|
3155
3488
|
console.log(' rsx install vscode [--force] [--local] [--dry-run]');
|
|
3156
|
-
console.log(
|
|
3489
|
+
console.log(
|
|
3490
|
+
' rsx install compiler [--pm <pnpm|npm|yarn|bun>] [--next] [--dry-run]',
|
|
3491
|
+
);
|
|
3157
3492
|
}
|
|
3158
3493
|
|
|
3159
3494
|
function printSetupHelp() {
|
|
3160
3495
|
console.log('Usage:');
|
|
3161
3496
|
console.log(
|
|
3162
|
-
' rsx setup [--pm <pnpm|npm|yarn|bun>] [--force] [--local] [--dry-run]',
|
|
3497
|
+
' rsx setup [--pm <pnpm|npm|yarn|bun>] [--next] [--force] [--local] [--dry-run]',
|
|
3163
3498
|
);
|
|
3164
3499
|
console.log('');
|
|
3165
3500
|
console.log('What it does:');
|
|
@@ -3173,6 +3508,7 @@ function printSetupHelp() {
|
|
|
3173
3508
|
console.log('');
|
|
3174
3509
|
console.log('Options:');
|
|
3175
3510
|
console.log(' --pm Explicit package manager');
|
|
3511
|
+
console.log(' --next Install prerelease versions (dist-tag next)');
|
|
3176
3512
|
console.log(' --force Reinstall extension if already installed');
|
|
3177
3513
|
console.log(' --local Build/install local VSIX from repo workspace');
|
|
3178
3514
|
console.log(' --dry-run Print commands without executing them');
|
|
@@ -3181,7 +3517,7 @@ function printSetupHelp() {
|
|
|
3181
3517
|
function printInitHelp() {
|
|
3182
3518
|
console.log('Usage:');
|
|
3183
3519
|
console.log(
|
|
3184
|
-
' rsx init [--pm <pnpm|npm|yarn|bun>] [--entry <path>] [--skip-install] [--skip-vscode] [--force] [--local] [--dry-run]',
|
|
3520
|
+
' rsx init [--pm <pnpm|npm|yarn|bun>] [--entry <path>] [--next] [--skip-install] [--skip-vscode] [--force] [--local] [--dry-run]',
|
|
3185
3521
|
);
|
|
3186
3522
|
console.log('');
|
|
3187
3523
|
console.log('What it does:');
|
|
@@ -3196,6 +3532,7 @@ function printInitHelp() {
|
|
|
3196
3532
|
console.log('Options:');
|
|
3197
3533
|
console.log(' --pm Explicit package manager');
|
|
3198
3534
|
console.log(' --entry Explicit application entry file');
|
|
3535
|
+
console.log(' --next Install prerelease versions (dist-tag next)');
|
|
3199
3536
|
console.log(' --skip-install Skip npm/pnpm/yarn/bun package installation');
|
|
3200
3537
|
console.log(' --skip-vscode Skip VS Code extension installation');
|
|
3201
3538
|
console.log(' --force Reinstall extension if already installed');
|
|
@@ -3206,18 +3543,23 @@ function printInitHelp() {
|
|
|
3206
3543
|
function printProjectHelp() {
|
|
3207
3544
|
console.log('Usage:');
|
|
3208
3545
|
console.log(
|
|
3209
|
-
' rsx project [angular|vuejs|react|nextjs|nodejs] [--name <project-name>] [--pm <pnpm|npm|yarn|bun>] [--template <angular|vuejs|react|nextjs|nodejs>] [--tarballs-dir <path>] [--skip-install] [--skip-vscode] [--dry-run]',
|
|
3546
|
+
' rsx project [angular|vuejs|react|nextjs|nodejs] [--name <project-name>] [--pm <pnpm|npm|yarn|bun>] [--next] [--template <angular|vuejs|react|nextjs|nodejs>] [--tarballs-dir <path>] [--skip-install] [--skip-vscode] [--dry-run]',
|
|
3210
3547
|
);
|
|
3211
3548
|
console.log('');
|
|
3212
3549
|
console.log('What it does:');
|
|
3213
3550
|
console.log(' - Creates a new project folder');
|
|
3214
3551
|
console.log(' - Supports templates: angular, vuejs, react, nextjs, nodejs');
|
|
3552
|
+
console.log(
|
|
3553
|
+
' - Angular generates the RS-X virtual-table demo starter on top of the latest Angular scaffold',
|
|
3554
|
+
);
|
|
3215
3555
|
console.log(' - Scaffolds framework app and wires RS-X bootstrap/setup');
|
|
3216
3556
|
console.log(' - Writes package.json with RS-X dependencies');
|
|
3217
3557
|
console.log(
|
|
3218
3558
|
' - Adds tsconfig + TypeScript plugin config for editor support',
|
|
3219
3559
|
);
|
|
3220
|
-
console.log(
|
|
3560
|
+
console.log(
|
|
3561
|
+
' - For Angular template: uses the latest Angular CLI scaffold, then applies the RS-X demo starter',
|
|
3562
|
+
);
|
|
3221
3563
|
console.log(' - For React/Next templates: also installs @rs-x/react');
|
|
3222
3564
|
console.log(' - For Vue template: also installs @rs-x/vue');
|
|
3223
3565
|
console.log(' - Installs dependencies (unless --skip-install)');
|
|
@@ -3228,6 +3570,7 @@ function printProjectHelp() {
|
|
|
3228
3570
|
' --template Project template (if omitted, asks interactively)',
|
|
3229
3571
|
);
|
|
3230
3572
|
console.log(' --pm Explicit package manager');
|
|
3573
|
+
console.log(' --next Install prerelease versions (dist-tag next)');
|
|
3231
3574
|
console.log(
|
|
3232
3575
|
' --tarballs-dir Directory containing local RS-X package tarballs (*.tgz)',
|
|
3233
3576
|
);
|
|
@@ -3449,7 +3792,8 @@ function main() {
|
|
|
3449
3792
|
|
|
3450
3793
|
if (command === 'install' && target === 'compiler') {
|
|
3451
3794
|
const pm = detectPackageManager(flags.pm);
|
|
3452
|
-
|
|
3795
|
+
const tag = resolveInstallTag(flags);
|
|
3796
|
+
installCompilerPackages(pm, Boolean(flags['dry-run']), tag);
|
|
3453
3797
|
return;
|
|
3454
3798
|
}
|
|
3455
3799
|
|