kempo-server 1.4.7 → 1.4.8

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "kempo-server",
3
3
  "type": "module",
4
- "version": "1.4.7",
4
+ "version": "1.4.8",
5
5
  "description": "A lightweight, zero-dependency, file based routing server.",
6
6
  "main": "index.js",
7
7
  "bin": {
package/utils/cli.js ADDED
@@ -0,0 +1,124 @@
1
+ import { spawn } from 'child_process';
2
+ import readline from 'readline';
3
+
4
+ /*
5
+ Argument Parsing
6
+ */
7
+ export const getArgs = (mapping = {}) => {
8
+ const args = {};
9
+ let name = '';
10
+ let values = [];
11
+
12
+ const save = () => {
13
+ if(name){
14
+ if(values.length === 0){
15
+ args[name] = true;
16
+ } else if(values.length === 1){
17
+ if(values[0] === 'false'){
18
+ args[name] = false;
19
+ } else {
20
+ args[name] = values[0];
21
+ }
22
+ } else {
23
+ args[name] = values;
24
+ }
25
+ }
26
+ };
27
+
28
+ for(let i = 2; i < process.argv.length; i++){
29
+ const arg = process.argv[i];
30
+ if(arg.startsWith('-')){
31
+ save();
32
+ if(arg.startsWith('--')){
33
+ name = arg.slice(2);
34
+ } else {
35
+ name = arg.slice(1);
36
+ if(mapping[name]){
37
+ name = mapping[name];
38
+ }
39
+ }
40
+ values = [];
41
+ } else {
42
+ values.push(arg);
43
+ }
44
+ }
45
+ save();
46
+ return args;
47
+ };
48
+
49
+ /*
50
+ Child Process Utilities
51
+ */
52
+ export const runChildProcess = command => new Promise((resolve, reject) => {
53
+ const [cmd, ...args] = command.split(' ');
54
+ const child = spawn(cmd, args, { stdio: 'inherit', shell: true });
55
+
56
+ child.on('close', code => {
57
+ if(code === 0){
58
+ resolve(`child process exited with code ${code}`);
59
+ } else {
60
+ reject(new Error(`child process exited with code ${code}`));
61
+ }
62
+ });
63
+
64
+ child.on('error', reject);
65
+ });
66
+
67
+ export const runChildNodeProcess = (scriptPath, argsObj = {}) => {
68
+ const args = Object.entries(argsObj).flatMap(([key, value]) => {
69
+ if(value === true){
70
+ return [`--${key}`];
71
+ } else {
72
+ return [`--${key}`, value];
73
+ }
74
+ });
75
+ const command = `node ${scriptPath} ${args.join(' ')}`;
76
+ return runChildProcess(command);
77
+ };
78
+
79
+ export const runChildNodeProcessScript = scriptPath => {
80
+ const child = spawn('node', [scriptPath], {
81
+ stdio: 'inherit',
82
+ shell: true
83
+ });
84
+
85
+ return new Promise((resolve, reject) => {
86
+ child.on('close', code => {
87
+ if(code === 0){
88
+ resolve();
89
+ } else {
90
+ reject(new Error(`Process exited with code ${code}`));
91
+ }
92
+ });
93
+
94
+ child.on('error', reject);
95
+ });
96
+ };
97
+
98
+ /*
99
+ User Input Utilities
100
+ */
101
+ export const promptUser = query => {
102
+ const rl = readline.createInterface({
103
+ input: process.stdin,
104
+ output: process.stdout
105
+ });
106
+
107
+ return new Promise((resolve) => {
108
+ rl.question(`${query}: `, (answer) => {
109
+ rl.close();
110
+ resolve(answer);
111
+ });
112
+ });
113
+ };
114
+
115
+ export const promptYN = (query, defaultValue = 'y') => {
116
+ const formattedQuery = `${query} (${defaultValue === 'y' ? 'Y/n' : 'y/N'}): `;
117
+ return promptUser(formattedQuery).then((answer) => {
118
+ const normalizedAnswer = answer.trim().toLowerCase();
119
+ if (normalizedAnswer === '') {
120
+ return defaultValue === 'y';
121
+ }
122
+ return normalizedAnswer === 'y';
123
+ });
124
+ };
@@ -0,0 +1,41 @@
1
+ import fs from 'fs/promises';
2
+ import path from 'path';
3
+
4
+ export const ensureDir = async dirPath => {
5
+ try {
6
+ await fs.mkdir(dirPath, { recursive: true });
7
+ } catch (error) {
8
+ if(error.code !== 'EEXIST') {
9
+ throw error;
10
+ }
11
+ }
12
+ };
13
+
14
+ export const copyDir = async (src, dest) => {
15
+ await ensureDir(dest);
16
+ const entries = await fs.readdir(src, { withFileTypes: true });
17
+
18
+ for(const entry of entries) {
19
+ const srcPath = path.join(src, entry.name);
20
+ const destPath = path.join(dest, entry.name);
21
+
22
+ if(entry.isDirectory()) {
23
+ await copyDir(srcPath, destPath);
24
+ } else {
25
+ await fs.copyFile(srcPath, destPath);
26
+ }
27
+ }
28
+ };
29
+
30
+ export const emptyDir = async dirPath => {
31
+ try {
32
+ const entries = await fs.readdir(dirPath);
33
+ await Promise.all(entries.map(entry =>
34
+ fs.rm(path.join(dirPath, entry), { recursive: true, force: true })
35
+ ));
36
+ } catch (error) {
37
+ if(error.code !== 'ENOENT') {
38
+ throw error;
39
+ }
40
+ }
41
+ };