@ijuantm/simpl-addon 2.8.3 → 2.8.6
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 +48 -24
- package/install.js +21 -16
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,38 +1,63 @@
|
|
|
1
1
|
# Simpl Add-on Installer
|
|
2
2
|
|
|
3
|
-
CLI tool for installing Simpl framework add-ons
|
|
3
|
+
CLI tool for installing Simpl framework add-ons with `npx`.
|
|
4
|
+
|
|
5
|
+
## What it does
|
|
6
|
+
|
|
7
|
+
- Downloads the selected Simpl add-on for your project version
|
|
8
|
+
- Copies new files into the current project directory
|
|
9
|
+
- Merges existing files using add-on markers
|
|
10
|
+
- Keeps existing content when no merge markers are present
|
|
4
11
|
|
|
5
12
|
## Usage
|
|
6
13
|
|
|
7
|
-
|
|
14
|
+
Run the installer from the root of a Simpl project. The project must contain a `.simpl` file with a `version` field so the installer can match the add-on version to your Simpl framework version.
|
|
15
|
+
|
|
16
|
+
Run the installer with no arguments to be prompted for the add-on:
|
|
8
17
|
|
|
9
18
|
```bash
|
|
10
|
-
npx @ijuantm/simpl-addon
|
|
19
|
+
npx @ijuantm/simpl-addon
|
|
11
20
|
```
|
|
12
21
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
Navigate to your Simpl project directory and run the following command. For example, to install the "auth" add-on:
|
|
22
|
+
Or provide the add-on name up front:
|
|
16
23
|
|
|
17
24
|
```bash
|
|
18
25
|
npx @ijuantm/simpl-addon auth
|
|
19
26
|
```
|
|
20
27
|
|
|
21
|
-
|
|
28
|
+
You can also pass explicit options:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx @ijuantm/simpl-addon --addon=auth
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The first non-flag argument is treated as the add-on name. If you do not pass `--addon`, the installer will ask for it interactively.
|
|
35
|
+
|
|
36
|
+
### Available options
|
|
37
|
+
|
|
38
|
+
| Option | Description |
|
|
39
|
+
|-------------------------------|-----------------------------------------------------|
|
|
40
|
+
| `--addon=<name>`, `-a=<name>` | Add-on to install. |
|
|
41
|
+
| `--list`, `-l` | List all available add-ons for the current version. |
|
|
42
|
+
| `--help`, `-h` | Show the help message. |
|
|
43
|
+
|
|
44
|
+
### Helpful commands
|
|
22
45
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
46
|
+
List available add-ons:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npx @ijuantm/simpl-addon --list
|
|
50
|
+
```
|
|
26
51
|
|
|
27
|
-
|
|
52
|
+
Show help:
|
|
28
53
|
|
|
29
54
|
```bash
|
|
30
55
|
npx @ijuantm/simpl-addon --help
|
|
31
56
|
```
|
|
32
57
|
|
|
33
|
-
## How
|
|
58
|
+
## How it works
|
|
34
59
|
|
|
35
|
-
The installer
|
|
60
|
+
The installer reads special markers in add-on files to safely merge content. Content for a marker is read from the marker line until `@addon-end`:
|
|
36
61
|
|
|
37
62
|
```php
|
|
38
63
|
// @addon-insert:after('existing line')
|
|
@@ -40,22 +65,21 @@ new AuthController();
|
|
|
40
65
|
// @addon-end
|
|
41
66
|
```
|
|
42
67
|
|
|
43
|
-
|
|
68
|
+
Supported markers:
|
|
44
69
|
|
|
45
|
-
- `@addon-insert:after('text')` - Insert content after matching line
|
|
46
|
-
- `@addon-insert:before('text')` - Insert content before matching line
|
|
47
|
-
- `@addon-insert:replace('text')` - Replace matching line with content
|
|
70
|
+
- `@addon-insert:after('text')` - Insert content after a matching line
|
|
71
|
+
- `@addon-insert:before('text')` - Insert content before a matching line
|
|
72
|
+
- `@addon-insert:replace('text')` - Replace a matching line with content
|
|
48
73
|
- `@addon-insert:prepend` - Add content at the beginning of the file
|
|
49
74
|
- `@addon-insert:append` - Add content at the end of the file
|
|
50
75
|
|
|
51
|
-
The installer:
|
|
76
|
+
The installer also:
|
|
52
77
|
|
|
53
|
-
- Creates new files that
|
|
54
|
-
-
|
|
55
|
-
-
|
|
56
|
-
- Detects duplicate content (won't add twice)
|
|
78
|
+
- Creates new files that do not exist
|
|
79
|
+
- Skips files without markers instead of overwriting them
|
|
80
|
+
- Avoids adding the same content twice
|
|
57
81
|
|
|
58
82
|
## Requirements
|
|
59
83
|
|
|
60
|
-
- **Node.js**: >= 22
|
|
61
|
-
- **Simpl Framework**: A
|
|
84
|
+
- **Node.js**: >= 22
|
|
85
|
+
- **Simpl Framework**: A Simpl project with a valid `.simpl` file in the project root
|
package/install.js
CHANGED
|
@@ -110,7 +110,8 @@ const downloadFile = (url, dest) => new Promise((resolve, reject) => {
|
|
|
110
110
|
|
|
111
111
|
const promptUser = (question, defaultValue = '') => new Promise(resolve => {
|
|
112
112
|
const rl = readline.createInterface({input: process.stdin, output: process.stdout});
|
|
113
|
-
|
|
113
|
+
const prompt = defaultValue ? `${question} ${C.dim}(${defaultValue})${C.reset}: ` : `${question}: `;
|
|
114
|
+
rl.question(prompt, answer => {
|
|
114
115
|
rl.close();
|
|
115
116
|
resolve(answer.trim() || defaultValue);
|
|
116
117
|
});
|
|
@@ -155,7 +156,7 @@ const listAddons = (addons) => addons.forEach((name, i) => out(PAD + C.cyan + `$
|
|
|
155
156
|
const confirmSuggestion = async (suggestion) => {
|
|
156
157
|
line();
|
|
157
158
|
while (true) {
|
|
158
|
-
const a = (await promptUser(PAD + `${C.cyan}◌${C.reset} ${C.dim}Did you mean${C.reset} ${C.cyan}${suggestion}${C.reset}${C.dim}?${C.reset}
|
|
159
|
+
const a = (await promptUser(PAD + `${C.cyan}◌${C.reset} ${C.dim}Did you mean${C.reset} ${C.cyan}${suggestion}${C.reset}${C.dim}?${C.reset}`, 'n')).toLowerCase();
|
|
159
160
|
if (['y', 'yes'].includes(a)) return true;
|
|
160
161
|
if (['n', 'no'].includes(a)) return false;
|
|
161
162
|
warn('Please answer [Y] Yes or [N] No)');
|
|
@@ -194,18 +195,19 @@ const promptAddon = async (addons, firstInput = null) => {
|
|
|
194
195
|
};
|
|
195
196
|
|
|
196
197
|
const showHelp = () => {
|
|
197
|
-
box(
|
|
198
|
-
line();
|
|
199
|
-
out(PAD + styled('Usage:', C.bold), C.blue);
|
|
200
|
-
out(PAD + styled('npx @ijuantm/simpl-addon', C.dim));
|
|
201
|
-
out(PAD + styled('npx @ijuantm/simpl-addon --addon=<name>', C.dim));
|
|
202
|
-
out(PAD + styled('npx @ijuantm/simpl-addon --help', C.dim));
|
|
198
|
+
box(`Simpl Add-on Installer ${C.dim}-${C.reset} ${C.blue}Help${C.reset}`);
|
|
203
199
|
line();
|
|
204
200
|
out(PAD + styled('Options:', C.bold), C.blue);
|
|
205
201
|
out(PAD + styled('--addon=<name>, -a=<name>', C.dim) + ' Add-on to install');
|
|
206
202
|
out(PAD + styled('--list, -l', C.dim) + ' List available add-ons');
|
|
207
203
|
out(PAD + styled('--help, -h', C.dim) + ' Show this help message');
|
|
208
204
|
line();
|
|
205
|
+
out(PAD + styled('Usage:', C.bold), C.blue);
|
|
206
|
+
out(PAD + styled('npx @ijuantm/simpl-addon', C.dim));
|
|
207
|
+
out(PAD + styled('npx @ijuantm/simpl-addon --addon=<name>', C.dim));
|
|
208
|
+
out(PAD + styled('npx @ijuantm/simpl-addon --list', C.dim));
|
|
209
|
+
out(PAD + styled('npx @ijuantm/simpl-addon -h', C.dim));
|
|
210
|
+
line();
|
|
209
211
|
out(PAD + styled('Note:', C.bold), C.blue);
|
|
210
212
|
item('Run this command from the root of your Simpl project.');
|
|
211
213
|
item('The add-on version will match your Simpl framework version.');
|
|
@@ -477,6 +479,15 @@ const main = async () => {
|
|
|
477
479
|
process.exit(0);
|
|
478
480
|
}
|
|
479
481
|
|
|
482
|
+
if (parsed.list) {
|
|
483
|
+
box(`Simpl Add-on Installer ${C.dim}-${C.reset} ${C.blue}Available Add-ons${C.reset}`);
|
|
484
|
+
line();
|
|
485
|
+
out(PAD + styled('Available add-ons:', C.bold), C.blue);
|
|
486
|
+
listAddons(addons);
|
|
487
|
+
line();
|
|
488
|
+
process.exit(0);
|
|
489
|
+
}
|
|
490
|
+
|
|
480
491
|
if (parsed.unknownFlags.length) {
|
|
481
492
|
for (const flag of parsed.unknownFlags) {
|
|
482
493
|
const flagName = flag.includes('=') ? flag.slice(0, flag.indexOf('=')) : flag;
|
|
@@ -551,17 +562,11 @@ const main = async () => {
|
|
|
551
562
|
process.exit(0);
|
|
552
563
|
}
|
|
553
564
|
|
|
554
|
-
if (parsed.list) {
|
|
555
|
-
line();
|
|
556
|
-
out(PAD + styled('Available add-ons:', C.bold), C.blue);
|
|
557
|
-
listAddons(addons);
|
|
558
|
-
line();
|
|
559
|
-
process.exit(0);
|
|
560
|
-
}
|
|
561
|
-
|
|
562
565
|
let addonName;
|
|
563
566
|
if (parsed.addon) {
|
|
564
567
|
addonName = await promptAddon(addons, parsed.addon);
|
|
568
|
+
|
|
569
|
+
line();
|
|
565
570
|
printAnswer(PAD + 'Add-on to install', addonName);
|
|
566
571
|
} else {
|
|
567
572
|
line();
|