@ijuantm/simpl-addon 2.1.0 → 2.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.
Files changed (2) hide show
  1. package/install.js +115 -44
  2. package/package.json +3 -3
package/install.js CHANGED
@@ -3,6 +3,7 @@
3
3
  const fs = require('fs');
4
4
  const path = require('path');
5
5
  const https = require('https');
6
+ const readline = require('readline');
6
7
  const {promisify} = require('util');
7
8
  const {exec} = require('child_process');
8
9
 
@@ -57,6 +58,16 @@ const downloadFile = (url, dest) => new Promise((resolve, reject) => {
57
58
  });
58
59
  });
59
60
 
61
+ const promptUser = (question, defaultValue = '') => new Promise(resolve => {
62
+ const rl = readline.createInterface({input: process.stdin, output: process.stdout});
63
+ const prompt = defaultValue ? `${question} ${COLORS.dim}(${defaultValue})${COLORS.reset}: ` : `${question}: `;
64
+
65
+ rl.question(prompt, answer => {
66
+ rl.close();
67
+ resolve(answer.trim() || defaultValue);
68
+ });
69
+ });
70
+
60
71
  const getSimplVersion = () => {
61
72
  const simplFile = path.join(process.cwd(), '.simpl');
62
73
 
@@ -76,20 +87,14 @@ const showHelp = () => {
76
87
  log(` ╰${'─'.repeat(62)}╯`);
77
88
  console.log();
78
89
  log(` ${COLORS.bold}Usage:${COLORS.reset}`, 'blue');
79
- log(` ${COLORS.dim}npx @ijuantm/simpl-addon <addon-name>${COLORS.reset}`);
80
- log(` ${COLORS.dim}npx @ijuantm/simpl-addon --list${COLORS.reset}`);
90
+ log(` ${COLORS.dim}npx @ijuantm/simpl-addon${COLORS.reset}`);
81
91
  log(` ${COLORS.dim}npx @ijuantm/simpl-addon --help${COLORS.reset}`);
82
92
  console.log();
83
- log(` ${COLORS.bold}Arguments:${COLORS.reset}`, 'blue');
84
- log(` ${COLORS.dim}addon-name${COLORS.reset} Name of the add-on to install`);
85
- console.log();
86
93
  log(` ${COLORS.bold}Commands:${COLORS.reset}`, 'blue');
87
- log(` ${COLORS.dim}--list, -l${COLORS.reset} List all available add-ons`);
88
94
  log(` ${COLORS.dim}--help, -h${COLORS.reset} Show this help message`);
89
95
  console.log();
90
96
  log(` ${COLORS.bold}Examples:${COLORS.reset}`, 'blue');
91
- log(` ${COLORS.dim}npx @ijuantm/simpl-addon auth${COLORS.reset}`);
92
- log(` ${COLORS.dim}npx @ijuantm/simpl-addon --list${COLORS.reset}`);
97
+ log(` ${COLORS.dim}npx @ijuantm/simpl-addon${COLORS.reset}`);
93
98
  console.log();
94
99
  log(` ${COLORS.bold}Note:${COLORS.reset}`, 'blue');
95
100
  log(` Run this command from the root of your Simpl project.`);
@@ -109,39 +114,21 @@ const checkServerAvailability = () => new Promise(resolve => {
109
114
  });
110
115
  });
111
116
 
112
- const listAddons = async (version) => {
113
- console.log();
114
- log(` ╭${'─'.repeat(62)}╮`);
115
- log(` │ ${COLORS.bold}Available Add-ons${COLORS.reset} ${COLORS.dim}(${version})${COLORS.reset}${' '.repeat(40 - version.length)}│`);
116
- log(` ╰${'─'.repeat(62)}╯`);
117
- console.log();
118
- log(' 📦 Fetching available add-ons...', 'bold');
119
-
120
- try {
121
- const localListPath = path.join(LOCAL_RELEASES_DIR, version, 'add-ons', 'list.json');
122
- let addons;
117
+ const getVersionsData = async () => {
118
+ if (!await checkServerAvailability()) throw new Error('CDN server is currently unreachable');
119
+ return JSON.parse(await fetchUrl(`${CDN_BASE}/versions.json`));
120
+ };
123
121
 
124
- if (fs.existsSync(localListPath)) {
125
- console.log();
126
- log(` 💻 Using local add-ons list`, 'bold');
127
- addons = JSON.parse(fs.readFileSync(localListPath, 'utf8'))['add-ons'];
128
- } else {
129
- if (!await checkServerAvailability()) throw new Error('CDN server is currently unreachable');
130
- addons = JSON.parse(await fetchUrl(`${CDN_BASE}/${version}/add-ons/list.json`))['add-ons'];
131
- }
122
+ const getAvailableAddons = async (version) => {
123
+ const localAddonsDir = path.join(LOCAL_RELEASES_DIR, version, 'add-ons');
132
124
 
133
- console.log();
125
+ if (fs.existsSync(localAddonsDir)) return fs.readdirSync(localAddonsDir, {withFileTypes: true})
126
+ .filter(entry => entry.isFile() && entry.name.endsWith('.zip'))
127
+ .map(entry => entry.name.replace('.zip', ''));
134
128
 
135
- if (addons.length === 0) log(` ${COLORS.yellow}⚠${COLORS.reset} No add-ons available`);
136
- else addons.forEach(name => log(` ${COLORS.cyan}•${COLORS.reset} ${name}`));
137
- } catch (error) {
138
- console.log();
139
- log(` ${COLORS.red}✗${COLORS.reset} Failed to fetch add-ons`, 'red');
140
- console.log();
141
- process.exit(1);
142
- }
143
-
144
- console.log();
129
+ const versionsData = await getVersionsData();
130
+ const versionMeta = versionsData.versions[version];
131
+ return versionMeta?.['add-ons'] || [];
145
132
  };
146
133
 
147
134
  const extractMarkers = (content) => {
@@ -375,7 +362,7 @@ const main = async () => {
375
362
  const args = process.argv.slice(2);
376
363
  const firstArg = args[0];
377
364
 
378
- if (!firstArg || firstArg === '--help' || firstArg === '-h') {
365
+ if (firstArg === '--help' || firstArg === '-h') {
379
366
  showHelp();
380
367
  process.exit(0);
381
368
  }
@@ -391,16 +378,100 @@ const main = async () => {
391
378
  process.exit(1);
392
379
  }
393
380
 
394
- if (firstArg === '--list' || firstArg === '-l') {
395
- await listAddons(version);
381
+ console.log();
382
+ log(` ╭${'─'.repeat(62)}╮`);
383
+ log(` │ ${COLORS.bold}Simpl Add-on Installer${COLORS.reset} ${COLORS.dim}(${version})${COLORS.reset}${' '.repeat(37 - version.length)}│`);
384
+ log(` ╰${'─'.repeat(62)}╯`);
385
+ console.log();
386
+
387
+ let versionsData;
388
+
389
+ try {
390
+ versionsData = await getVersionsData();
391
+ } catch (error) {
392
+ console.log();
393
+ log(` ${COLORS.red}✗${COLORS.reset} Failed to fetch version data`, 'red');
394
+ if (error.message === 'CDN server is currently unreachable') log(` ${COLORS.dim}The CDN server is currently unavailable. Please try again later.${COLORS.reset}`);
395
+ console.log();
396
+ process.exit(1);
397
+ }
398
+
399
+ const versionMeta = versionsData.versions[version];
400
+ if (!versionMeta) {
401
+ console.log();
402
+ log(` ${COLORS.red}✗${COLORS.reset} Version ${COLORS.bold}${version}${COLORS.reset} not found`, 'red');
403
+ console.log();
404
+ process.exit(1);
405
+ }
406
+
407
+ if (versionMeta['script-compatible'] === false) {
408
+ console.log();
409
+ log(` ${COLORS.red}✗${COLORS.reset} Version ${COLORS.bold}${version}${COLORS.reset} is not compatible with this installer`, 'red');
410
+ console.log();
411
+ log(` ${COLORS.bold}Manual download:${COLORS.reset}`, 'blue');
412
+ log(` ${COLORS.cyan}${CDN_BASE}/${version}/add-ons/`, 'cyan');
413
+ console.log();
414
+ log(` ${COLORS.bold}Available add-ons for this version:${COLORS.reset}`, 'blue');
415
+
416
+ const addons = versionMeta['add-ons'] || [];
417
+ if (addons.length === 0) {
418
+ log(` ${COLORS.dim}No add-ons available${COLORS.reset}`);
419
+ } else {
420
+ addons.forEach(name => {
421
+ log(` ${COLORS.cyan}•${COLORS.reset} ${name}: ${COLORS.dim}${CDN_BASE}/${version}/add-ons/${name}.zip${COLORS.reset}`);
422
+ });
423
+ }
424
+
425
+ console.log();
426
+ process.exit(1);
427
+ }
428
+
429
+ log(' 📦 Fetching available add-ons...', 'bold');
430
+
431
+ let addons;
432
+
433
+ try {
434
+ addons = await getAvailableAddons(version);
435
+ } catch (error) {
436
+ console.log();
437
+ log(` ${COLORS.red}✗${COLORS.reset} Failed to fetch add-ons`, 'red');
438
+ if (error.message === 'CDN server is currently unreachable') log(` ${COLORS.dim}The CDN server is currently unavailable. Please try again later.${COLORS.reset}`);
439
+ console.log();
440
+ process.exit(1);
441
+ }
442
+
443
+ console.log();
444
+
445
+ if (addons.length === 0) {
446
+ log(` ${COLORS.yellow}⚠${COLORS.reset} No add-ons available for this version`);
447
+ console.log();
396
448
  process.exit(0);
397
449
  }
398
450
 
399
- const addonName = firstArg;
451
+ log(` ${COLORS.bold}Available add-ons:${COLORS.reset}`, 'blue');
452
+ addons.forEach(name => log(` ${COLORS.cyan}•${COLORS.reset} ${name}`));
453
+ console.log();
454
+
455
+ let addonName;
456
+
457
+ while (true) {
458
+ addonName = await promptUser(' Add-on to install');
459
+ if (!addonName) {
460
+ log(` ${COLORS.red}✗${COLORS.reset} Add-on name cannot be empty`, 'red');
461
+ console.log();
462
+ continue;
463
+ }
464
+ if (!addons.includes(addonName)) {
465
+ log(` ${COLORS.red}✗${COLORS.reset} Add-on "${addonName}" not found`, 'red');
466
+ console.log();
467
+ continue;
468
+ }
469
+ break;
470
+ }
400
471
 
401
472
  console.log();
402
473
  log(` ╭${'─'.repeat(62)}╮`);
403
- log(` │ ${COLORS.bold}Installing Add-on: ${COLORS.cyan}${addonName}${COLORS.reset} ${COLORS.dim}(${version})${COLORS.reset}${' '.repeat(38 - addonName.length - version.length)}│`);
474
+ log(` │ ${COLORS.bold}Installing: ${COLORS.cyan}${addonName}${COLORS.reset} ${COLORS.dim}(${version})${COLORS.reset}${' '.repeat(46 - addonName.length - version.length)}│`);
404
475
  log(` ╰${'─'.repeat(62)}╯`);
405
476
  console.log();
406
477
  log(' 📦 Downloading add-on...', 'bold');
@@ -413,7 +484,7 @@ const main = async () => {
413
484
  console.log();
414
485
  log(` ${COLORS.red}✗${COLORS.reset} Installation failed`, 'red');
415
486
  if (error.message === 'CDN server is currently unreachable') log(` ${COLORS.dim}The CDN server is currently unavailable. Please try again later.${COLORS.reset}`);
416
- else log(` ${COLORS.dim}Run ${COLORS.dim}npx @ijuantm/simpl-addon --list${COLORS.reset} to see available add-ons`);
487
+ else log(` ${COLORS.dim}Please verify the add-on exists and try again${COLORS.reset}`);
417
488
  console.log();
418
489
  process.exit(1);
419
490
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ijuantm/simpl-addon",
3
3
  "description": "CLI tool to install Simpl framework add-ons.",
4
- "version": "2.1.0",
4
+ "version": "2.3.0",
5
5
  "scripts": {
6
6
  "link": "npm link",
7
7
  "unlink": "npm unlink -g @ijuantm/simpl-addon"
@@ -15,7 +15,7 @@
15
15
  },
16
16
  "repository": {
17
17
  "type": "git",
18
- "url": "https://github.com/IJuanTM/simpl"
18
+ "url": "https://github.com/IJuanTM/simpl/"
19
19
  },
20
20
  "keywords": [
21
21
  "simpl",
@@ -26,5 +26,5 @@
26
26
  ],
27
27
  "author": "Iwan van der Wal",
28
28
  "license": "GPL-3.0-only",
29
- "homepage": "https://simpl.iwanvanderwal.nl"
29
+ "homepage": "https://simpl.iwanvanderwal.nl/"
30
30
  }