slicejs-cli 2.9.5 → 3.0.2

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 CHANGED
@@ -45,6 +45,29 @@ npm run dev
45
45
  npm run slice -- get Button
46
46
  ```
47
47
 
48
+ 4. Use `slice` directly when the launcher command is available on your system
49
+ (commonly after a global install that puts `slice` in your PATH).
50
+ The launcher delegates to your nearest project-local `node_modules/slicejs-cli`
51
+ so project-pinned behavior is used from the project root and subdirectories.
52
+
53
+ ```bash
54
+ slice dev
55
+ slice build
56
+ slice version
57
+ ```
58
+
59
+ If `slice` is not available in your shell, use:
60
+
61
+ ```bash
62
+ npx slicejs-cli dev
63
+ ```
64
+
65
+ You can disable launcher delegation for a command when needed:
66
+
67
+ ```bash
68
+ SLICE_NO_LOCAL_DELEGATION=1 slice version
69
+ ```
70
+
48
71
  ### Global (Not Recommended)
49
72
 
50
73
  Global installations can lead to version mismatches and "works on my machine" issues.
@@ -55,7 +78,10 @@ npm install -g slicejs-cli
55
78
 
56
79
  ## Usage
57
80
 
58
- After installation, you can use the `slice` command directly:
81
+ After installation, prefer your project-local CLI. When the `slice` launcher command is
82
+ available, it automatically delegates to the nearest local `slicejs-cli` install.
83
+
84
+ Use the `slice` command directly:
59
85
 
60
86
  ```bash
61
87
  slice [command] [options]
@@ -67,6 +93,8 @@ Or with npx (without global install):
67
93
  npx slicejs-cli [command]
68
94
  ```
69
95
 
96
+ Use `npx slicejs-cli [command]` as a fallback when the `slice` launcher command is unavailable.
97
+
70
98
  ## Essential Commands
71
99
 
72
100
  ### Initialize a project
@@ -154,7 +182,7 @@ slice sync
154
182
  ```bash
155
183
  # Version info
156
184
  slice version
157
- slice -v
185
+ slice v
158
186
 
159
187
  # Updates (CLI and Framework)
160
188
  slice update # Check and prompt to update
@@ -325,16 +353,16 @@ slice init
325
353
  ### Command not found
326
354
 
327
355
  ```bash
328
- # Use npx if not installed globally
356
+ # If the launcher command is unavailable, run the local CLI via npx
329
357
  npx slicejs-cli dev
330
358
 
331
- # Or install globally
359
+ # Optional: install globally to expose the slice launcher command
332
360
  npm install -g slicejs-cli
333
361
  ```
334
362
 
335
363
  ## Links
336
364
 
337
- - 📘 Documentation: https://slice-js-docs.vercel.app/
365
+ - 📘 CLI Documentation: https://slice-js-docs.vercel.app/Documentation/CLI
338
366
  - 🐙 GitHub: https://github.com/VKneider/slice-cli
339
367
  - 📦 npm: https://www.npmjs.com/package/slicejs-cli
340
368
 
package/client.js CHANGED
@@ -14,12 +14,18 @@ import fs from "fs";
14
14
  import path from "path";
15
15
  import { fileURLToPath } from "url";
16
16
  import { getConfigPath, getProjectRoot } from "./commands/utils/PathHelper.js";
17
- import { exec } from "child_process";
17
+ import { exec, spawnSync } from "node:child_process";
18
18
  import { promisify } from "util";
19
19
  import validations from "./commands/Validations.js";
20
20
  import Print from "./commands/Print.js";
21
21
  import build from './commands/build/build.js';
22
22
  import { cleanBundles, bundleInfo } from './commands/bundle/bundle.js';
23
+ import {
24
+ isLocalDelegationDisabled,
25
+ findNearestLocalCliEntry,
26
+ resolveLocalCliCandidate,
27
+ shouldDelegateToLocalCli
28
+ } from './commands/utils/LocalCliDelegation.js';
23
29
 
24
30
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
25
31
 
@@ -84,10 +90,7 @@ async function runWithVersionCheck(commandFunction, ...args) {
84
90
  } catch {}
85
91
  })();
86
92
 
87
- const updateInfo = await updateManager.checkForUpdates();
88
- if (updateInfo && updateInfo.hasUpdates) {
89
- await updateManager.checkAndPromptUpdates({});
90
- }
93
+ updateManager.notifyAvailableUpdates().catch(() => {});
91
94
 
92
95
  const result = await commandFunction(...args);
93
96
 
@@ -102,6 +105,33 @@ async function runWithVersionCheck(commandFunction, ...args) {
102
105
  }
103
106
  }
104
107
 
108
+ function maybeDelegateToLocalCli() {
109
+ if (isLocalDelegationDisabled(process.env)) {
110
+ return;
111
+ }
112
+
113
+ const currentEntryPath = fileURLToPath(import.meta.url);
114
+ const localEntryPath = findNearestLocalCliEntry(process.cwd(), resolveLocalCliCandidate);
115
+
116
+ if (!shouldDelegateToLocalCli(currentEntryPath, localEntryPath)) {
117
+ return;
118
+ }
119
+
120
+ const child = spawnSync(
121
+ process.execPath,
122
+ [localEntryPath, ...process.argv.slice(2)],
123
+ {
124
+ stdio: 'inherit',
125
+ cwd: process.cwd(),
126
+ env: process.env
127
+ }
128
+ );
129
+
130
+ process.exit(child.status ?? 1);
131
+ }
132
+
133
+ maybeDelegateToLocalCli();
134
+
105
135
  const sliceClient = program;
106
136
 
107
137
  try {
@@ -0,0 +1,53 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ function getParentDirectory(dir) {
5
+ const parent = path.dirname(dir);
6
+ return parent === dir ? null : parent;
7
+ }
8
+
9
+ export function isLocalDelegationDisabled(env = process.env) {
10
+ return env.SLICE_NO_LOCAL_DELEGATION === '1';
11
+ }
12
+
13
+ export function findNearestLocalCliEntry(startDirectory, resolveCandidate) {
14
+ if (!startDirectory || typeof resolveCandidate !== 'function') {
15
+ return null;
16
+ }
17
+
18
+ let current = path.resolve(startDirectory);
19
+ while (current) {
20
+ const candidate = resolveCandidate(current);
21
+ if (candidate) {
22
+ return candidate;
23
+ }
24
+ current = getParentDirectory(current);
25
+ }
26
+
27
+ return null;
28
+ }
29
+
30
+ export function resolveLocalCliCandidate(directory) {
31
+ const candidate = path.join(directory, 'node_modules', 'slicejs-cli', 'client.js');
32
+
33
+ try {
34
+ const stats = fs.statSync(candidate);
35
+ return stats.isFile() ? candidate : null;
36
+ } catch {
37
+ return null;
38
+ }
39
+ }
40
+
41
+ export function shouldDelegateToLocalCli(currentEntryPath, localEntryPath) {
42
+ if (!localEntryPath) {
43
+ return false;
44
+ }
45
+
46
+ try {
47
+ const currentReal = fs.realpathSync(currentEntryPath);
48
+ const localReal = fs.realpathSync(localEntryPath);
49
+ return currentReal !== localReal;
50
+ } catch {
51
+ return path.resolve(currentEntryPath) !== path.resolve(localEntryPath);
52
+ }
53
+ }