slicejs-cli 3.3.0 → 3.4.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/AGENTS.md +247 -0
- package/LICENSE +21 -21
- package/client.js +663 -626
- package/commands/Print.js +163 -167
- package/commands/Validations.js +92 -103
- package/commands/build/build.js +40 -40
- package/commands/buildProduction/buildProduction.js +576 -579
- package/commands/bundle/bundle.js +234 -235
- package/commands/createComponent/VisualComponentTemplate.js +55 -55
- package/commands/createComponent/createComponent.js +124 -126
- package/commands/deleteComponent/deleteComponent.js +77 -77
- package/commands/doctor/doctor.js +366 -369
- package/commands/getComponent/getComponent.js +684 -747
- package/commands/init/init.js +269 -261
- package/commands/listComponents/listComponents.js +172 -175
- package/commands/startServer/startServer.js +261 -264
- package/commands/startServer/watchServer.js +79 -79
- package/commands/types/types.js +69 -27
- package/commands/utils/LocalCliDelegation.js +53 -53
- package/commands/utils/PathHelper.js +75 -68
- package/commands/utils/VersionChecker.js +167 -167
- package/commands/utils/bundling/BundleGenerator.js +2292 -2292
- package/commands/utils/bundling/DependencyAnalyzer.js +925 -933
- package/commands/utils/loadConfig.js +31 -0
- package/commands/utils/updateManager.js +452 -453
- package/docs/superpowers/specs/2026-05-10-pwa-generate-design.md +105 -105
- package/package.json +58 -46
- package/post.js +66 -65
- package/tests/bundle-generator.test.js +691 -708
- package/tests/bundle-v2-register-output.test.js +470 -470
- package/tests/client-launcher-contract.test.js +211 -211
- package/tests/client-update-flow-contract.test.js +272 -272
- package/tests/component-registry-parse.test.js +34 -0
- package/tests/dependency-analyzer.test.js +24 -24
- package/tests/fixtures/components.js +8 -0
- package/tests/fixtures/sliceConfig.json +74 -0
- package/tests/getcomponent.test.js +407 -0
- package/tests/helpers/setup.js +97 -0
- package/tests/init-command-contract.test.js +46 -0
- package/tests/local-cli-delegation.test.js +81 -79
- package/tests/path-helper.test.js +206 -0
- package/tests/types-breakage.test.js +491 -0
- package/tests/types-generator-errors.test.js +361 -0
- package/tests/types-generator.test.js +172 -184
- package/tests/update-manager-notifications.test.js +88 -88
- package/.github/workflows/docs-render-cicd.yml +0 -65
package/AGENTS.md
ADDED
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
# Slice.js CLI — Agent Context
|
|
2
|
+
|
|
3
|
+
## Project Structure
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
slicejs-cli/
|
|
7
|
+
├── client.js # CLI entry point (commander)
|
|
8
|
+
├── commands/
|
|
9
|
+
│ ├── init/init.js # slice init
|
|
10
|
+
│ ├── startServer/startServer.js # slice dev / slice start
|
|
11
|
+
│ ├── build/build.js # slice build
|
|
12
|
+
│ ├── getComponent/getComponent.js # slice get / browse / sync
|
|
13
|
+
│ ├── createComponent/ # slice component create
|
|
14
|
+
│ ├── listComponents/ # slice component list
|
|
15
|
+
│ ├── deleteComponent/ # slice component delete
|
|
16
|
+
│ ├── doctor/doctor.js # slice doctor
|
|
17
|
+
│ ├── types/types.js # slice types generate
|
|
18
|
+
│ ├── bundle/bundle.js # bundling logic
|
|
19
|
+
│ ├── utils/
|
|
20
|
+
│ │ ├── PathHelper.js # Path resolution (critical)
|
|
21
|
+
│ │ ├── bundling/BundleGenerator.js
|
|
22
|
+
│ │ ├── updateManager.js
|
|
23
|
+
│ │ ├── VersionChecker.js
|
|
24
|
+
│ │ └── LocalCliDelegation.js
|
|
25
|
+
│ └── Print.js # Wrapper for console.log/error
|
|
26
|
+
├── tests/
|
|
27
|
+
│ ├── helpers/setup.js # Shared test helper (createTestProject, withTestProject)
|
|
28
|
+
│ ├── fixtures/ # Minimal fixture files for tests
|
|
29
|
+
│ ├── bundle-generator.test.js
|
|
30
|
+
│ ├── bundle-v2-register-output.test.js
|
|
31
|
+
│ ├── client-launcher-contract.test.js
|
|
32
|
+
│ ├── client-update-flow-contract.test.js
|
|
33
|
+
│ ├── component-registry-parse.test.js
|
|
34
|
+
│ ├── dependency-analyzer.test.js
|
|
35
|
+
│ ├── init-command-contract.test.js
|
|
36
|
+
│ ├── local-cli-delegation.test.js
|
|
37
|
+
│ ├── path-helper.test.js
|
|
38
|
+
│ ├── postinstall-command.test.js
|
|
39
|
+
│ ├── types-generator.test.js
|
|
40
|
+
│ └── update-manager-notifications.test.js
|
|
41
|
+
├── package.json # type: "module" — ES modules only
|
|
42
|
+
└── AGENTS.md # This file
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Testing System
|
|
46
|
+
|
|
47
|
+
### Runner
|
|
48
|
+
- Uses Node.js built-in test runner: `node --test`
|
|
49
|
+
- Run: `npm test`
|
|
50
|
+
- Watch mode: `node --test --watch`
|
|
51
|
+
|
|
52
|
+
### Shared Test Helper (`tests/helpers/setup.js`)
|
|
53
|
+
Three exported functions:
|
|
54
|
+
|
|
55
|
+
```js
|
|
56
|
+
import { createTestProject, cleanupTestProject, withTestProject } from './helpers/setup.js';
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**`createTestProject(options)`** — Creates a temp directory with full Slice.js project scaffold.
|
|
60
|
+
- Copies real framework files from `../slice.js/` (sibling directory in monorepo)
|
|
61
|
+
- Falls back to `tests/fixtures/` minimal scaffold if framework not available
|
|
62
|
+
- Options:
|
|
63
|
+
- `visualComponents: ['Button']` — creates stub component files + rewrites `components.js` to include only those
|
|
64
|
+
- `frameworkDir` — custom framework source path
|
|
65
|
+
- Returns the temp directory path
|
|
66
|
+
- Temp dir path: `{os.tmpdir()}/slice-test-{PID}-{N}-{random}/`
|
|
67
|
+
|
|
68
|
+
**`cleanupTestProject(dir)`** — Removes the temp directory recursively.
|
|
69
|
+
|
|
70
|
+
**`withTestProject(fn, options)`** — Convenience wrapper that:
|
|
71
|
+
1. Calls `createTestProject(options)`
|
|
72
|
+
2. Saves and sets `process.env.INIT_CWD = dir`
|
|
73
|
+
3. Runs `fn(dir)`
|
|
74
|
+
4. Restores `process.env.INIT_CWD` to original value
|
|
75
|
+
5. Calls `cleanupTestProject(dir)` in `finally`
|
|
76
|
+
|
|
77
|
+
### Patterns
|
|
78
|
+
|
|
79
|
+
**For tests that need INIT_CWD pointing to the project:**
|
|
80
|
+
```js
|
|
81
|
+
test('my test', async () => {
|
|
82
|
+
await withTestProject(async (tmpDir) => {
|
|
83
|
+
// process.env.INIT_CWD is already set to tmpDir
|
|
84
|
+
const result = someFunction(import.meta.url);
|
|
85
|
+
assert.ok(result);
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**For tests that pass projectRoot explicitly:**
|
|
91
|
+
```js
|
|
92
|
+
test('my test', async () => {
|
|
93
|
+
const tmpRoot = await createTestProject({ visualComponents: ['Button'] });
|
|
94
|
+
try {
|
|
95
|
+
const result = await someFunction({ projectRoot: tmpRoot });
|
|
96
|
+
assert.equal(result, 1);
|
|
97
|
+
} finally {
|
|
98
|
+
await cleanupTestProject(tmpRoot);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**For tests with shared project setup across a describe block:**
|
|
104
|
+
```js
|
|
105
|
+
let tmpRoot;
|
|
106
|
+
before(async () => {
|
|
107
|
+
tmpRoot = await createTestProject();
|
|
108
|
+
process.env.INIT_CWD = tmpRoot;
|
|
109
|
+
});
|
|
110
|
+
after(async () => {
|
|
111
|
+
delete process.env.INIT_CWD;
|
|
112
|
+
await cleanupTestProject(tmpRoot);
|
|
113
|
+
});
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Test types
|
|
117
|
+
|
|
118
|
+
1. **Contract tests** (`*-contract.test.js`) — Static analysis of `client.js` source code via `@babel/parser` + AST or regex. Verify command registration, option flags, and function calls. No runtime execution.
|
|
119
|
+
2. **Unit tests** — Test individual functions/modules in isolation. Use temp dirs for filesystem-dependent code.
|
|
120
|
+
3. **Snapshot/Integration tests** — Verify output files, generated declarations, bundle configs.
|
|
121
|
+
|
|
122
|
+
### Rules
|
|
123
|
+
- No external mocking libraries (sinon, jest, etc.). Use monkey-patching + try/finally restore.
|
|
124
|
+
- All temp dirs MUST be cleaned up in `finally` blocks.
|
|
125
|
+
- `process.env.INIT_CWD` must be saved before modification and restored in `finally`.
|
|
126
|
+
- Dynamic `import()` is used where module caching matters, but PathHelper reads env vars at call time so cached modules work correctly.
|
|
127
|
+
|
|
128
|
+
## PathHelper Rules (`commands/utils/PathHelper.js`)
|
|
129
|
+
|
|
130
|
+
### Project Root Resolution
|
|
131
|
+
`getProjectRoot(moduleUrl)` resolves in this order:
|
|
132
|
+
1. `process.env.INIT_CWD` — set by npm or by `withTestProject` during tests
|
|
133
|
+
2. `process.cwd()` — current working directory
|
|
134
|
+
3. `candidates(moduleUrl)` — heuristic: walk up `../../` and `../../../../` from module location, check for `src/` or `api/`
|
|
135
|
+
|
|
136
|
+
### Functions
|
|
137
|
+
|
|
138
|
+
| Function | Returns | Notes |
|
|
139
|
+
|---|---|---|
|
|
140
|
+
| `getProjectRoot(moduleUrl)` | Resolved project root path | |
|
|
141
|
+
| `getSrcPath(moduleUrl, ...seg)` | `<root>/src/[...seg]` | |
|
|
142
|
+
| `getApiPath(moduleUrl, ...seg)` | `<root>/api/[...seg]` | |
|
|
143
|
+
| `getDistPath(moduleUrl, ...seg)` | `<root>/dist/[...seg]` | |
|
|
144
|
+
| `getPath(moduleUrl, ...seg)` | `<root>/[...seg]` | General purpose |
|
|
145
|
+
| `getConfigPath(moduleUrl, root?)` | `src/sliceConfig.json` | Optional explicit root param |
|
|
146
|
+
| `getComponentsJsPath(moduleUrl, root?)` | `src/Components/components.js` | Optional explicit root param |
|
|
147
|
+
| `joinRoot(root, ...seg)` | `<root>/[...seg]` | No moduleUrl needed, pure path join |
|
|
148
|
+
|
|
149
|
+
### Critical Rules
|
|
150
|
+
|
|
151
|
+
1. **`import.meta.url` must be passed** as first argument to all PathHelper functions (except `joinRoot`).
|
|
152
|
+
2. **Explicit root parameter** (`getConfigPath`, `getComponentsJsPath`) is used by `types/types.js` when generating types for a non-cwd project. This keeps functions testable without global state.
|
|
153
|
+
3. **`INIT_CWD` is the primary mechanism** for project root resolution. It's set by npm lifecycle scripts and by `withTestProject`.
|
|
154
|
+
4. **`candidates()` fallback** only works when the CLI is installed inside a project that has `src/` or `api/`. This is intentionally limited.
|
|
155
|
+
|
|
156
|
+
## Code Quality Standards
|
|
157
|
+
|
|
158
|
+
### ES Modules Only
|
|
159
|
+
- `"type": "module"` in `package.json`
|
|
160
|
+
- Use `import`/`export` everywhere
|
|
161
|
+
- NO `require()`, NO `__dirname` at module scope (use `path.dirname(fileURLToPath(import.meta.url))` inline where needed)
|
|
162
|
+
|
|
163
|
+
### No eval()
|
|
164
|
+
- `eval()` has been fully replaced with `JSON.parse()` for reading `components.js` files
|
|
165
|
+
- Components are written via `JSON.stringify()`, so content is always valid JSON
|
|
166
|
+
- Use `JSON.parse()` or the AST-based `ComponentRegistry` for component registry parsing
|
|
167
|
+
|
|
168
|
+
### Error Messages
|
|
169
|
+
- Bare error messages (just the error message without context) must NOT be used
|
|
170
|
+
- Always wrap errors with context: `Print.error('Context:', error.message)`
|
|
171
|
+
- Use `Print.error()` / `Print.success()` / `Print.info()` / `Print.warning()` instead of raw `console.log`/`console.error`
|
|
172
|
+
- EXCEPTION: Formatted help/command listing output can use `console.log` directly (avoids `ℹ️ Info:` prefix pollution)
|
|
173
|
+
|
|
174
|
+
### Empty Catch Blocks
|
|
175
|
+
- Silent catches are acceptable ONLY for:
|
|
176
|
+
- Non-critical operations (update checks, optional config reads)
|
|
177
|
+
- Graceful degradation paths
|
|
178
|
+
- All silent catches MUST have a comment explaining why: `catch { /* intentional: non-critical */ }`
|
|
179
|
+
|
|
180
|
+
### Port Resolution (startServer)
|
|
181
|
+
Priority order:
|
|
182
|
+
1. `--port` CLI flag (if provided by user)
|
|
183
|
+
2. `config.server.port` from `sliceConfig.json`
|
|
184
|
+
3. Hardcoded `3000` fallback
|
|
185
|
+
|
|
186
|
+
Commander `.option()` defaults must NOT override config values. Pass `undefined` when flag is not provided:
|
|
187
|
+
```js
|
|
188
|
+
port: options.port ? parseInt(options.port) : undefined
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Dependency Injection for Testability
|
|
192
|
+
- Functions that need a project root accept it as a parameter (`projectRoot`, `root`)
|
|
193
|
+
- PathHelper functions that accept an explicit root param enable testing without INIT_CWD gymnastics
|
|
194
|
+
- Avoid reading `process.env.INIT_CWD` or `process.cwd()` directly inside business logic; use PathHelper
|
|
195
|
+
|
|
196
|
+
## CLI Architecture (client.js)
|
|
197
|
+
|
|
198
|
+
### Command Registration Pattern
|
|
199
|
+
```js
|
|
200
|
+
sliceClient
|
|
201
|
+
.command("mycommand")
|
|
202
|
+
.description("...")
|
|
203
|
+
.option("-x, --flag <value>", "...")
|
|
204
|
+
.action(async (options) => {
|
|
205
|
+
// 1. Handle --yes / non-interactive flags before prompts
|
|
206
|
+
// 2. Prompt for missing required values
|
|
207
|
+
// 3. Delegate to command implementation
|
|
208
|
+
await runWithVersionCheck(async () => {
|
|
209
|
+
await myCommandImplementation(options);
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### `runWithVersionCheck(commandFunction)`
|
|
215
|
+
- Wraps every command action
|
|
216
|
+
- Responsibilities:
|
|
217
|
+
1. Fire-and-forget update notification (`notifyAvailableUpdates().catch(() => {})`)
|
|
218
|
+
2. Execute the command
|
|
219
|
+
3. Background version check (`checkForUpdates(false)` after 100ms delay)
|
|
220
|
+
- Does NOT block or prompt the user (pre-flight checks were removed)
|
|
221
|
+
- Errors are caught and logged via `Print.error()`
|
|
222
|
+
|
|
223
|
+
### Init Command (`slice init`)
|
|
224
|
+
- Default project name: `my-slice-app`
|
|
225
|
+
- `-y`/`--yes [name]` flag skips interactive prompts
|
|
226
|
+
- Creates project directory, `chdir`s into it, sets `INIT_CWD`
|
|
227
|
+
- Calls `initializeProject()` from `commands/init/init.js`
|
|
228
|
+
- Name normalization: trim → lowercase → spaces to hyphens → strip non-alphanumeric → collapse hyphens → trim hyphens
|
|
229
|
+
|
|
230
|
+
### Local CLI Delegation
|
|
231
|
+
- `maybeDelegateToLocalCli()` runs at module level before command parsing
|
|
232
|
+
- If a local `node_modules/slicejs-cli/` exists, spawns it instead of running the global CLI
|
|
233
|
+
- Controlled by `SLICE_NO_LOCAL_DELEGATION` env var
|
|
234
|
+
|
|
235
|
+
## Visual Component Registry
|
|
236
|
+
- Components downloaded from GitHub: `https://raw.githubusercontent.com/VKneider/slice.js_visual_library/master/src/Components/{category}/{Name}/{file}`
|
|
237
|
+
- Registry URL: same base + `src/Components/components.js`
|
|
238
|
+
- Starter visual components on init: Button, Link, Loading, MultiRoute, Navbar, NotFound, Route
|
|
239
|
+
- Components are registered by writing to `src/Components/components.js`
|
|
240
|
+
|
|
241
|
+
### File Download Rules (in `getAvailableComponents`)
|
|
242
|
+
- **Routing/navigation components** (`Route`, `MultiRoute`, `Link`): only `.js` file
|
|
243
|
+
- **Other Visual components** (Button, Loading, Navbar, etc.): `.js`, `.html`, `.css`
|
|
244
|
+
- **Service components** (FetchManager, etc.): only `.js` file
|
|
245
|
+
- File list is determined by hardcoded rules, NOT by checking the remote server
|
|
246
|
+
- If `.js` download fails → component install fails (fatal)
|
|
247
|
+
- If `.html`/`.css` fails → component install succeeds with warning
|
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2024 Victor Jose Kneider Alnahi and Julio Antonio Graterol Bracho
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Victor Jose Kneider Alnahi and Julio Antonio Graterol Bracho
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|