@ijuantm/simpl-addon 2.8.4 → 2.8.7
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 +55 -46
- 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
|
@@ -195,18 +195,19 @@ const promptAddon = async (addons, firstInput = null) => {
|
|
|
195
195
|
};
|
|
196
196
|
|
|
197
197
|
const showHelp = () => {
|
|
198
|
-
box(
|
|
199
|
-
line();
|
|
200
|
-
out(PAD + styled('Usage:', C.bold), C.blue);
|
|
201
|
-
out(PAD + styled('npx @ijuantm/simpl-addon', C.dim));
|
|
202
|
-
out(PAD + styled('npx @ijuantm/simpl-addon --addon=<name>', C.dim));
|
|
203
|
-
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}`);
|
|
204
199
|
line();
|
|
205
200
|
out(PAD + styled('Options:', C.bold), C.blue);
|
|
206
201
|
out(PAD + styled('--addon=<name>, -a=<name>', C.dim) + ' Add-on to install');
|
|
207
202
|
out(PAD + styled('--list, -l', C.dim) + ' List available add-ons');
|
|
208
203
|
out(PAD + styled('--help, -h', C.dim) + ' Show this help message');
|
|
209
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();
|
|
210
211
|
out(PAD + styled('Note:', C.bold), C.blue);
|
|
211
212
|
item('Run this command from the root of your Simpl project.');
|
|
212
213
|
item('The add-on version will match your Simpl framework version.');
|
|
@@ -470,6 +471,43 @@ const mergeFiles = (toMerge) => {
|
|
|
470
471
|
return {merged, failed, unchanged};
|
|
471
472
|
};
|
|
472
473
|
|
|
474
|
+
const loadAddons = async (version) => {
|
|
475
|
+
const {versions} = await getVersionsData();
|
|
476
|
+
const versionMeta = versions[version];
|
|
477
|
+
|
|
478
|
+
if (!versionMeta) {
|
|
479
|
+
line();
|
|
480
|
+
error(`Version ${styled(version, C.bold)} not found`);
|
|
481
|
+
line();
|
|
482
|
+
process.exit(1);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
if (versionMeta['script-compatible'] === false) {
|
|
486
|
+
line();
|
|
487
|
+
error(`Version ${styled(version, C.bold)} is not compatible with this installer`);
|
|
488
|
+
line();
|
|
489
|
+
out(PAD + styled('Manual download:', C.bold), C.blue);
|
|
490
|
+
item(`${C.cyan}${CDN_BASE}/${version}/add-ons/`);
|
|
491
|
+
line();
|
|
492
|
+
out(PAD + styled('Available add-ons for this version:', C.bold), C.blue);
|
|
493
|
+
const addons = versionMeta['add-ons'] || [];
|
|
494
|
+
if (!addons.length) info('No add-ons available');
|
|
495
|
+
else for (const name of addons) item(`${name}: ${styled(`${CDN_BASE}/${version}/add-ons/${name}.zip`, C.dim)}`);
|
|
496
|
+
line();
|
|
497
|
+
process.exit(1);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
try {
|
|
501
|
+
return await getAvailableAddons(version);
|
|
502
|
+
} catch {
|
|
503
|
+
line();
|
|
504
|
+
error('Failed to fetch add-ons');
|
|
505
|
+
info('The CDN server is currently unavailable. Please try again later.');
|
|
506
|
+
line();
|
|
507
|
+
process.exit(1);
|
|
508
|
+
}
|
|
509
|
+
};
|
|
510
|
+
|
|
473
511
|
const main = async () => {
|
|
474
512
|
const parsed = parseArgs(process.argv.slice(2));
|
|
475
513
|
|
|
@@ -502,48 +540,25 @@ const main = async () => {
|
|
|
502
540
|
process.exit(1);
|
|
503
541
|
}
|
|
504
542
|
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
const versionMeta = versions[version];
|
|
510
|
-
if (!versionMeta) {
|
|
543
|
+
if (parsed.list) {
|
|
544
|
+
const addons = await loadAddons(version);
|
|
545
|
+
box(`Simpl Add-on Installer ${C.dim}-${C.reset} ${C.blue}Available Add-ons${C.reset}`);
|
|
511
546
|
line();
|
|
512
|
-
|
|
547
|
+
out(PAD + styled('Available add-ons:', C.bold), C.blue);
|
|
548
|
+
if (!addons.length) info('No add-ons available for this version');
|
|
549
|
+
else listAddons(addons);
|
|
513
550
|
line();
|
|
514
|
-
process.exit(
|
|
551
|
+
process.exit(0);
|
|
515
552
|
}
|
|
516
553
|
|
|
517
|
-
|
|
518
|
-
line();
|
|
519
|
-
error(`Version ${styled(version, C.bold)} is not compatible with this installer`);
|
|
520
|
-
line();
|
|
521
|
-
out(PAD + styled('Manual download:', C.bold), C.blue);
|
|
522
|
-
item(`${C.cyan}${CDN_BASE}/${version}/add-ons/`);
|
|
523
|
-
line();
|
|
524
|
-
out(PAD + styled('Available add-ons for this version:', C.bold), C.blue);
|
|
525
|
-
const addons = versionMeta['add-ons'] || [];
|
|
526
|
-
if (!addons.length) info('No add-ons available');
|
|
527
|
-
else for (const name of addons) item(`${name}: ${styled(`${CDN_BASE}/${version}/add-ons/${name}.zip`, C.dim)}`);
|
|
528
|
-
line();
|
|
529
|
-
process.exit(1);
|
|
530
|
-
}
|
|
554
|
+
box(`Simpl Add-on Installer ${C.dim}(v${version})${C.reset}`);
|
|
531
555
|
|
|
532
556
|
if (!parsed.addon) {
|
|
533
557
|
line();
|
|
534
558
|
task('🗄️ Fetching available add-ons...');
|
|
535
559
|
}
|
|
536
560
|
|
|
537
|
-
|
|
538
|
-
try {
|
|
539
|
-
addons = await getAvailableAddons(version);
|
|
540
|
-
} catch {
|
|
541
|
-
line();
|
|
542
|
-
error('Failed to fetch add-ons');
|
|
543
|
-
info('The CDN server is currently unavailable. Please try again later.');
|
|
544
|
-
line();
|
|
545
|
-
process.exit(1);
|
|
546
|
-
}
|
|
561
|
+
const addons = await loadAddons(version);
|
|
547
562
|
|
|
548
563
|
if (!addons.length) {
|
|
549
564
|
line();
|
|
@@ -552,17 +567,11 @@ const main = async () => {
|
|
|
552
567
|
process.exit(0);
|
|
553
568
|
}
|
|
554
569
|
|
|
555
|
-
if (parsed.list) {
|
|
556
|
-
line();
|
|
557
|
-
out(PAD + styled('Available add-ons:', C.bold), C.blue);
|
|
558
|
-
listAddons(addons);
|
|
559
|
-
line();
|
|
560
|
-
process.exit(0);
|
|
561
|
-
}
|
|
562
|
-
|
|
563
570
|
let addonName;
|
|
564
571
|
if (parsed.addon) {
|
|
565
572
|
addonName = await promptAddon(addons, parsed.addon);
|
|
573
|
+
|
|
574
|
+
line();
|
|
566
575
|
printAnswer(PAD + 'Add-on to install', addonName);
|
|
567
576
|
} else {
|
|
568
577
|
line();
|