slicejs-cli 3.2.0 → 3.3.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/.github/ISSUE_TEMPLATE/bug_report.md +29 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +25 -0
- package/.github/pull_request_template.md +22 -0
- package/.github/workflows/docs-render-cicd.yml +65 -0
- package/CODE_OF_CONDUCT.md +126 -0
- package/ECOSYSTEM.md +9 -0
- package/LICENSE +21 -0
- package/README.md +171 -375
- package/client.js +66 -3
- package/package.json +1 -1
- package/post.js +50 -10
- package/tests/postinstall-command.test.js +72 -0
- package/refactor.md +0 -271
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug Report
|
|
3
|
+
about: Report a bug in a component or the parser
|
|
4
|
+
title: ''
|
|
5
|
+
labels: bug
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Description
|
|
10
|
+
A clear description of the bug.
|
|
11
|
+
|
|
12
|
+
## Reproduction
|
|
13
|
+
Steps to reproduce:
|
|
14
|
+
1. Go to '...'
|
|
15
|
+
2. Click on '...'
|
|
16
|
+
3. Error: '...'
|
|
17
|
+
|
|
18
|
+
## Expected behavior
|
|
19
|
+
What should have happened.
|
|
20
|
+
|
|
21
|
+
## Environment
|
|
22
|
+
- Browser/Node version:
|
|
23
|
+
- OS:
|
|
24
|
+
- slice.js_visual_library version:
|
|
25
|
+
|
|
26
|
+
## Screenshots / Console output
|
|
27
|
+
If applicable.
|
|
28
|
+
|
|
29
|
+
## Additional context
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature Request
|
|
3
|
+
about: Suggest a new component or improvement
|
|
4
|
+
title: ''
|
|
5
|
+
labels: enhancement
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Problem
|
|
10
|
+
What problem does this solve? (e.g. "I need a component that...")
|
|
11
|
+
|
|
12
|
+
## Proposed solution
|
|
13
|
+
How should it work? Include props, behavior, and visual details if applicable.
|
|
14
|
+
|
|
15
|
+
## Alternatives considered
|
|
16
|
+
What other approaches have you considered?
|
|
17
|
+
|
|
18
|
+
## Example usage
|
|
19
|
+
```javascript
|
|
20
|
+
const component = await slice.build('ComponentName', {
|
|
21
|
+
// props here
|
|
22
|
+
});
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Additional context
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
-
|
|
3
|
+
|
|
4
|
+
## Docs Scope
|
|
5
|
+
- [ ] Visual library docs pages (`src/markdown/` and generated outputs)
|
|
6
|
+
- [ ] Parser logic (`parser/`)
|
|
7
|
+
- [ ] Routes/index sync (`documentationRoutes.generated.js`, `docsIndex.js`, `components.js`)
|
|
8
|
+
|
|
9
|
+
## Verification
|
|
10
|
+
- [ ] `npm run docs:lint-md`
|
|
11
|
+
- [ ] `npm run docs:generate`
|
|
12
|
+
- [ ] `node --test parser/tests/index.test.js`
|
|
13
|
+
|
|
14
|
+
## Screenshots / UI Notes
|
|
15
|
+
-
|
|
16
|
+
|
|
17
|
+
## Breaking Changes
|
|
18
|
+
- [ ] None
|
|
19
|
+
- [ ] Yes (describe below)
|
|
20
|
+
|
|
21
|
+
## Additional Context
|
|
22
|
+
-
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
name: Docs Parse + Render CD
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches: [main]
|
|
6
|
+
push:
|
|
7
|
+
branches: [main]
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
contents: write
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
docs-pipeline:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- name: Checkout
|
|
19
|
+
uses: actions/checkout@v4
|
|
20
|
+
with:
|
|
21
|
+
fetch-depth: 0
|
|
22
|
+
|
|
23
|
+
- name: Setup Node
|
|
24
|
+
uses: actions/setup-node@v4
|
|
25
|
+
with:
|
|
26
|
+
node-version: '20'
|
|
27
|
+
cache: 'npm'
|
|
28
|
+
|
|
29
|
+
- name: Install dependencies
|
|
30
|
+
run: npm ci
|
|
31
|
+
|
|
32
|
+
- name: Validate markdown docs
|
|
33
|
+
run: npm run docs:lint-md
|
|
34
|
+
|
|
35
|
+
- name: Generate documentation artifacts
|
|
36
|
+
run: npm run docs:generate
|
|
37
|
+
|
|
38
|
+
- name: Check generated changes (PR)
|
|
39
|
+
if: github.event_name == 'pull_request'
|
|
40
|
+
run: |
|
|
41
|
+
if ! git diff --quiet; then
|
|
42
|
+
echo "Generated files are out of date. Run 'npm run docs:generate' and commit changes."
|
|
43
|
+
git status --short
|
|
44
|
+
exit 1
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
- name: Commit generated docs (main)
|
|
48
|
+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
49
|
+
run: |
|
|
50
|
+
if ! git diff --quiet; then
|
|
51
|
+
git config user.name "github-actions[bot]"
|
|
52
|
+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
53
|
+
git add src/Components src/Styles src/routes.js
|
|
54
|
+
git commit -m "chore(docs): auto-generate docs artifacts from markdown"
|
|
55
|
+
git push
|
|
56
|
+
else
|
|
57
|
+
echo "No generated changes to commit."
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
- name: Trigger Render deploy
|
|
61
|
+
if: github.event_name == 'push' && github.ref == 'refs/heads/main' && secrets.RENDER_DEPLOY_HOOK_URL != ''
|
|
62
|
+
run: |
|
|
63
|
+
curl --fail --silent --show-error --request POST "$RENDER_DEPLOY_HOOK_URL"
|
|
64
|
+
env:
|
|
65
|
+
RENDER_DEPLOY_HOOK_URL: ${{ secrets.RENDER_DEPLOY_HOOK_URL }}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
|
2
|
+
|
|
3
|
+
## Our Pledge
|
|
4
|
+
|
|
5
|
+
We as members, contributors, and leaders pledge to make participation in our
|
|
6
|
+
community a harassment-free experience for everyone, regardless of age, body
|
|
7
|
+
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
|
8
|
+
identity and expression, level of experience, education, socio-economic status,
|
|
9
|
+
nationality, personal appearance, race, caste, color, religion, or sexual
|
|
10
|
+
identity and orientation.
|
|
11
|
+
|
|
12
|
+
We pledge to act and interact in ways that contribute to an open, welcoming,
|
|
13
|
+
diverse, inclusive, and healthy community.
|
|
14
|
+
|
|
15
|
+
## Our Standards
|
|
16
|
+
|
|
17
|
+
Examples of behavior that contributes to a positive environment for our
|
|
18
|
+
community include:
|
|
19
|
+
|
|
20
|
+
* Demonstrating empathy and kindness toward other people
|
|
21
|
+
* Being respectful of differing opinions, viewpoints, and experiences
|
|
22
|
+
* Giving and gracefully accepting constructive feedback
|
|
23
|
+
* Accepting responsibility and apologizing to those affected by our mistakes,
|
|
24
|
+
and learning from the experience
|
|
25
|
+
* Focusing on what is best not just for us as individuals, but for the
|
|
26
|
+
overall community
|
|
27
|
+
|
|
28
|
+
Examples of unacceptable behavior include:
|
|
29
|
+
|
|
30
|
+
* The use of sexualized language or imagery, and sexual attention or
|
|
31
|
+
advances of any kind
|
|
32
|
+
* Trolling, insulting or derogatory comments, and personal or political attacks
|
|
33
|
+
* Public or private harassment
|
|
34
|
+
* Publishing others' private information, such as a physical or email
|
|
35
|
+
address, without their explicit permission
|
|
36
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
|
37
|
+
professional setting
|
|
38
|
+
|
|
39
|
+
## Enforcement Responsibilities
|
|
40
|
+
|
|
41
|
+
Community leaders are responsible for clarifying and enforcing our standards of
|
|
42
|
+
acceptable behavior and will take appropriate and fair corrective action in
|
|
43
|
+
response to any behavior that they deem inappropriate, threatening, offensive,
|
|
44
|
+
or harmful.
|
|
45
|
+
|
|
46
|
+
Community leaders have the right and responsibility to remove, edit, or reject
|
|
47
|
+
comments, commits, code, wiki edits, issues, and other contributions that are
|
|
48
|
+
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
|
49
|
+
decisions when appropriate.
|
|
50
|
+
|
|
51
|
+
## Scope
|
|
52
|
+
|
|
53
|
+
This Code of Conduct applies within all community spaces, and also applies when
|
|
54
|
+
an individual is officially representing the community in public spaces.
|
|
55
|
+
Examples of representing our community include using an official e-mail address,
|
|
56
|
+
posting via an official social media account, or acting as an appointed
|
|
57
|
+
representative at an online or offline event.
|
|
58
|
+
|
|
59
|
+
## Enforcement
|
|
60
|
+
|
|
61
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
62
|
+
reported to Victor Kneider at vkneider.dev@gmail.com or via LinkedIn
|
|
63
|
+
(https://www.linkedin.com/in/vkneider/). All complaints will be reviewed and investigated
|
|
64
|
+
promptly and fairly.
|
|
65
|
+
|
|
66
|
+
All community leaders are obligated to respect the privacy and security of the
|
|
67
|
+
reporter of any incident.
|
|
68
|
+
|
|
69
|
+
## Enforcement Guidelines
|
|
70
|
+
|
|
71
|
+
Community leaders will follow these Community Impact Guidelines in determining
|
|
72
|
+
the consequences for any action they deem in violation of this Code of Conduct:
|
|
73
|
+
|
|
74
|
+
### 1. Correction
|
|
75
|
+
|
|
76
|
+
**Community Impact**: Use of inappropriate language or other behavior deemed
|
|
77
|
+
unprofessional or unwelcome in the community.
|
|
78
|
+
|
|
79
|
+
**Consequence**: A private, written warning from community leaders, providing
|
|
80
|
+
clarity around the nature of the violation and an explanation of why the
|
|
81
|
+
behavior was inappropriate. A public apology may be requested.
|
|
82
|
+
|
|
83
|
+
### 2. Warning
|
|
84
|
+
|
|
85
|
+
**Community Impact**: A violation through a single incident or series of
|
|
86
|
+
actions.
|
|
87
|
+
|
|
88
|
+
**Consequence**: A warning with consequences for continued behavior. No
|
|
89
|
+
interaction with the people involved, including unsolicited interaction with
|
|
90
|
+
those enforcing the Code of Conduct, for a specified period of time. This
|
|
91
|
+
includes avoiding interactions in community spaces as well as external channels
|
|
92
|
+
like social media. Violating these terms may lead to a temporary or permanent
|
|
93
|
+
ban.
|
|
94
|
+
|
|
95
|
+
### 3. Temporary Ban
|
|
96
|
+
|
|
97
|
+
**Community Impact**: A serious violation of community standards, including
|
|
98
|
+
sustained inappropriate behavior.
|
|
99
|
+
|
|
100
|
+
**Consequence**: A temporary ban from any sort of interaction or public
|
|
101
|
+
communication with the community for a specified period of time. No public or
|
|
102
|
+
private interaction with the people involved, including unsolicited interaction
|
|
103
|
+
with those enforcing the Code of Conduct, is allowed during this period.
|
|
104
|
+
Violating these terms may lead to a permanent ban.
|
|
105
|
+
|
|
106
|
+
### 4. Permanent Ban
|
|
107
|
+
|
|
108
|
+
**Community Impact**: Demonstrating a pattern of violation of community
|
|
109
|
+
standards, including sustained inappropriate behavior, harassment of an
|
|
110
|
+
individual, or aggression toward or disparagement of classes of individuals.
|
|
111
|
+
|
|
112
|
+
**Consequence**: A permanent ban from any sort of public interaction within
|
|
113
|
+
the community.
|
|
114
|
+
|
|
115
|
+
## Attribution
|
|
116
|
+
|
|
117
|
+
This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org),
|
|
118
|
+
version 2.1, available at
|
|
119
|
+
https://www.contributor-covenant.org/version/2/1/code_of_conduct.html.
|
|
120
|
+
|
|
121
|
+
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
|
122
|
+
enforcement ladder](https://github.com/mozilla/diversity).
|
|
123
|
+
|
|
124
|
+
For answers to common questions about this code of conduct, see the FAQ at
|
|
125
|
+
https://www.contributor-covenant.org/faq. Translations are available at
|
|
126
|
+
https://www.contributor-covenant.org/translations.
|
package/ECOSYSTEM.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Slice.js Ecosystem
|
|
2
|
+
|
|
3
|
+
| Repository | Description | URL |
|
|
4
|
+
|---|---|---|
|
|
5
|
+
| slice.js | Core web framework | https://github.com/VKneider/slice.js |
|
|
6
|
+
| slice-cli | CLI tool for project management | https://github.com/VKneider/slicejs-cli |
|
|
7
|
+
| slice.js_visual_library | Official visual components and docs | https://github.com/VKneider/slice.js_visual_library |
|
|
8
|
+
| sliceDocs | Framework documentation site | https://github.com/VKneider/slicejs_docs |
|
|
9
|
+
| PortfolioVK2 | Portfolio and demo app | https://github.com/VKneider/portfolio |
|
package/LICENSE
ADDED
|
@@ -0,0 +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.
|
package/README.md
CHANGED
|
@@ -1,375 +1,171 @@
|
|
|
1
|
-
<div align="center">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
<
|
|
5
|
-
<
|
|
6
|
-
|
|
7
|
-
<
|
|
8
|
-
<a href="https://www.npmjs.com/package/slicejs-cli"><img src="https://img.shields.io/npm/v/slicejs-cli.svg?label=CLI" alt="npm version" /></a>
|
|
9
|
-
<img src="https://img.shields.io/badge/Node-%E2%89%A5%2020.0.0-339933?logo=node.js" alt="node requirement" />
|
|
10
|
-
<a href="#license"><img src="https://img.shields.io/badge/License-ISC-blue.svg" alt="license" /></a>
|
|
11
|
-
</
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
##
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
```bash
|
|
62
|
-
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
##
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
slice
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
#
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
#
|
|
143
|
-
slice
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
```bash
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
slice
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
Shortcuts:
|
|
174
|
-
```bash
|
|
175
|
-
slice get Button
|
|
176
|
-
slice browse
|
|
177
|
-
slice sync
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
### Utilities
|
|
181
|
-
|
|
182
|
-
```bash
|
|
183
|
-
# Version info
|
|
184
|
-
slice version
|
|
185
|
-
slice v
|
|
186
|
-
|
|
187
|
-
# Updates (CLI and Framework)
|
|
188
|
-
slice update # Check and prompt to update
|
|
189
|
-
slice update --yes # Update everything automatically
|
|
190
|
-
slice update --cli # CLI only
|
|
191
|
-
slice update --framework # Framework only
|
|
192
|
-
|
|
193
|
-
# Help
|
|
194
|
-
slice --help
|
|
195
|
-
slice [command] --help
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
## npm Scripts
|
|
199
|
-
|
|
200
|
-
`slice init` automatically configures the recommended scripts in your `package.json`:
|
|
201
|
-
|
|
202
|
-
```json
|
|
203
|
-
{
|
|
204
|
-
"scripts": {
|
|
205
|
-
"dev": "slice dev",
|
|
206
|
-
"start": "slice start",
|
|
207
|
-
"get": "slice get",
|
|
208
|
-
"browse": "slice browse",
|
|
209
|
-
"sync": "slice sync",
|
|
210
|
-
"component:create": "slice component create",
|
|
211
|
-
"component:list": "slice component list",
|
|
212
|
-
"component:delete": "slice component delete"
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
Usage:
|
|
218
|
-
```bash
|
|
219
|
-
npm run dev
|
|
220
|
-
npm run get
|
|
221
|
-
npm run browse
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
## Quick Start
|
|
225
|
-
|
|
226
|
-
```bash
|
|
227
|
-
# 1. Create a new project directory
|
|
228
|
-
mkdir my-slice-project
|
|
229
|
-
cd my-slice-project
|
|
230
|
-
|
|
231
|
-
# 2. Initialize npm and install Slice CLI
|
|
232
|
-
npm init -y
|
|
233
|
-
npm install slicejs-cli --save-dev
|
|
234
|
-
|
|
235
|
-
# 3. Initialize Slice.js project
|
|
236
|
-
slice init
|
|
237
|
-
|
|
238
|
-
# 4. Start development server
|
|
239
|
-
slice dev
|
|
240
|
-
|
|
241
|
-
# 5. Open browser at http://localhost:3000
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
## Common Workflows
|
|
245
|
-
|
|
246
|
-
### Starting a New Project
|
|
247
|
-
|
|
248
|
-
```bash
|
|
249
|
-
slice init
|
|
250
|
-
slice dev
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
### Production Build + Start
|
|
254
|
-
|
|
255
|
-
```bash
|
|
256
|
-
slice build
|
|
257
|
-
slice start
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
### Adding Components
|
|
261
|
-
|
|
262
|
-
```bash
|
|
263
|
-
# Browse available components
|
|
264
|
-
slice browse
|
|
265
|
-
|
|
266
|
-
# Install specific components
|
|
267
|
-
slice get Button Card Input
|
|
268
|
-
|
|
269
|
-
# Create custom component
|
|
270
|
-
slice component create
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
### Keeping Components Updated
|
|
274
|
-
|
|
275
|
-
```bash
|
|
276
|
-
# Check what needs updating
|
|
277
|
-
slice browse
|
|
278
|
-
|
|
279
|
-
# Update all components
|
|
280
|
-
slice sync
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
## Development Mode
|
|
284
|
-
|
|
285
|
-
The development server (`slice dev`) provides:
|
|
286
|
-
|
|
287
|
-
- ✅ Hot reload
|
|
288
|
-
- ✅ Serves directly from `/src`
|
|
289
|
-
- ✅ No build step
|
|
290
|
-
- ✅ Port validation
|
|
291
|
-
- ✅ Clear error messages
|
|
292
|
-
|
|
293
|
-
## Production Mode
|
|
294
|
-
|
|
295
|
-
The production workflow uses `slice build` + `slice start`:
|
|
296
|
-
|
|
297
|
-
- ✅ Builds to `/dist`
|
|
298
|
-
- ✅ Generates bundles into `/dist/bundles`
|
|
299
|
-
- ✅ Generates a dedicated framework bundle for Structural components (`slice-bundle.framework.js`)
|
|
300
|
-
- ✅ Minifies + obfuscates by default
|
|
301
|
-
- ✅ Serves production assets only
|
|
302
|
-
|
|
303
|
-
## Requirements
|
|
304
|
-
|
|
305
|
-
- Node.js >= 20.0.0
|
|
306
|
-
- npm or yarn
|
|
307
|
-
|
|
308
|
-
## Configuration
|
|
309
|
-
|
|
310
|
-
Project configuration is stored in `src/sliceConfig.json` and is created automatically by `slice init`.
|
|
311
|
-
|
|
312
|
-
In production, `publicFolders` defines **public asset folders** served by the server (defaults to
|
|
313
|
-
`/Themes`, `/Styles`, `/assets`). This keeps source-only folders private while exposing the assets
|
|
314
|
-
your app needs.
|
|
315
|
-
|
|
316
|
-
## Features
|
|
317
|
-
|
|
318
|
-
- 🚀 Development server with hot reload
|
|
319
|
-
- 📦 Official component registry
|
|
320
|
-
- 🎨 Visual and Service component types
|
|
321
|
-
- ✨ Interactive component creation
|
|
322
|
-
- 🔄 Automatic component synchronization
|
|
323
|
-
- 🛠️ Built-in validation and error handling
|
|
324
|
-
|
|
325
|
-
### Smart Updates
|
|
326
|
-
|
|
327
|
-
- Detects whether the CLI in use is global or local
|
|
328
|
-
- Shows an update plan (GLOBAL/PROJECT) before execution
|
|
329
|
-
- Offers to include global CLI update interactively
|
|
330
|
-
- Applies `uninstall` + `install @latest` to ensure latest versions
|
|
331
|
-
|
|
332
|
-
### Cross-platform Paths
|
|
333
|
-
|
|
334
|
-
- Centralized path helper avoids `../../..`
|
|
335
|
-
- Windows/Linux/Mac compatibility using `import.meta.url` and `fileURLToPath`
|
|
336
|
-
|
|
337
|
-
## Troubleshooting
|
|
338
|
-
|
|
339
|
-
### Port already in use
|
|
340
|
-
|
|
341
|
-
```bash
|
|
342
|
-
# Use a different port
|
|
343
|
-
slice dev -p 8080
|
|
344
|
-
```
|
|
345
|
-
|
|
346
|
-
### Project not initialized
|
|
347
|
-
|
|
348
|
-
```bash
|
|
349
|
-
# Make sure to run init first
|
|
350
|
-
slice init
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
### Command not found
|
|
354
|
-
|
|
355
|
-
```bash
|
|
356
|
-
# If the launcher command is unavailable, run the local CLI via npx
|
|
357
|
-
npx slicejs-cli dev
|
|
358
|
-
|
|
359
|
-
# Optional: install globally to expose the slice launcher command
|
|
360
|
-
npm install -g slicejs-cli
|
|
361
|
-
```
|
|
362
|
-
|
|
363
|
-
## Links
|
|
364
|
-
|
|
365
|
-
- 📘 CLI Documentation: https://slice-js-docs.vercel.app/Documentation/CLI
|
|
366
|
-
- 🐙 GitHub: https://github.com/VKneider/slice-cli
|
|
367
|
-
- 📦 npm: https://www.npmjs.com/package/slicejs-cli
|
|
368
|
-
|
|
369
|
-
## License
|
|
370
|
-
|
|
371
|
-
ISC
|
|
372
|
-
|
|
373
|
-
## Author
|
|
374
|
-
|
|
375
|
-
vkneider
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="./assets/Slice.js-logo.png" alt="Slice.js logo" width="150" />
|
|
3
|
+
<h1>Slice.js CLI</h1>
|
|
4
|
+
<p>Command-line client for building web applications with the Slice.js framework</p>
|
|
5
|
+
<p>
|
|
6
|
+
<a href="https://slice-js-docs.vercel.app/Documentation/CLI"><strong>Explore the docs »</strong></a>
|
|
7
|
+
<br />
|
|
8
|
+
<a href="https://www.npmjs.com/package/slicejs-cli"><img src="https://img.shields.io/npm/v/slicejs-cli.svg?label=CLI" alt="npm version" /></a>
|
|
9
|
+
<img src="https://img.shields.io/badge/Node-%E2%89%A5%2020.0.0-339933?logo=node.js" alt="node requirement" />
|
|
10
|
+
<a href="#license"><img src="https://img.shields.io/badge/License-ISC-blue.svg" alt="license" /></a>
|
|
11
|
+
</p>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
## About this repository
|
|
15
|
+
|
|
16
|
+
This repository contains the Slice.js CLI (`slicejs-cli`), the command-line tool for developing applications with the Slice.js framework. It includes a development server, build system, component management, and more.
|
|
17
|
+
|
|
18
|
+
## Prerequisites
|
|
19
|
+
|
|
20
|
+
- Node.js >= 20
|
|
21
|
+
- npm or pnpm
|
|
22
|
+
|
|
23
|
+
## Local development
|
|
24
|
+
|
|
25
|
+
1. **Clone the repository**
|
|
26
|
+
```bash
|
|
27
|
+
git clone https://github.com/VKneider/slicejs-cli.git
|
|
28
|
+
cd slicejs-cli
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
2. **Install dependencies**
|
|
32
|
+
```bash
|
|
33
|
+
npm install
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
3. **Test changes locally**
|
|
37
|
+
```bash
|
|
38
|
+
node client.js --help
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
To bypass delegation to a global installation:
|
|
42
|
+
```bash
|
|
43
|
+
SLICE_NO_LOCAL_DELEGATION=1 node client.js --help
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
4. **Run tests**
|
|
47
|
+
```bash
|
|
48
|
+
npm test
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Installation (for users)
|
|
52
|
+
|
|
53
|
+
### Local (Recommended)
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
npm install slicejs-cli --save-dev
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Global (Not recommended)
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npm install -g slicejs-cli
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Main commands
|
|
66
|
+
|
|
67
|
+
| Command | Description |
|
|
68
|
+
|---------|-------------|
|
|
69
|
+
| `slice init` | Initialize a Slice.js project |
|
|
70
|
+
| `slice dev` | Development server with hot reload |
|
|
71
|
+
| `slice build` | Build for production |
|
|
72
|
+
| `slice start` | Serve production build |
|
|
73
|
+
| `slice get <component>` | Install components from the official registry |
|
|
74
|
+
| `slice browse` | Browse available components |
|
|
75
|
+
| `slice component create` | Create a local component |
|
|
76
|
+
| `slice doctor` | Run project diagnostics |
|
|
77
|
+
| `slice postinstall` | Configure npm scripts (alternative to postinstall) |
|
|
78
|
+
|
|
79
|
+
## Postinstall Scripts
|
|
80
|
+
|
|
81
|
+
When you install `slicejs-cli`, the `postinstall` script automatically configures `slice:*` npm scripts in your `package.json`:
|
|
82
|
+
|
|
83
|
+
```json
|
|
84
|
+
{
|
|
85
|
+
"scripts": {
|
|
86
|
+
"slice:dev": "slice dev",
|
|
87
|
+
"slice:start": "slice start",
|
|
88
|
+
"slice:create": "slice component create",
|
|
89
|
+
"slice:list": "slice component list",
|
|
90
|
+
"slice:delete": "slice component delete",
|
|
91
|
+
"slice:init": "slice init",
|
|
92
|
+
"slice:get": "slice get",
|
|
93
|
+
"slice:browse": "slice browse",
|
|
94
|
+
"slice:sync": "slice sync",
|
|
95
|
+
"slice:version": "slice version",
|
|
96
|
+
"slice:update": "slice update"
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
If you installed with `--ignore-scripts`, run manually:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
npx slicejs-cli postinstall
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Quick start
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
# 1. Create project
|
|
111
|
+
mkdir my-project && cd my-project
|
|
112
|
+
npm init -y
|
|
113
|
+
|
|
114
|
+
# 2. Install CLI
|
|
115
|
+
npm install slicejs-cli --save-dev
|
|
116
|
+
|
|
117
|
+
# 3. Initialize
|
|
118
|
+
npx slicejs-cli init
|
|
119
|
+
|
|
120
|
+
# 4. Development
|
|
121
|
+
npx slicejs-cli dev
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Tests
|
|
125
|
+
|
|
126
|
+
The CLI uses Node.js native test runner:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
# All tests
|
|
130
|
+
node --test
|
|
131
|
+
|
|
132
|
+
# Specific tests
|
|
133
|
+
node --test tests/postinstall-command.test.js
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Project structure
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
slicejs-cli/
|
|
140
|
+
├── client.js # CLI entry point
|
|
141
|
+
├── commands/ # Command implementations
|
|
142
|
+
│ ├── init/ # slice init
|
|
143
|
+
│ ├── build/ # slice build
|
|
144
|
+
│ ├── startServer/ # slice dev / slice start
|
|
145
|
+
│ ├── createComponent/ # slice component create
|
|
146
|
+
│ └── utils/ # PathHelper, VersionChecker, etc.
|
|
147
|
+
├── tests/ # Tests
|
|
148
|
+
└── post.js # Postinstall hook
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Local delegation
|
|
152
|
+
|
|
153
|
+
When the `slice` command is globally available, it automatically delegates to the project-local CLI (`node_modules/slicejs-cli`). To disable:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
SLICE_NO_LOCAL_DELEGATION=1 slice version
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Contributing
|
|
160
|
+
|
|
161
|
+
We welcome contributions. Please review the guidelines in [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) before submitting changes.
|
|
162
|
+
|
|
163
|
+
## License
|
|
164
|
+
|
|
165
|
+
Distributed under the ISC License. See `LICENSE` for more information.
|
|
166
|
+
|
|
167
|
+
## Links
|
|
168
|
+
|
|
169
|
+
- 📘 Documentation: https://slice-js-docs.vercel.app/Documentation/CLI
|
|
170
|
+
- 🐙 GitHub: https://github.com/VKneider/slicejs-cli
|
|
171
|
+
- 📦 npm: https://www.npmjs.com/package/slicejs-cli
|
package/client.js
CHANGED
|
@@ -528,6 +528,68 @@ sliceClient
|
|
|
528
528
|
});
|
|
529
529
|
});
|
|
530
530
|
|
|
531
|
+
// POSTINSTALL COMMAND - Manual alternative to postinstall
|
|
532
|
+
sliceClient
|
|
533
|
+
.command("postinstall")
|
|
534
|
+
.description("Configure npm scripts in package.json (alternative to postinstall for --ignore-scripts users)")
|
|
535
|
+
.action(() => {
|
|
536
|
+
const isGlobal = process.env.npm_config_global === 'true';
|
|
537
|
+
if (isGlobal) {
|
|
538
|
+
console.log('⚠️ Global installation of slicejs-cli detected.');
|
|
539
|
+
console.log(' We strongly recommend using a local installation to avoid version mismatches.');
|
|
540
|
+
console.log(' Uninstall global: npm uninstall -g slicejs-cli');
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
const projectRoot = getProjectRoot(import.meta.url);
|
|
545
|
+
const pkgPath = path.join(projectRoot, 'package.json');
|
|
546
|
+
|
|
547
|
+
const sliceScripts = {
|
|
548
|
+
'slice:dev': 'slice dev',
|
|
549
|
+
'slice:start': 'slice start',
|
|
550
|
+
'slice:create': 'slice component create',
|
|
551
|
+
'slice:list': 'slice component list',
|
|
552
|
+
'slice:delete': 'slice component delete',
|
|
553
|
+
'slice:init': 'slice init',
|
|
554
|
+
'slice:get': 'slice get',
|
|
555
|
+
'slice:browse': 'slice browse',
|
|
556
|
+
'slice:sync': 'slice sync',
|
|
557
|
+
'slice:version': 'slice version',
|
|
558
|
+
'slice:update': 'slice update',
|
|
559
|
+
};
|
|
560
|
+
|
|
561
|
+
try {
|
|
562
|
+
let pkg = {};
|
|
563
|
+
if (fs.existsSync(pkgPath)) {
|
|
564
|
+
pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
565
|
+
} else {
|
|
566
|
+
pkg = {
|
|
567
|
+
name: path.basename(projectRoot),
|
|
568
|
+
version: '1.0.0',
|
|
569
|
+
description: 'Slice.js project',
|
|
570
|
+
scripts: {}
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
pkg.scripts = pkg.scripts || {};
|
|
575
|
+
let addedCount = 0;
|
|
576
|
+
for (const [script, command] of Object.entries(sliceScripts)) {
|
|
577
|
+
if (!pkg.scripts[script]) {
|
|
578
|
+
pkg.scripts[script] = command;
|
|
579
|
+
addedCount++;
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2), 'utf-8');
|
|
584
|
+
console.log(`✅ slicejs-cli installed successfully. Added ${addedCount} npm scripts to package.json.`);
|
|
585
|
+
console.log(' Run: npm run slice:dev');
|
|
586
|
+
} catch (err) {
|
|
587
|
+
console.log('✅ slicejs-cli installed successfully.');
|
|
588
|
+
console.log(' Could not auto-configure scripts:', err.message);
|
|
589
|
+
console.log(' Run: npx slice dev');
|
|
590
|
+
}
|
|
591
|
+
});
|
|
592
|
+
|
|
531
593
|
// Enhanced help
|
|
532
594
|
sliceClient
|
|
533
595
|
.option("--no-version-check", "Skip version check for this command")
|
|
@@ -550,8 +612,9 @@ Common Usage Examples:
|
|
|
550
612
|
slice sync - Update local components to latest versions
|
|
551
613
|
slice component create - Create new local component
|
|
552
614
|
slice list - List all local components
|
|
553
|
-
slice doctor - Run project diagnostics
|
|
554
|
-
slice types generate - Generate TypeScript typings for slice.build
|
|
615
|
+
slice doctor - Run project diagnostics
|
|
616
|
+
slice types generate - Generate TypeScript typings for slice.build
|
|
617
|
+
slice postinstall - Show post-install setup guide
|
|
555
618
|
|
|
556
619
|
Command Categories:
|
|
557
620
|
• init, dev, start - Project lifecycle (development only)
|
|
@@ -559,7 +622,7 @@ Command Categories:
|
|
|
559
622
|
• component <cmd> - Local component management
|
|
560
623
|
• registry <cmd> - Official repository operations
|
|
561
624
|
• types generate - Type declarations from static props
|
|
562
|
-
• version, update, doctor
|
|
625
|
+
• version, update, doctor, setup - Maintenance commands
|
|
563
626
|
|
|
564
627
|
Development Workflow:
|
|
565
628
|
• slice init - Initialize project
|
package/package.json
CHANGED
package/post.js
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
|
-
import { fileURLToPath } from 'url';
|
|
3
2
|
import path from 'path';
|
|
4
|
-
import
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import { getProjectRoot } from './commands/utils/PathHelper.js';
|
|
5
5
|
|
|
6
6
|
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
-
const __dirname = path.dirname(__filename);
|
|
8
7
|
|
|
9
8
|
const isGlobal = process.env.npm_config_global === 'true';
|
|
10
|
-
const initCwd = process.env.INIT_CWD ? path.resolve(process.env.INIT_CWD) : null;
|
|
11
|
-
const targetRoot = initCwd || path.resolve(__dirname, '../../');
|
|
12
|
-
const projectPackageJsonPath = path.join(targetRoot, 'package.json');
|
|
13
9
|
|
|
14
10
|
if (isGlobal) {
|
|
15
11
|
console.log('⚠️ Global installation of slicejs-cli detected.');
|
|
@@ -18,8 +14,52 @@ if (isGlobal) {
|
|
|
18
14
|
process.exit(0);
|
|
19
15
|
}
|
|
20
16
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
17
|
+
const projectRoot = getProjectRoot(import.meta.url);
|
|
18
|
+
const pkgPath = path.join(projectRoot, 'package.json');
|
|
19
|
+
|
|
20
|
+
const sliceScripts = {
|
|
21
|
+
'slice:dev': 'slice dev',
|
|
22
|
+
'slice:start': 'slice start',
|
|
23
|
+
'slice:create': 'slice component create',
|
|
24
|
+
'slice:list': 'slice component list',
|
|
25
|
+
'slice:delete': 'slice component delete',
|
|
26
|
+
'slice:init': 'slice init',
|
|
27
|
+
'slice:get': 'slice get',
|
|
28
|
+
'slice:browse': 'slice browse',
|
|
29
|
+
'slice:sync': 'slice sync',
|
|
30
|
+
'slice:version': 'slice version',
|
|
31
|
+
'slice:update': 'slice update',
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
let pkg = {};
|
|
36
|
+
if (fs.existsSync(pkgPath)) {
|
|
37
|
+
pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
38
|
+
} else {
|
|
39
|
+
pkg = {
|
|
40
|
+
name: path.basename(projectRoot),
|
|
41
|
+
version: '1.0.0',
|
|
42
|
+
description: 'Slice.js project',
|
|
43
|
+
scripts: {}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
pkg.scripts = pkg.scripts || {};
|
|
48
|
+
let addedCount = 0;
|
|
49
|
+
for (const [script, command] of Object.entries(sliceScripts)) {
|
|
50
|
+
if (!pkg.scripts[script]) {
|
|
51
|
+
pkg.scripts[script] = command;
|
|
52
|
+
addedCount++;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2), 'utf-8');
|
|
57
|
+
console.log(`✅ slicejs-cli installed successfully. Added ${addedCount} npm scripts to package.json.`);
|
|
58
|
+
console.log(' Run: npm run slice:dev');
|
|
59
|
+
} catch (err) {
|
|
60
|
+
console.log('✅ slicejs-cli installed successfully.');
|
|
61
|
+
console.log(' Could not auto-configure scripts:', err.message);
|
|
62
|
+
console.log(' Run: npx slice dev');
|
|
63
|
+
}
|
|
64
|
+
|
|
25
65
|
process.exit(0);
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { test, describe } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
|
|
7
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
const clientPath = path.join(__dirname, '..', 'client.js');
|
|
9
|
+
const source = fs.readFileSync(clientPath, 'utf-8');
|
|
10
|
+
|
|
11
|
+
test('postinstall command is registered in client.js', () => {
|
|
12
|
+
const hasSetupCommand = source.includes('.command("postinstall")');
|
|
13
|
+
assert.ok(hasSetupCommand, 'client.js must register a "postinstall" command');
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test('postinstall command has a description', () => {
|
|
17
|
+
const match = source.match(/\.command\(["']postinstall["']\)\s*\.description\(["']([^"']+)["']\)/);
|
|
18
|
+
assert.ok(match, 'postinstall command must have a .description() call');
|
|
19
|
+
assert.ok(match[1].length > 0, 'postinstall command description must not be empty');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test('postinstall command checks npm_config_global environment variable', () => {
|
|
23
|
+
const hasGlobalCheck = source.includes('npm_config_global');
|
|
24
|
+
assert.ok(hasGlobalCheck, 'postinstall command must check npm_config_global to detect global installation');
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test('postinstall command prints global install warning', () => {
|
|
28
|
+
const hasGlobalWarning = source.includes('Global installation');
|
|
29
|
+
assert.ok(hasGlobalWarning, 'postinstall command must warn about global installation');
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test('postinstall command prints local install success message', () => {
|
|
33
|
+
const hasSuccessMsg = source.includes('installed successfully');
|
|
34
|
+
assert.ok(hasSuccessMsg, 'postinstall command must show success message for local installs');
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test('postinstall command uses getProjectRoot from PathHelper', () => {
|
|
38
|
+
const hasPathHelper = source.includes("getProjectRoot(import.meta.url)");
|
|
39
|
+
assert.ok(hasPathHelper, 'postinstall command must use getProjectRoot resolver');
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test('postinstall command writes npm scripts to package.json via fs', () => {
|
|
43
|
+
const hasFsWrite = source.includes('writeFileSync(pkgPath');
|
|
44
|
+
assert.ok(hasFsWrite, 'postinstall command must write scripts to package.json');
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test('postinstall command writes slice:dev script to package.json', () => {
|
|
48
|
+
const hasDevScript = source.includes("'slice:dev': 'slice dev'");
|
|
49
|
+
assert.ok(hasDevScript, 'postinstall command must add "slice:dev" script to package.json');
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test('postinstall command writes all slice:* scripts to package.json', () => {
|
|
53
|
+
const scripts = [
|
|
54
|
+
'slice:dev', 'slice:start', 'slice:create', 'slice:list',
|
|
55
|
+
'slice:delete', 'slice:init', 'slice:get', 'slice:browse',
|
|
56
|
+
'slice:sync', 'slice:version', 'slice:update'
|
|
57
|
+
];
|
|
58
|
+
for (const script of scripts) {
|
|
59
|
+
assert.ok(source.includes(script), `postinstall command must configure ${script} script`);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test('postinstall command action is a function', () => {
|
|
64
|
+
const SetupActionPattern = /\.command\(["']postinstall["']\)[\s\S]*?\.action\(\(\)\s*=>\s*\{[\s\S]*?\}\)/;
|
|
65
|
+
const match = source.match(SetupActionPattern);
|
|
66
|
+
assert.ok(match, 'postinstall command must have an .action() with arrow function');
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
test('postinstall command provides npm uninstall -g instruction for global installs', () => {
|
|
70
|
+
const hasUninstallInstruction = source.includes('npm uninstall -g slicejs-cli');
|
|
71
|
+
assert.ok(hasUninstallInstruction, 'postinstall command must tell users how to uninstall global CLI');
|
|
72
|
+
});
|
package/refactor.md
DELETED
|
@@ -1,271 +0,0 @@
|
|
|
1
|
-
# Plan de Refactorización del CLI para MCP
|
|
2
|
-
|
|
3
|
-
## Objetivo
|
|
4
|
-
Separar la lógica de negocio de la presentación CLI para permitir importación directa desde el MCP server, manteniendo **100% de compatibilidad** con el CLI actual.
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## Estructura Propuesta
|
|
9
|
-
|
|
10
|
-
```
|
|
11
|
-
commands/
|
|
12
|
-
├── createComponent/
|
|
13
|
-
│ ├── createComponent.js # CLI wrapper (presentación)
|
|
14
|
-
│ ├── core.js # ⭐ NUEVO - Lógica pura exportable
|
|
15
|
-
│ └── VisualComponentTemplate.js
|
|
16
|
-
│
|
|
17
|
-
├── listComponents/
|
|
18
|
-
│ ├── listComponents.js # CLI wrapper (presentación)
|
|
19
|
-
│ └── core.js # ⭐ NUEVO - Lógica pura exportable
|
|
20
|
-
│
|
|
21
|
-
├── deleteComponent/
|
|
22
|
-
│ ├── deleteComponent.js # CLI wrapper (presentación)
|
|
23
|
-
│ └── core.js # ⭐ NUEVO - Lógica pura exportable
|
|
24
|
-
│
|
|
25
|
-
├── getComponent/
|
|
26
|
-
│ ├── getComponent.js # CLI wrapper (presentación)
|
|
27
|
-
│ └── core.js # ⭐ NUEVO - Lógica pura exportable
|
|
28
|
-
│
|
|
29
|
-
└── init/
|
|
30
|
-
├── init.js # CLI wrapper (presentación)
|
|
31
|
-
└── core.js # ⭐ NUEVO - Lógica pura exportable
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
## Principios de Refactorización
|
|
37
|
-
|
|
38
|
-
### 1. Separación de Responsabilidades
|
|
39
|
-
- **core.js**: Lógica pura sin dependencias de CLI (Print, chalk, Table, inquirer)
|
|
40
|
-
- **[comando].js**: Solo presentación CLI, usa funciones del core
|
|
41
|
-
|
|
42
|
-
### 2. Funciones Puras en Core
|
|
43
|
-
- Reciben parámetros explícitos (no usan import.meta.url implícitamente)
|
|
44
|
-
- Retornan objetos con estructura `{ success: boolean, data?, error? }`
|
|
45
|
-
- No imprimen a consola directamente
|
|
46
|
-
- Son agnósticas del entorno (CLI vs MCP)
|
|
47
|
-
|
|
48
|
-
### 3. Compatibilidad Total
|
|
49
|
-
- Los archivos CLI actuales se mantienen funcionales
|
|
50
|
-
- Misma API de comandos
|
|
51
|
-
- Mismo comportamiento observable
|
|
52
|
-
- No romper ningún test existente
|
|
53
|
-
|
|
54
|
-
---
|
|
55
|
-
|
|
56
|
-
## Pasos de Refactorización por Comando
|
|
57
|
-
|
|
58
|
-
### Fase 1: List Components
|
|
59
|
-
|
|
60
|
-
#### Paso 1.1: Análisis del Código Actual
|
|
61
|
-
- Identificar toda la lógica de negocio en `listComponents.js`
|
|
62
|
-
- Separar mentalmente: lógica vs presentación
|
|
63
|
-
- Funciones a extraer: `loadConfig`, `getComponents`, `countComponentFiles`, `listComponentDirectories`
|
|
64
|
-
|
|
65
|
-
#### Paso 1.2: Crear core.js
|
|
66
|
-
- Crear archivo `commands/listComponents/core.js`
|
|
67
|
-
- Extraer funciones de lógica pura
|
|
68
|
-
- Modificar para que acepten `projectPath` como parámetro opcional
|
|
69
|
-
- Retornar objetos estructurados en lugar de imprimir
|
|
70
|
-
|
|
71
|
-
#### Paso 1.3: Adaptar listComponents.js
|
|
72
|
-
- Importar funciones desde `core.js`
|
|
73
|
-
- Mantener solo la lógica de presentación (Print, Table, chalk)
|
|
74
|
-
- Re-exportar funciones del core: `export { getComponents, ... } from './core.js'`
|
|
75
|
-
|
|
76
|
-
#### Paso 1.4: Verificación
|
|
77
|
-
- Ejecutar `slice list` - debe funcionar idéntico
|
|
78
|
-
- Probar importación directa: `import { getComponents } from './commands/listComponents/core.js'`
|
|
79
|
-
- Verificar que retorna datos correctos sin CLI
|
|
80
|
-
|
|
81
|
-
---
|
|
82
|
-
|
|
83
|
-
### Fase 2: Create Component
|
|
84
|
-
|
|
85
|
-
#### Paso 2.1: Análisis
|
|
86
|
-
- Identificar lógica: validaciones, generación de templates, creación de archivos
|
|
87
|
-
- Identificar presentación: mensajes de error, comandos de ejemplo
|
|
88
|
-
|
|
89
|
-
#### Paso 2.2: Crear core.js
|
|
90
|
-
- Crear `commands/createComponent/core.js`
|
|
91
|
-
- Extraer: `validateComponentName`, `validateCategory`, `generateTemplate`, `createComponentFiles`
|
|
92
|
-
- Cada función retorna `{ success, data, error }`
|
|
93
|
-
|
|
94
|
-
#### Paso 2.3: Adaptar createComponent.js
|
|
95
|
-
- Importar funciones del core
|
|
96
|
-
- Mantener solo los Print y mensajes de ayuda
|
|
97
|
-
- Re-exportar funciones del core
|
|
98
|
-
|
|
99
|
-
#### Paso 2.4: Verificación
|
|
100
|
-
- Ejecutar `slice component create` - debe funcionar igual
|
|
101
|
-
- Probar importación directa y creación programática
|
|
102
|
-
|
|
103
|
-
---
|
|
104
|
-
|
|
105
|
-
### Fase 3: Delete Component
|
|
106
|
-
|
|
107
|
-
#### Paso 3.1: Análisis
|
|
108
|
-
- Identificar lógica: validaciones, verificación de existencia, eliminación de archivos
|
|
109
|
-
- Identificar presentación: mensajes de confirmación, errores
|
|
110
|
-
|
|
111
|
-
#### Paso 3.2: Crear core.js
|
|
112
|
-
- Crear `commands/deleteComponent/core.js`
|
|
113
|
-
- Extraer: `deleteComponentFiles` (con validaciones integradas)
|
|
114
|
-
|
|
115
|
-
#### Paso 3.3: Adaptar deleteComponent.js
|
|
116
|
-
- Importar del core
|
|
117
|
-
- Mantener presentación CLI
|
|
118
|
-
- Re-exportar funciones
|
|
119
|
-
|
|
120
|
-
#### Paso 3.4: Verificación
|
|
121
|
-
- Ejecutar `slice component delete`
|
|
122
|
-
- Verificar funcionamiento idéntico
|
|
123
|
-
|
|
124
|
-
---
|
|
125
|
-
|
|
126
|
-
### Fase 4: Get Component (Registry)
|
|
127
|
-
|
|
128
|
-
#### Paso 4.1: Análisis
|
|
129
|
-
- Identificar lógica: descarga de registry, instalación de componentes, actualización
|
|
130
|
-
- Es el más complejo - tiene clase ComponentRegistry
|
|
131
|
-
|
|
132
|
-
#### Paso 4.2: Crear core.js
|
|
133
|
-
- Crear `commands/getComponent/core.js`
|
|
134
|
-
- Extraer clase `ComponentRegistry` limpia (sin inquirer, sin Print)
|
|
135
|
-
- Métodos retornan objetos estructurados
|
|
136
|
-
|
|
137
|
-
#### Paso 4.3: Adaptar getComponent.js
|
|
138
|
-
- Importar ComponentRegistry del core
|
|
139
|
-
- Envolver con lógica interactiva (inquirer) solo en CLI
|
|
140
|
-
- Mantener funciones: `getComponents`, `listComponents`, `syncComponents`
|
|
141
|
-
|
|
142
|
-
#### Paso 4.4: Verificación
|
|
143
|
-
- Probar: `slice get Button`, `slice browse`, `slice sync`
|
|
144
|
-
- Verificar descarga y registro correctos
|
|
145
|
-
|
|
146
|
-
---
|
|
147
|
-
|
|
148
|
-
### Fase 5: Init Project
|
|
149
|
-
|
|
150
|
-
#### Paso 5.1: Análisis
|
|
151
|
-
- Identificar lógica: copia de estructuras, configuración de package.json
|
|
152
|
-
- Separar spinners y mensajes visuales
|
|
153
|
-
|
|
154
|
-
#### Paso 5.2: Crear core.js
|
|
155
|
-
- Crear `commands/init/core.js`
|
|
156
|
-
- Extraer: funciones de scaffolding, configuración
|
|
157
|
-
|
|
158
|
-
#### Paso 5.3: Adaptar init.js
|
|
159
|
-
- Importar del core
|
|
160
|
-
- Mantener spinners y presentación
|
|
161
|
-
- Re-exportar funciones
|
|
162
|
-
|
|
163
|
-
#### Paso 5.4: Verificación
|
|
164
|
-
- Ejecutar `slice init` en proyecto nuevo
|
|
165
|
-
- Verificar estructura completa creada
|
|
166
|
-
|
|
167
|
-
---
|
|
168
|
-
|
|
169
|
-
## Patrón de Estructura de Funciones Core
|
|
170
|
-
|
|
171
|
-
### Firma de Función Estándar
|
|
172
|
-
```
|
|
173
|
-
function operationName({ param1, param2, projectPath = null }) {
|
|
174
|
-
// Validaciones
|
|
175
|
-
// Lógica de negocio
|
|
176
|
-
return { success: boolean, data?, error? }
|
|
177
|
-
}
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
### Objeto de Retorno Estándar
|
|
181
|
-
```javascript
|
|
182
|
-
// Éxito
|
|
183
|
-
{
|
|
184
|
-
success: true,
|
|
185
|
-
data: { ... },
|
|
186
|
-
// Campos adicionales específicos
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
// Error
|
|
190
|
-
{
|
|
191
|
-
success: false,
|
|
192
|
-
error: "mensaje descriptivo"
|
|
193
|
-
}
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
---
|
|
197
|
-
|
|
198
|
-
## Estrategia de Dependencias
|
|
199
|
-
|
|
200
|
-
### Dependencias Permitidas en core.js
|
|
201
|
-
- ✅ `fs`, `fs-extra`
|
|
202
|
-
- ✅ `path`
|
|
203
|
-
- ✅ `Validations.js` (lógica pura)
|
|
204
|
-
- ✅ Helpers de PathHelper (refactorizar para aceptar projectPath)
|
|
205
|
-
|
|
206
|
-
### Dependencias NO Permitidas en core.js
|
|
207
|
-
- ❌ `Print.js` (específico de CLI)
|
|
208
|
-
- ❌ `chalk` (presentación)
|
|
209
|
-
- ❌ `cli-table3` (presentación)
|
|
210
|
-
- ❌ `inquirer` (interacción CLI)
|
|
211
|
-
- ❌ `ora` (spinners CLI)
|
|
212
|
-
|
|
213
|
-
---
|
|
214
|
-
|
|
215
|
-
## Refactorización de PathHelper
|
|
216
|
-
|
|
217
|
-
### Problema Actual
|
|
218
|
-
PathHelper usa `import.meta.url` internamente, asumiendo que se llama desde dentro del CLI
|
|
219
|
-
|
|
220
|
-
### Solución
|
|
221
|
-
Crear versiones alternativas que acepten `projectPath`:
|
|
222
|
-
|
|
223
|
-
```
|
|
224
|
-
// Versión CLI (actual)
|
|
225
|
-
getSrcPath(import.meta.url, ...paths)
|
|
226
|
-
|
|
227
|
-
// Versión core (nueva)
|
|
228
|
-
getProjectSrcPath(projectPath, ...paths)
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
O mejor: modificar funciones existentes para aceptar ambos modos:
|
|
232
|
-
```
|
|
233
|
-
getSrcPath(importMetaUrlOrProjectPath, ...paths)
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
---
|
|
237
|
-
|
|
238
|
-
## Testing de la Refactorización
|
|
239
|
-
|
|
240
|
-
### Test 1: CLI Functionality
|
|
241
|
-
Para cada comando refactorizado:
|
|
242
|
-
- Ejecutar comando CLI
|
|
243
|
-
- Verificar output idéntico al anterior
|
|
244
|
-
- Verificar archivos creados/modificados
|
|
245
|
-
|
|
246
|
-
### Test 2: Importación Directa
|
|
247
|
-
```javascript
|
|
248
|
-
// test-mcp-import.js
|
|
249
|
-
import { getComponents } from './commands/listComponents/core.js';
|
|
250
|
-
|
|
251
|
-
const result = getComponents('/ruta/proyecto');
|
|
252
|
-
console.log(result); // Debe retornar objeto con componentes
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
### Test 3: Sin Dependencias CLI
|
|
256
|
-
Verificar que core.js no tiene imports de Print, chalk, etc:
|
|
257
|
-
```bash
|
|
258
|
-
grep -r "from.*Print" commands/*/core.js # debe estar vacío
|
|
259
|
-
grep -r "from.*chalk" commands/*/core.js # debe estar vacío
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
---
|
|
263
|
-
|
|
264
|
-
## Orden de Implementación Recomendado
|
|
265
|
-
|
|
266
|
-
1. **listComponents** (más simple, establece patrón)
|
|
267
|
-
2. **createComponent** (complejidad media)
|
|
268
|
-
3. **deleteComponent** (similar a create)
|
|
269
|
-
4. **getComponent** (más complejo, tiene clase)
|
|
270
|
-
5. **init** (el más complejo)
|
|
271
|
-
|