slicejs-cli 3.6.0 → 3.6.1
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 +47 -11
- package/client.js +10 -7
- package/commands/buildProduction/buildProduction.js +6 -3
- package/commands/doctor/doctor.js +1 -2
- package/commands/init/init.js +69 -20
- package/commands/utils/PackageManager.js +11 -11
- package/commands/utils/sliceScripts.js +15 -13
- package/package.json +1 -1
- package/post.js +5 -3
package/README.md
CHANGED
|
@@ -70,6 +70,38 @@ so each project keeps its pinned CLI version.
|
|
|
70
70
|
|
|
71
71
|
## Main commands
|
|
72
72
|
|
|
73
|
+
Inside initialized projects, prefer package scripts (`pnpm run ...`, `npm run ...`)
|
|
74
|
+
over direct binary calls.
|
|
75
|
+
|
|
76
|
+
Common script workflow:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
pnpm run dev
|
|
80
|
+
pnpm run build
|
|
81
|
+
pnpm run start
|
|
82
|
+
pnpm run browse
|
|
83
|
+
pnpm run get -- Button
|
|
84
|
+
pnpm run sync
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Alternative with local devDependency resolution:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
pnpm exec slice dev
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
If `slicejs-cli` is installed globally, `slice` can be executed directly from PATH.
|
|
94
|
+
|
|
95
|
+
For pnpm v10+, if build scripts are restricted, configure `allowBuilds` in
|
|
96
|
+
`pnpm-workspace.yaml`:
|
|
97
|
+
|
|
98
|
+
```yaml
|
|
99
|
+
allowBuilds:
|
|
100
|
+
slicejs-cli: true
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
`slice init --pm pnpm` now writes this automatically.
|
|
104
|
+
|
|
73
105
|
| Command | Description |
|
|
74
106
|
|---------|-------------|
|
|
75
107
|
| `slice init` | Initialize a Slice.js project |
|
|
@@ -89,17 +121,21 @@ When you install `slicejs-cli`, the `postinstall` script automatically configure
|
|
|
89
121
|
```json
|
|
90
122
|
{
|
|
91
123
|
"scripts": {
|
|
92
|
-
"slice:
|
|
93
|
-
"slice:
|
|
94
|
-
"slice:
|
|
95
|
-
"slice:
|
|
96
|
-
"slice:
|
|
97
|
-
"slice:
|
|
98
|
-
"slice:
|
|
99
|
-
"slice:
|
|
100
|
-
"slice:
|
|
101
|
-
"slice:
|
|
102
|
-
"slice:
|
|
124
|
+
"slice:init": "node ./node_modules/slicejs-cli/client.js init",
|
|
125
|
+
"slice:dev": "node ./node_modules/slicejs-cli/client.js dev",
|
|
126
|
+
"slice:build": "node ./node_modules/slicejs-cli/client.js build",
|
|
127
|
+
"slice:start": "node ./node_modules/slicejs-cli/client.js start",
|
|
128
|
+
"slice:create": "node ./node_modules/slicejs-cli/client.js component create",
|
|
129
|
+
"slice:list": "node ./node_modules/slicejs-cli/client.js component list",
|
|
130
|
+
"slice:delete": "node ./node_modules/slicejs-cli/client.js component delete",
|
|
131
|
+
"slice:get": "node ./node_modules/slicejs-cli/client.js get",
|
|
132
|
+
"slice:browse": "node ./node_modules/slicejs-cli/client.js browse",
|
|
133
|
+
"slice:sync": "node ./node_modules/slicejs-cli/client.js sync",
|
|
134
|
+
"slice:doctor": "node ./node_modules/slicejs-cli/client.js doctor",
|
|
135
|
+
"slice:version": "node ./node_modules/slicejs-cli/client.js version",
|
|
136
|
+
"slice:help": "node ./node_modules/slicejs-cli/client.js --help",
|
|
137
|
+
"slice:update": "node ./node_modules/slicejs-cli/client.js update",
|
|
138
|
+
"slice:types": "node ./node_modules/slicejs-cli/client.js types generate"
|
|
103
139
|
}
|
|
104
140
|
}
|
|
105
141
|
```
|
package/client.js
CHANGED
|
@@ -31,6 +31,8 @@ import {
|
|
|
31
31
|
detectPackageManager,
|
|
32
32
|
getAvailablePackageManagers,
|
|
33
33
|
isPackageManagerAvailable,
|
|
34
|
+
resolvePackageManager,
|
|
35
|
+
runScriptCommand,
|
|
34
36
|
SUPPORTED_PACKAGE_MANAGERS
|
|
35
37
|
} from './commands/utils/PackageManager.js';
|
|
36
38
|
import { SLICE_SCRIPTS } from './commands/utils/sliceScripts.js';
|
|
@@ -103,7 +105,7 @@ sliceClient
|
|
|
103
105
|
.command("init")
|
|
104
106
|
.description("Initialize a new Slice.js project")
|
|
105
107
|
.option("-y, --yes [name]", "Skip prompts and initialize with project name")
|
|
106
|
-
.option("--pm <packageManager>", "Package manager to use (
|
|
108
|
+
.option("--pm <packageManager>", "Package manager to use (pnpm or npm). Auto-detected when omitted")
|
|
107
109
|
.action(async (options) => {
|
|
108
110
|
let projectName = 'my-slice-app';
|
|
109
111
|
if (options.yes) {
|
|
@@ -150,7 +152,7 @@ sliceClient
|
|
|
150
152
|
} else if (!options.yes) {
|
|
151
153
|
const available = getAvailablePackageManagers();
|
|
152
154
|
if (available.length === 0) {
|
|
153
|
-
Print.error('No package manager found (
|
|
155
|
+
Print.error('No package manager found (pnpm or npm). Install one and retry.');
|
|
154
156
|
return;
|
|
155
157
|
}
|
|
156
158
|
const { pm } = await inquirer.prompt([
|
|
@@ -165,9 +167,9 @@ sliceClient
|
|
|
165
167
|
packageManager = pm;
|
|
166
168
|
} else {
|
|
167
169
|
const available = getAvailablePackageManagers();
|
|
168
|
-
packageManager = available.includes('
|
|
170
|
+
packageManager = available.includes('pnpm') ? 'pnpm' : available[0];
|
|
169
171
|
if (!packageManager) {
|
|
170
|
-
Print.error('No package manager found (
|
|
172
|
+
Print.error('No package manager found (pnpm or npm). Install one and retry.');
|
|
171
173
|
return;
|
|
172
174
|
}
|
|
173
175
|
}
|
|
@@ -638,6 +640,7 @@ sliceClient
|
|
|
638
640
|
|
|
639
641
|
const projectRoot = getProjectRoot(import.meta.url);
|
|
640
642
|
const pkgPath = path.join(projectRoot, 'package.json');
|
|
643
|
+
const packageManager = resolvePackageManager(projectRoot).name;
|
|
641
644
|
|
|
642
645
|
// Shared with post.js and slice init — see commands/utils/sliceScripts.js
|
|
643
646
|
const sliceScripts = SLICE_SCRIPTS;
|
|
@@ -665,12 +668,12 @@ sliceClient
|
|
|
665
668
|
}
|
|
666
669
|
|
|
667
670
|
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2), 'utf-8');
|
|
668
|
-
console.log(`✅ slicejs-cli installed successfully. Added ${addedCount}
|
|
669
|
-
console.log(
|
|
671
|
+
console.log(`✅ slicejs-cli installed successfully. Added ${addedCount} package scripts to package.json.`);
|
|
672
|
+
console.log(` Run: ${runScriptCommand(packageManager, 'slice:dev')}`);
|
|
670
673
|
} catch (err) {
|
|
671
674
|
console.log('✅ slicejs-cli installed successfully.');
|
|
672
675
|
console.log(' Could not auto-configure scripts:', err.message);
|
|
673
|
-
console.log(
|
|
676
|
+
console.log(` Configure scripts manually and run: ${runScriptCommand(packageManager, 'slice:dev')}`);
|
|
674
677
|
}
|
|
675
678
|
});
|
|
676
679
|
|
|
@@ -6,7 +6,8 @@ import { minify as terserMinify } from 'terser';
|
|
|
6
6
|
import { minify } from 'html-minifier-terser';
|
|
7
7
|
import CleanCSS from 'clean-css';
|
|
8
8
|
import Print from '../Print.js';
|
|
9
|
-
import { getSrcPath, getDistPath, getConfigPath } from '../utils/PathHelper.js';
|
|
9
|
+
import { getSrcPath, getDistPath, getConfigPath, getProjectRoot } from '../utils/PathHelper.js';
|
|
10
|
+
import { resolvePackageManager, runScriptCommand } from '../utils/PackageManager.js';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Loads configuration from sliceConfig.json
|
|
@@ -441,6 +442,7 @@ async function analyzeBuild() {
|
|
|
441
442
|
*/
|
|
442
443
|
export default async function buildProduction(options = {}) {
|
|
443
444
|
const startTime = Date.now();
|
|
445
|
+
const packageManager = resolvePackageManager(getProjectRoot(import.meta.url)).name;
|
|
444
446
|
|
|
445
447
|
try {
|
|
446
448
|
Print.title('🔨 Building Slice.js project for production...');
|
|
@@ -483,7 +485,7 @@ export default async function buildProduction(options = {}) {
|
|
|
483
485
|
Print.info('Your optimized project is ready in the /dist directory');
|
|
484
486
|
Print.newLine();
|
|
485
487
|
Print.info('Next steps:');
|
|
486
|
-
console.log(
|
|
488
|
+
console.log(` • Use "${runScriptCommand(packageManager, 'start')}" to test the production build`);
|
|
487
489
|
console.log(' • All Slice.js components and architecture preserved');
|
|
488
490
|
|
|
489
491
|
return true;
|
|
@@ -499,6 +501,7 @@ export default async function buildProduction(options = {}) {
|
|
|
499
501
|
*/
|
|
500
502
|
export async function serveProductionBuild(port) {
|
|
501
503
|
try {
|
|
504
|
+
const packageManager = resolvePackageManager(getProjectRoot(import.meta.url)).name;
|
|
502
505
|
const config = loadConfig();
|
|
503
506
|
const defaultPort = config?.server?.port || 3001;
|
|
504
507
|
const finalPort = port || defaultPort;
|
|
@@ -533,7 +536,7 @@ export async function serveProductionBuild(port) {
|
|
|
533
536
|
Print.success(`Production preview server running at http://localhost:${finalPort}`);
|
|
534
537
|
Print.info('Press Ctrl+C to stop the server');
|
|
535
538
|
Print.info('This server previews your production build from /dist');
|
|
536
|
-
Print.warning(
|
|
539
|
+
Print.warning(`This is a preview server - use "${runScriptCommand(packageManager, 'start')}" for the full production server`);
|
|
537
540
|
});
|
|
538
541
|
|
|
539
542
|
} catch (error) {
|
|
@@ -154,8 +154,7 @@ export async function checkPackageManagerSetup(projectRoot = getProjectRoot(impo
|
|
|
154
154
|
|
|
155
155
|
const LOCKFILE_PM = {
|
|
156
156
|
'package-lock.json': 'npm',
|
|
157
|
-
'pnpm-lock.yaml': 'pnpm'
|
|
158
|
-
'yarn.lock': 'yarn'
|
|
157
|
+
'pnpm-lock.yaml': 'pnpm'
|
|
159
158
|
};
|
|
160
159
|
const lockfiles = [];
|
|
161
160
|
for (const lockfile of Object.keys(LOCKFILE_PM)) {
|
package/commands/init/init.js
CHANGED
|
@@ -32,6 +32,51 @@ async function fetchLatestVersion(packageName) {
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
async function ensurePnpmAllowBuilds(projectRoot) {
|
|
36
|
+
const workspacePath = path.join(projectRoot, 'pnpm-workspace.yaml');
|
|
37
|
+
const allowBuildLine = ' slicejs-cli: true';
|
|
38
|
+
|
|
39
|
+
if (!(await fs.pathExists(workspacePath))) {
|
|
40
|
+
await fs.writeFile(workspacePath, `allowBuilds:\n${allowBuildLine}\n`, 'utf8');
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const raw = await fs.readFile(workspacePath, 'utf8');
|
|
45
|
+
const lines = raw.split(/\r?\n/);
|
|
46
|
+
const allowIdx = lines.findIndex((line) => /^allowBuilds:\s*$/.test(line));
|
|
47
|
+
|
|
48
|
+
if (allowIdx === -1) {
|
|
49
|
+
const suffix = raw.endsWith('\n') ? '' : '\n';
|
|
50
|
+
await fs.writeFile(workspacePath, `${raw}${suffix}allowBuilds:\n${allowBuildLine}\n`, 'utf8');
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
let blockEnd = lines.length;
|
|
55
|
+
for (let i = allowIdx + 1; i < lines.length; i++) {
|
|
56
|
+
const line = lines[i];
|
|
57
|
+
if (!line.trim()) continue;
|
|
58
|
+
if (!/^\s/.test(line)) {
|
|
59
|
+
blockEnd = i;
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
let found = false;
|
|
65
|
+
for (let i = allowIdx + 1; i < blockEnd; i++) {
|
|
66
|
+
if (/^\s+slicejs-cli\s*:/.test(lines[i])) {
|
|
67
|
+
lines[i] = allowBuildLine;
|
|
68
|
+
found = true;
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (!found) {
|
|
74
|
+
lines.splice(blockEnd, 0, allowBuildLine);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
await fs.writeFile(workspacePath, `${lines.join('\n').replace(/\n*$/, '\n')}`, 'utf8');
|
|
78
|
+
}
|
|
79
|
+
|
|
35
80
|
// Create the project manifest BEFORE any install runs. Without a package.json in
|
|
36
81
|
// the project folder, npm/pnpm walk up the directory tree looking for the nearest
|
|
37
82
|
// manifest and anchor node_modules (and the dependency entry) OUTSIDE the project.
|
|
@@ -93,6 +138,10 @@ export default async function initializeProject(options = {}) {
|
|
|
93
138
|
const packageManager = options.packageManager
|
|
94
139
|
|| resolvePackageManager(projectRoot).name;
|
|
95
140
|
|
|
141
|
+
if (packageManager === 'pnpm') {
|
|
142
|
+
await ensurePnpmAllowBuilds(projectRoot);
|
|
143
|
+
}
|
|
144
|
+
|
|
96
145
|
// 0. CREATE PROJECT MANIFEST FIRST — must exist before any install so the
|
|
97
146
|
// package manager anchors node_modules inside the project folder.
|
|
98
147
|
await ensureProjectManifest(projectRoot, packageManager);
|
|
@@ -256,20 +305,20 @@ export default async function initializeProject(options = {}) {
|
|
|
256
305
|
componentsSpinner.succeed(`All ${successful} Visual components installed successfully`);
|
|
257
306
|
} else if (successful > 0) {
|
|
258
307
|
componentsSpinner.warn(`${successful} components installed, ${failed} failed`);
|
|
259
|
-
Print.info(
|
|
308
|
+
Print.info(`You can install failed components later using "${packageManager} run get -- <component-name>"`);
|
|
260
309
|
} else {
|
|
261
310
|
componentsSpinner.fail('Failed to install Visual components');
|
|
262
311
|
}
|
|
263
312
|
} else {
|
|
264
313
|
componentsSpinner.warn('No Visual components found in registry');
|
|
265
|
-
Print.info(
|
|
314
|
+
Print.info(`You can add components later using "${packageManager} run get -- <component-name>"`);
|
|
266
315
|
}
|
|
267
316
|
|
|
268
317
|
} catch (error) {
|
|
269
318
|
componentsSpinner.fail('Could not download Visual components from official repository');
|
|
270
319
|
Print.error(`Repository error: ${error.message}`);
|
|
271
320
|
Print.info('Project initialized without Visual components');
|
|
272
|
-
Print.info(
|
|
321
|
+
Print.info(`You can add them later using "${packageManager} run get -- <component-name>"`);
|
|
273
322
|
}
|
|
274
323
|
|
|
275
324
|
// 3b. DOWNLOAD STARTER SERVICE COMPONENTS FROM OFFICIAL REPOSITORY
|
|
@@ -295,7 +344,7 @@ export default async function initializeProject(options = {}) {
|
|
|
295
344
|
serviceSpinner.succeed(`All ${successful} Service components installed successfully`);
|
|
296
345
|
} else if (successful > 0) {
|
|
297
346
|
serviceSpinner.warn(`${successful} Service components installed, ${failed} failed`);
|
|
298
|
-
Print.info(
|
|
347
|
+
Print.info(`You can install failed components later using "${packageManager} run get -- <component-name>"`);
|
|
299
348
|
} else {
|
|
300
349
|
serviceSpinner.fail('Failed to install Service components');
|
|
301
350
|
}
|
|
@@ -305,7 +354,7 @@ export default async function initializeProject(options = {}) {
|
|
|
305
354
|
} catch (error) {
|
|
306
355
|
serviceSpinner.fail('Could not download Service components from official repository');
|
|
307
356
|
Print.error(`Repository error: ${error.message}`);
|
|
308
|
-
Print.info(
|
|
357
|
+
Print.info(`You can add them later using "${packageManager} run get -- <component-name>"`);
|
|
309
358
|
}
|
|
310
359
|
|
|
311
360
|
// 4. CONFIGURE SCRIPTS IN PROJECT package.json
|
|
@@ -330,25 +379,25 @@ export default async function initializeProject(options = {}) {
|
|
|
330
379
|
pkg.scripts = pkg.scripts || {};
|
|
331
380
|
pkg.dependencies = pkg.dependencies || {};
|
|
332
381
|
|
|
333
|
-
//
|
|
334
|
-
pkg.scripts['dev'] = 'slice
|
|
335
|
-
pkg.scripts['build'] = 'slice
|
|
336
|
-
pkg.scripts['start'] = 'slice
|
|
382
|
+
// Main scripts (local CLI path, no global launcher dependency)
|
|
383
|
+
pkg.scripts['dev'] = SLICE_SCRIPTS['slice:dev'];
|
|
384
|
+
pkg.scripts['build'] = SLICE_SCRIPTS['slice:build'];
|
|
385
|
+
pkg.scripts['start'] = SLICE_SCRIPTS['slice:start'];
|
|
337
386
|
|
|
338
387
|
// Component management
|
|
339
|
-
pkg.scripts['component:create'] = 'slice
|
|
340
|
-
pkg.scripts['component:list'] = 'slice
|
|
341
|
-
pkg.scripts['component:delete'] = 'slice
|
|
388
|
+
pkg.scripts['component:create'] = SLICE_SCRIPTS['slice:create'];
|
|
389
|
+
pkg.scripts['component:list'] = SLICE_SCRIPTS['slice:list'];
|
|
390
|
+
pkg.scripts['component:delete'] = SLICE_SCRIPTS['slice:delete'];
|
|
342
391
|
|
|
343
|
-
//
|
|
344
|
-
pkg.scripts['get'] = 'slice
|
|
345
|
-
pkg.scripts['browse'] = 'slice
|
|
346
|
-
pkg.scripts['sync'] = 'slice
|
|
392
|
+
// Registry shortcuts
|
|
393
|
+
pkg.scripts['get'] = SLICE_SCRIPTS['slice:get'];
|
|
394
|
+
pkg.scripts['browse'] = SLICE_SCRIPTS['slice:browse'];
|
|
395
|
+
pkg.scripts['sync'] = SLICE_SCRIPTS['slice:sync'];
|
|
347
396
|
|
|
348
397
|
// slice:* namespaced set — shared with post.js and `slice postinstall`
|
|
349
398
|
// (commands/utils/sliceScripts.js) so the three never drift apart.
|
|
350
399
|
Object.assign(pkg.scripts, SLICE_SCRIPTS);
|
|
351
|
-
pkg.scripts['run'] = 'slice
|
|
400
|
+
pkg.scripts['run'] = SLICE_SCRIPTS['slice:dev'];
|
|
352
401
|
|
|
353
402
|
// Module configuration
|
|
354
403
|
pkg.type = 'module';
|
|
@@ -378,9 +427,9 @@ export default async function initializeProject(options = {}) {
|
|
|
378
427
|
Print.title('Next steps:');
|
|
379
428
|
console.log(` cd ${projectName}`);
|
|
380
429
|
console.log(` ${packageManager} run dev - Start development server`);
|
|
381
|
-
console.log(
|
|
382
|
-
console.log(
|
|
383
|
-
console.log(
|
|
430
|
+
console.log(` ${packageManager} run browse - View available components`);
|
|
431
|
+
console.log(` ${packageManager} run get -- Button - Install specific components`);
|
|
432
|
+
console.log(` ${packageManager} run sync - Update all components to latest versions`);
|
|
384
433
|
|
|
385
434
|
} catch (error) {
|
|
386
435
|
Print.error('Unexpected error initializing project:', error.message);
|
|
@@ -1,29 +1,28 @@
|
|
|
1
1
|
// commands/utils/PackageManager.js
|
|
2
2
|
//
|
|
3
|
-
// Package manager detection and command building (
|
|
3
|
+
// Package manager detection and command building (pnpm / npm).
|
|
4
4
|
// Resolution priority for an existing project:
|
|
5
5
|
// 1. "packageManager" field in the project package.json (corepack convention)
|
|
6
6
|
// 2. Lockfile present at the project root
|
|
7
7
|
// 3. npm_config_user_agent (set when the CLI runs via `npx` / `pnpm dlx` / a PM script)
|
|
8
8
|
// 4. The only PM binary available on PATH (if exactly one)
|
|
9
9
|
// When everything is ambiguous, detectPackageManager() returns null so callers
|
|
10
|
-
// can prompt the user (interactive init) or fall back to
|
|
10
|
+
// can prompt the user (interactive init) or fall back to pnpm (non-interactive).
|
|
11
11
|
|
|
12
12
|
import fs from 'fs-extra'
|
|
13
13
|
import path from 'path'
|
|
14
14
|
import { spawnSync } from 'node:child_process'
|
|
15
15
|
|
|
16
|
-
export const SUPPORTED_PACKAGE_MANAGERS = ['
|
|
16
|
+
export const SUPPORTED_PACKAGE_MANAGERS = ['pnpm', 'npm']
|
|
17
17
|
|
|
18
18
|
const LOCKFILES = {
|
|
19
19
|
'pnpm-lock.yaml': 'pnpm',
|
|
20
|
-
'package-lock.json': 'npm'
|
|
21
|
-
'yarn.lock': 'yarn'
|
|
20
|
+
'package-lock.json': 'npm'
|
|
22
21
|
}
|
|
23
22
|
|
|
24
23
|
export function parseUserAgent(userAgent = process.env.npm_config_user_agent) {
|
|
25
24
|
if (!userAgent) return null
|
|
26
|
-
const match = userAgent.match(/^(npm|pnpm
|
|
25
|
+
const match = userAgent.match(/^(npm|pnpm)\/(\S+)/)
|
|
27
26
|
if (!match) return null
|
|
28
27
|
return { name: match[1], version: match[2], source: 'user-agent' }
|
|
29
28
|
}
|
|
@@ -34,7 +33,7 @@ export function fromPackageManagerField(projectRoot) {
|
|
|
34
33
|
if (!fs.pathExistsSync(pkgPath)) return null
|
|
35
34
|
const pkg = fs.readJsonSync(pkgPath)
|
|
36
35
|
if (typeof pkg.packageManager !== 'string') return null
|
|
37
|
-
const match = pkg.packageManager.match(/^(npm|pnpm
|
|
36
|
+
const match = pkg.packageManager.match(/^(npm|pnpm)@(\S+)/)
|
|
38
37
|
if (!match) return null
|
|
39
38
|
return { name: match[1], version: match[2], source: 'package-manager-field' }
|
|
40
39
|
} catch {
|
|
@@ -109,7 +108,7 @@ export function detectPackageManager(projectRoot, { userAgent = process.env.npm_
|
|
|
109
108
|
}
|
|
110
109
|
|
|
111
110
|
/**
|
|
112
|
-
* Non-interactive resolution: detection first, then
|
|
111
|
+
* Non-interactive resolution: detection first, then pnpm if available,
|
|
113
112
|
* then whatever binary exists. Never returns null so update/doctor flows
|
|
114
113
|
* always have a usable PM name (commands fail later with a clear error
|
|
115
114
|
* if no PM is actually installed).
|
|
@@ -119,16 +118,17 @@ export function resolvePackageManager(projectRoot, options = {}) {
|
|
|
119
118
|
if (detected) return detected
|
|
120
119
|
|
|
121
120
|
const available = getAvailablePackageManagers()
|
|
121
|
+
if (available.includes('pnpm')) return { name: 'pnpm', version: null, source: 'fallback' }
|
|
122
122
|
if (available.includes('npm')) return { name: 'npm', version: null, source: 'fallback' }
|
|
123
123
|
if (available.length > 0) return { name: available[0], version: null, source: 'fallback' }
|
|
124
|
-
return { name: '
|
|
124
|
+
return { name: 'pnpm', version: null, source: 'fallback (none detected)' }
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
export function installCommand(pmName, packages, { dev = false, global: isGlobal = false } = {}) {
|
|
128
128
|
const pkgs = Array.isArray(packages) ? packages.join(' ') : packages
|
|
129
129
|
const flags = [isGlobal ? '-g' : '', dev ? '-D' : ''].filter(Boolean).join(' ')
|
|
130
130
|
const flagSuffix = flags ? ` ${flags}` : ''
|
|
131
|
-
if (pmName === 'pnpm'
|
|
131
|
+
if (pmName === 'pnpm') {
|
|
132
132
|
return `${pmName} add${flagSuffix} ${pkgs}`
|
|
133
133
|
}
|
|
134
134
|
return `npm install${flagSuffix} ${pkgs}`
|
|
@@ -137,7 +137,7 @@ export function installCommand(pmName, packages, { dev = false, global: isGlobal
|
|
|
137
137
|
export function uninstallCommand(pmName, packages, { global: isGlobal = false } = {}) {
|
|
138
138
|
const pkgs = Array.isArray(packages) ? packages.join(' ') : packages
|
|
139
139
|
const flagSuffix = isGlobal ? ' -g' : ''
|
|
140
|
-
if (pmName === 'pnpm'
|
|
140
|
+
if (pmName === 'pnpm') {
|
|
141
141
|
return `${pmName} remove${flagSuffix} ${pkgs}`
|
|
142
142
|
}
|
|
143
143
|
return `npm uninstall${flagSuffix} ${pkgs}`
|
|
@@ -5,17 +5,19 @@
|
|
|
5
5
|
// client.js, and `slice init` — so the three can never drift apart (they did:
|
|
6
6
|
// client.js was missing slice:types, and none of them had slice:build).
|
|
7
7
|
export const SLICE_SCRIPTS = {
|
|
8
|
-
'slice:init': '
|
|
9
|
-
'slice:dev': '
|
|
10
|
-
'slice:build': '
|
|
11
|
-
'slice:start': '
|
|
12
|
-
'slice:create': '
|
|
13
|
-
'slice:list': '
|
|
14
|
-
'slice:delete': '
|
|
15
|
-
'slice:get': '
|
|
16
|
-
'slice:browse': '
|
|
17
|
-
'slice:sync': '
|
|
18
|
-
'slice:
|
|
19
|
-
'slice:
|
|
20
|
-
'slice:
|
|
8
|
+
'slice:init': 'node ./node_modules/slicejs-cli/client.js init',
|
|
9
|
+
'slice:dev': 'node ./node_modules/slicejs-cli/client.js dev',
|
|
10
|
+
'slice:build': 'node ./node_modules/slicejs-cli/client.js build',
|
|
11
|
+
'slice:start': 'node ./node_modules/slicejs-cli/client.js start',
|
|
12
|
+
'slice:create': 'node ./node_modules/slicejs-cli/client.js component create',
|
|
13
|
+
'slice:list': 'node ./node_modules/slicejs-cli/client.js component list',
|
|
14
|
+
'slice:delete': 'node ./node_modules/slicejs-cli/client.js component delete',
|
|
15
|
+
'slice:get': 'node ./node_modules/slicejs-cli/client.js get',
|
|
16
|
+
'slice:browse': 'node ./node_modules/slicejs-cli/client.js browse',
|
|
17
|
+
'slice:sync': 'node ./node_modules/slicejs-cli/client.js sync',
|
|
18
|
+
'slice:doctor': 'node ./node_modules/slicejs-cli/client.js doctor',
|
|
19
|
+
'slice:version': 'node ./node_modules/slicejs-cli/client.js version',
|
|
20
|
+
'slice:help': 'node ./node_modules/slicejs-cli/client.js --help',
|
|
21
|
+
'slice:update': 'node ./node_modules/slicejs-cli/client.js update',
|
|
22
|
+
'slice:types': 'node ./node_modules/slicejs-cli/client.js types generate',
|
|
21
23
|
};
|
package/package.json
CHANGED
package/post.js
CHANGED
|
@@ -3,6 +3,7 @@ import path from 'path';
|
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
4
|
import { getProjectRoot, getPath } from './commands/utils/PathHelper.js';
|
|
5
5
|
import { SLICE_SCRIPTS } from './commands/utils/sliceScripts.js';
|
|
6
|
+
import { resolvePackageManager, runScriptCommand } from './commands/utils/PackageManager.js';
|
|
6
7
|
|
|
7
8
|
const __filename = fileURLToPath(import.meta.url);
|
|
8
9
|
|
|
@@ -21,6 +22,7 @@ if (isGlobal) {
|
|
|
21
22
|
|
|
22
23
|
const projectRoot = getProjectRoot(import.meta.url);
|
|
23
24
|
const pkgPath = getPath(import.meta.url, 'package.json');
|
|
25
|
+
const packageManager = resolvePackageManager(projectRoot).name;
|
|
24
26
|
|
|
25
27
|
const sliceScripts = SLICE_SCRIPTS;
|
|
26
28
|
|
|
@@ -47,12 +49,12 @@ try {
|
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2), 'utf-8');
|
|
50
|
-
console.log(`✅ slicejs-cli installed successfully. Added ${addedCount}
|
|
51
|
-
console.log(
|
|
52
|
+
console.log(`✅ slicejs-cli installed successfully. Added ${addedCount} package scripts to package.json.`);
|
|
53
|
+
console.log(` Run: ${runScriptCommand(packageManager, 'slice:dev')}`);
|
|
52
54
|
} catch (err) {
|
|
53
55
|
console.log('✅ slicejs-cli installed successfully.');
|
|
54
56
|
console.log(' Could not auto-configure scripts:', err.message);
|
|
55
|
-
console.log(
|
|
57
|
+
console.log(` Configure scripts manually and run: ${runScriptCommand(packageManager, 'slice:dev')}`);
|
|
56
58
|
}
|
|
57
59
|
|
|
58
60
|
process.exit(0);
|