lucy-cli 0.8.2 โ 0.9.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/dist/Gulpfile.js +6 -1
- package/dist/gulp/backend.js +34 -19
- package/dist/gulp/checks.js +2 -1
- package/dist/gulp/clean.js +5 -3
- package/dist/gulp/copy.js +2 -1
- package/dist/gulp/pages.d.ts +1 -1
- package/dist/gulp/pages.js +20 -11
- package/dist/gulp/pipeline.js +3 -2
- package/dist/gulp/public.js +19 -13
- package/dist/gulp/styles.js +7 -1
- package/dist/gulp/templates.js +2 -1
- package/dist/gulp/test.js +2 -1
- package/dist/gulp/types.js +3 -3
- package/dist/helpers.d.ts +6 -1
- package/dist/helpers.js +73 -7
- package/dist/index.js +48 -4
- package/dist/settings.json +31 -25
- package/files/eslint.config.mjs +141 -0
- package/files/typedoc.json +27 -17
- package/package.json +7 -5
- package/src/Gulpfile.ts +5 -1
- package/src/gulp/backend.ts +44 -32
- package/src/gulp/checks.ts +2 -1
- package/src/gulp/clean.ts +5 -3
- package/src/gulp/copy.ts +2 -1
- package/src/gulp/pages.ts +26 -16
- package/src/gulp/pipeline.ts +3 -2
- package/src/gulp/public.ts +21 -15
- package/src/gulp/styles.ts +7 -1
- package/src/gulp/templates.ts +2 -1
- package/src/gulp/test.ts +2 -1
- package/src/gulp/types.ts +3 -3
- package/src/helpers.ts +74 -10
- package/src/index.ts +54 -4
- package/src/settings.json +31 -25
- package/src/types.d.ts +2 -1
- package/files/.eslintrc.cjs +0 -108
package/src/helpers.ts
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
import chalk from 'chalk';
|
2
|
-
import { join } from 'path';
|
3
2
|
import { simpleGit } from 'simple-git';
|
4
|
-
import fs from 'fs/promises';
|
5
3
|
import { spawnSync } from 'child_process';
|
6
4
|
// https://www.sergevandenoever.nl/run-gulp4-tasks-programatically-from-node/
|
7
5
|
import path from 'path';
|
8
6
|
import { fileURLToPath } from 'url';
|
9
7
|
import { ModuleSettings, ProjectSettings } from '.';
|
10
8
|
import { exec } from 'child_process';
|
9
|
+
import os from 'os';
|
11
10
|
|
12
|
-
import { blue, green, orange, red } from './index.js';
|
11
|
+
import { blue, green, orange, red, yellow, magenta } from './index.js';
|
13
12
|
|
14
13
|
export async function installPackages(wixPackages: Record<string, string>, devPackages: Record<string, string>, cwd: string, locked: boolean ) {
|
15
14
|
if (locked) console.log("๐" + blue.underline(` => Installing & version locked packages!`));
|
@@ -83,19 +82,84 @@ export async function runGulp(moduleSettings: ModuleSettings, projectSettings: P
|
|
83
82
|
/**
|
84
83
|
* Clean up and run a command before exiting the process.
|
85
84
|
*/
|
86
|
-
export function
|
85
|
+
export function cleanupWatchers() {
|
86
|
+
console.log(`๐งน ${magenta.underline('Cleaning up Watchman watchers...')}`);
|
87
87
|
const cwd = process.cwd();
|
88
|
-
const command = `watchman watch-del
|
89
|
-
|
90
|
-
console.log("๐" + blue.underline(' => Cleaning up...'));
|
88
|
+
const command = `watchman watch-del "${cwd}"`; // Adjust for Windows paths
|
91
89
|
exec(command, (error, stdout, stderr) => {
|
92
90
|
if (error) {
|
93
|
-
console.error(`๐ฉ Failed to run cleanup: ${error.message}`);
|
91
|
+
console.error(`๐ฉ ${red.underline('Failed to run cleanup:')} ${orange(error.message)}`);
|
94
92
|
return;
|
95
93
|
}
|
96
94
|
if (stderr) {
|
97
|
-
console.error(`โ ๏ธ
|
95
|
+
console.error(`โ ๏ธ ${yellow.underline('Watchman stderr:')} ${stderr}`);
|
98
96
|
}
|
99
|
-
console.log(`โ
Watchman cleanup success: ${stdout}`);
|
97
|
+
console.log(`โ
${green.underline('Watchman cleanup success:')} ${stdout}`);
|
100
98
|
});
|
101
99
|
}
|
100
|
+
|
101
|
+
/**
|
102
|
+
* Kill all processes matching a specific substring in their command, with a fallback for Windows.
|
103
|
+
* @param {string} processPattern - The substring to match (e.g., "wix:dev" or "@wix/cli/bin/wix.cjs").
|
104
|
+
*/
|
105
|
+
export function killAllProcesses(processPattern: string) {
|
106
|
+
const isWindows = os.platform() === 'win32';
|
107
|
+
const command = isWindows
|
108
|
+
? `tasklist /FI "IMAGENAME eq node.exe" /FO CSV | findstr "${processPattern}"` // Adjust for Node.js processes
|
109
|
+
: `ps -eo pid,command | grep "${processPattern}" | grep -v grep`;
|
110
|
+
|
111
|
+
exec(command, (error, stdout, stderr) => {
|
112
|
+
if (error) {
|
113
|
+
console.error(`๐ฉ ${red.underline('Failed to find processes:')} ${orange(error.message)}`);
|
114
|
+
return;
|
115
|
+
}
|
116
|
+
if (stderr) {
|
117
|
+
console.error(`โ ๏ธ ${yellow.underline('Error output:')} ${stderr}`);
|
118
|
+
}
|
119
|
+
if (!stdout.trim()) {
|
120
|
+
console.log(`โน๏ธ ${blue.underline(`No processes found matching pattern:`)} ${orange(processPattern)}`);
|
121
|
+
return;
|
122
|
+
}
|
123
|
+
|
124
|
+
console.log(`๐ ${magenta.underline('Found matching processes:')}\n${stdout}`);
|
125
|
+
const lines = stdout.trim().split('\n');
|
126
|
+
const pids = isWindows
|
127
|
+
? lines.map(line => line.match(/"(\d+)"/)?.[1]) // Extract PID from Windows tasklist output
|
128
|
+
: lines.map(line => line.trim().split(/\s+/)[0]).filter(pid => !isNaN(Number(pid)));
|
129
|
+
|
130
|
+
pids.forEach(pid => {
|
131
|
+
if (!pid) return;
|
132
|
+
try {
|
133
|
+
const killCommand = isWindows
|
134
|
+
? `taskkill /PID ${pid} /T /F` // Forcefully terminate the process on Windows
|
135
|
+
: `kill -SIGTERM ${pid}`;
|
136
|
+
|
137
|
+
exec(killCommand, (killError) => {
|
138
|
+
if (killError) {
|
139
|
+
console.error(`โ ๏ธ ${yellow.underline('Failed to kill process with PID')} ${orange(pid)}: ${red(killError.message)}`);
|
140
|
+
} else {
|
141
|
+
console.log(`โ
${green.underline('Killed process with PID:')} ${orange(pid)}`);
|
142
|
+
}
|
143
|
+
});
|
144
|
+
|
145
|
+
// Schedule SIGKILL fallback for non-Windows platforms
|
146
|
+
if (!isWindows) {
|
147
|
+
setTimeout(() => {
|
148
|
+
try {
|
149
|
+
process.kill(parseInt(pid, 10), 'SIGKILL');
|
150
|
+
console.log(`๐ช ${red.underline('Sent SIGKILL to process with PID:')} ${orange(pid)} (fallback).`);
|
151
|
+
} catch (killError: any) {
|
152
|
+
if (killError.code === 'ESRCH') {
|
153
|
+
console.log(`โ
${green.underline('Process with PID')} ${orange(pid)} ${green.underline('already terminated.')}`);
|
154
|
+
} else {
|
155
|
+
console.error(`โ ๏ธ ${yellow.underline('Failed to send SIGKILL to process with PID')} ${orange(pid)}: ${red(killError.message)}`);
|
156
|
+
}
|
157
|
+
}
|
158
|
+
}, 10000);
|
159
|
+
}
|
160
|
+
} catch (err: any) {
|
161
|
+
console.error(`โ ๏ธ ${yellow.underline('Failed to kill process with PID')} ${orange(pid)}: ${red(err.message)}`);
|
162
|
+
}
|
163
|
+
});
|
164
|
+
});
|
165
|
+
}
|
package/src/index.ts
CHANGED
@@ -11,8 +11,9 @@ import fs from 'fs/promises';
|
|
11
11
|
|
12
12
|
import { init } from './init.js';
|
13
13
|
import { sync } from './sync.js';
|
14
|
-
import { runGulp, installPackages,
|
14
|
+
import { runGulp, installPackages, killAllProcesses, cleanupWatchers } from './helpers.js';
|
15
15
|
import { prepare } from './prepare.js';
|
16
|
+
import { spawnSync } from 'child_process';
|
16
17
|
|
17
18
|
export type LucySettings = {
|
18
19
|
modules: {
|
@@ -70,10 +71,50 @@ const __filename = fileURLToPath(import.meta.url);
|
|
70
71
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
71
72
|
const __dirname = dirname(__filename);
|
72
73
|
|
74
|
+
// const cwd = process.cwd();
|
75
|
+
// const command = `watchman watch-del '${cwd}'`;
|
76
|
+
// killAllProcesses('@wix/cli/bin/wix.cjs'); // Matches processes running the Wix CLI
|
77
|
+
// killAllProcesses('wix:dev');
|
78
|
+
|
79
|
+
|
80
|
+
process.on('exit', (code) => {
|
81
|
+
killAllProcesses('@wix/cli/bin/wix.cjs'); // Matches processes running the Wix CLI
|
82
|
+
killAllProcesses('wix:dev');
|
83
|
+
cleanupWatchers();
|
84
|
+
console.log(`๐ช ${magenta.underline('Process exiting with code:')} ${orange(code)}`);
|
85
|
+
});
|
86
|
+
|
73
87
|
process.on('SIGINT', () => {
|
74
|
-
|
75
|
-
|
76
|
-
|
88
|
+
console.log(`๐ ${green.underline('Received Ctrl+C (SIGINT), cleaning up...')}`);
|
89
|
+
killAllProcesses('@wix/cli/bin/wix.cjs'); // Matches processes running the Wix CLI
|
90
|
+
killAllProcesses('wix:dev');
|
91
|
+
cleanupWatchers();
|
92
|
+
process.exit(); // Exit explicitly after handling
|
93
|
+
});
|
94
|
+
|
95
|
+
process.on('SIGTERM', () => {
|
96
|
+
console.log(`๐ ${red.underline('Received termination signal (SIGTERM), cleaning up...')}`);
|
97
|
+
killAllProcesses('@wix/cli/bin/wix.cjs'); // Matches processes running the Wix CLI
|
98
|
+
killAllProcesses('wix:dev');
|
99
|
+
cleanupWatchers();
|
100
|
+
process.exit(); // Exit explicitly after handling
|
101
|
+
});
|
102
|
+
|
103
|
+
process.on('uncaughtException', (error) => {
|
104
|
+
console.error(`๐ฅ ${red.underline('Uncaught Exception:')}`, error);
|
105
|
+
killAllProcesses('@wix/cli/bin/wix.cjs'); // Matches processes running the Wix CLI
|
106
|
+
killAllProcesses('wix:dev');
|
107
|
+
cleanupWatchers();
|
108
|
+
process.exit(1); // Exit with an error code
|
109
|
+
});
|
110
|
+
|
111
|
+
process.on('unhandledRejection', (reason, promise) => {
|
112
|
+
console.error(`๐จ ${yellow.underline('Unhandled Rejection at:')} ${orange(promise)}`);
|
113
|
+
console.error(`๐จ ${red.underline('Reason:')} ${reason}`); cleanupWatchers();
|
114
|
+
killAllProcesses('@wix/cli/bin/wix.cjs'); // Matches processes running the Wix CLI
|
115
|
+
killAllProcesses('wix:dev');
|
116
|
+
cleanupWatchers();
|
117
|
+
process.exit(1); // Exit with an error code
|
77
118
|
});
|
78
119
|
|
79
120
|
/**
|
@@ -113,6 +154,7 @@ async function main(): Promise<void> {
|
|
113
154
|
console.log("๐ฆฎ " + magenta.bold('sync') + " : Synchronizes the database (not Implemented)");
|
114
155
|
console.log("๐ฆฎ " + magenta.bold('install') + " : Installs all Wix npm packages listed in the 'lucy.json' file in the project directory.");
|
115
156
|
console.log("๐ฆฎ " + magenta.bold('fix') + " : Runs a fix command to resolve common issues in development or production settings.");
|
157
|
+
console.log("๐ฆฎ " + magenta.bold('docs') + " : Generates documentation for the project.");
|
116
158
|
console.log("\nOptions:");
|
117
159
|
console.log("๐ฆฎ " + magenta.bold('-h, help') + " : Displays this help message.");
|
118
160
|
console.log("๐ฆฎ " + magenta.bold('-v, version') + " : Displays the current version of Lucy CLI as defined in the projectโs package.json.");
|
@@ -189,6 +231,14 @@ async function main(): Promise<void> {
|
|
189
231
|
}
|
190
232
|
|
191
233
|
|
234
|
+
if(moduleSettings.args.includes('docs')){
|
235
|
+
const res = spawnSync('yarn docs', { shell: true, stdio: 'inherit' });
|
236
|
+
if (res.error) {
|
237
|
+
return console.log((`๐ฉ ${red.underline.bold("=> Failed to install dev packages =>")} ${orange(res.error.message)}`));
|
238
|
+
}
|
239
|
+
return console.log("๐" + blue.underline(` => Docs generated!`));
|
240
|
+
}
|
241
|
+
|
192
242
|
if(moduleSettings.args.includes('prepare')){
|
193
243
|
await prepare( moduleSettings, projectSettings);
|
194
244
|
|
package/src/settings.json
CHANGED
@@ -12,33 +12,39 @@
|
|
12
12
|
"initialized": false,
|
13
13
|
"wixPackages": {},
|
14
14
|
"devPackages": {
|
15
|
-
"@
|
15
|
+
"@eslint/js": "^9.15.0",
|
16
16
|
"@styled/typescript-styled-plugin": "^1.0.1",
|
17
|
-
"@total-typescript/ts-reset": "0.6.1",
|
18
|
-
"@types/jest": "^29.5.
|
19
|
-
"@types/node": "22.9.
|
20
|
-
"@types/
|
21
|
-
"@
|
22
|
-
"@typescript-eslint/
|
23
|
-
"@
|
24
|
-
"
|
25
|
-
"
|
26
|
-
"
|
27
|
-
"
|
28
|
-
"
|
29
|
-
"
|
17
|
+
"@total-typescript/ts-reset": "^0.6.1",
|
18
|
+
"@types/jest": "^29.5.14",
|
19
|
+
"@types/node": "^22.9.1",
|
20
|
+
"@types/nodemailer": "^6.4.17",
|
21
|
+
"@types/react": "^18.3.12",
|
22
|
+
"@typescript-eslint/eslint-plugin": "^8.15.0",
|
23
|
+
"@typescript-eslint/parser": "^8.15.0",
|
24
|
+
"@typescript-eslint/utils": "^8.15.0",
|
25
|
+
"@wix/cli": "^1.1.52",
|
26
|
+
"@wix/eslint-plugin-cli": "^1.0.2",
|
27
|
+
"cypress": "^13.16.0",
|
28
|
+
"cypress-cloud": "^1.11.0",
|
29
|
+
"esbuild": "^0.24.0",
|
30
|
+
"eslint": "^9.15.0",
|
31
|
+
"eslint-plugin-import": "^2.31.0",
|
32
|
+
"eslint-plugin-jsdoc": "^50.5.0",
|
30
33
|
"eslint-plugin-named-import-spacing": "^1.0.3",
|
31
|
-
"eslint-plugin-
|
32
|
-
"
|
33
|
-
"
|
34
|
-
"
|
35
|
-
"sass": "^1.
|
36
|
-
"ts-jest": "^29.
|
37
|
-
"ts-node": "^10.9.
|
38
|
-
"tsx": "4.19.2",
|
39
|
-
"typedoc": "0.26.11",
|
40
|
-
"typedoc-
|
41
|
-
"
|
34
|
+
"eslint-plugin-simple-import-sort": "^12.1.1",
|
35
|
+
"jest": "^29.7.0",
|
36
|
+
"prettier": "^3.3.3",
|
37
|
+
"react": "^18.3.1",
|
38
|
+
"sass": "^1.81.0",
|
39
|
+
"ts-jest": "^29.2.5",
|
40
|
+
"ts-node": "^10.9.2",
|
41
|
+
"tsx": "^4.19.2",
|
42
|
+
"typedoc": "^0.26.11",
|
43
|
+
"typedoc-plugin-merge-modules": "^6.0.3",
|
44
|
+
"typedoc-plugin-zod": "^1.3.0",
|
45
|
+
"typedoc-theme-hierarchy": "^5.0.3",
|
46
|
+
"typescript": "5.6.3",
|
47
|
+
"typescript-eslint": "^8.15.0",
|
42
48
|
"typescript-eslint-language-service": "^5.0.5"
|
43
49
|
},
|
44
50
|
"scripts": {
|
package/src/types.d.ts
CHANGED
package/files/.eslintrc.cjs
DELETED
@@ -1,108 +0,0 @@
|
|
1
|
-
module.exports = {
|
2
|
-
extends: ['eslint:recommended', 'plugin:import/recommended', 'plugin:jsdoc/recommended', 'plugin:@typescript-eslint/recommended', 'plugin:@wix/cli/recommended'],
|
3
|
-
plugins: ['simple-import-sort', 'eslint-plugin-named-import-spacing', '@typescript-eslint'],
|
4
|
-
parser: '@typescript-eslint/parser',
|
5
|
-
parserOptions: {
|
6
|
-
ecmaVersion: 2021,
|
7
|
-
},
|
8
|
-
ignorePatterns: ['src/**/*', 'typescript/types/backend/**/*', 'typescript/types/pages/**/*', 'typescript/types/public/**/*', 'typescript/types/node/**/*', '.wix/**/*', 'coverage/**/*', 'docs/**/*'],
|
9
|
-
rules: {
|
10
|
-
'no-static-block': 'error',
|
11
|
-
quotes: [2, 'single', { 'avoidEscape': true, 'allowTemplateLiterals': true }],
|
12
|
-
curly: ['error', 'multi-line'],
|
13
|
-
'simple-import-sort/imports': 'error',
|
14
|
-
'simple-import-sort/exports': 'error',
|
15
|
-
indent: ['error', 'tab'],
|
16
|
-
'no-tabs': 0,
|
17
|
-
'semi-style': ['error', 'last'],
|
18
|
-
semi: [2, 'always'],
|
19
|
-
'object-curly-spacing': ['error', 'always'],
|
20
|
-
'space-in-parens': ['error', 'never'],
|
21
|
-
'newline-before-return': 'error',
|
22
|
-
'space-before-blocks': ['error', { functions: 'always', keywords: 'never', classes: 'always' }],
|
23
|
-
'comma-spacing': ['error', { before: false, after: true }],
|
24
|
-
'no-multi-spaces': ['error'],
|
25
|
-
'import/newline-after-import': ['error', { count: 1 }],
|
26
|
-
'named-import-spacing/named-import-spacing': 2,
|
27
|
-
'no-unused-vars': 'warn',
|
28
|
-
'import/no-unresolved': [0],
|
29
|
-
'no-forbidden-relative-imports': [0],
|
30
|
-
'@typescript-eslint/triple-slash-reference': 'off',
|
31
|
-
'@typescript-eslint/member-ordering': [
|
32
|
-
'error',
|
33
|
-
{ classes: ['constructor', 'private-instance-field', 'protected-instance-field', 'public-instance-field', 'public-instance-method', 'private-instance-method'] }
|
34
|
-
],
|
35
|
-
'@typescript-eslint/naming-convention': [
|
36
|
-
'error',
|
37
|
-
{
|
38
|
-
selector: ['variable', 'function'],
|
39
|
-
format: ['camelCase'],
|
40
|
-
leadingUnderscore: 'allow'
|
41
|
-
},
|
42
|
-
{
|
43
|
-
selector: ['objectLiteralProperty'],
|
44
|
-
format: null,
|
45
|
-
leadingUnderscore: 'allow'
|
46
|
-
},
|
47
|
-
{
|
48
|
-
selector: 'memberLike',
|
49
|
-
modifiers: ['private'],
|
50
|
-
format: ['camelCase'],
|
51
|
-
leadingUnderscore: 'require'
|
52
|
-
},
|
53
|
-
{
|
54
|
-
selector: 'memberLike',
|
55
|
-
modifiers: ['protected'],
|
56
|
-
format: ['camelCase'],
|
57
|
-
leadingUnderscore: 'require'
|
58
|
-
},
|
59
|
-
{
|
60
|
-
selector: 'memberLike',
|
61
|
-
modifiers: ['public'],
|
62
|
-
format: ['camelCase'],
|
63
|
-
leadingUnderscore: 'forbid'
|
64
|
-
},
|
65
|
-
{
|
66
|
-
selector: ['parameterProperty', 'parameter'],
|
67
|
-
format: ['camelCase'],
|
68
|
-
leadingUnderscore: 'forbid'
|
69
|
-
},
|
70
|
-
{
|
71
|
-
selector: 'default',
|
72
|
-
format: ['UPPER_CASE'],
|
73
|
-
leadingUnderscore: 'forbid',
|
74
|
-
trailingUnderscore: 'forbid',
|
75
|
-
custom: {
|
76
|
-
regex: '^[A-Z_]+$',
|
77
|
-
match: true
|
78
|
-
}
|
79
|
-
},
|
80
|
-
{
|
81
|
-
selector: 'typeLike',
|
82
|
-
format: ['PascalCase']
|
83
|
-
},
|
84
|
-
// Custom rule added
|
85
|
-
{
|
86
|
-
selector: 'function',
|
87
|
-
format: ['UPPER_CASE']
|
88
|
-
}
|
89
|
-
],
|
90
|
-
},
|
91
|
-
overrides: [
|
92
|
-
{
|
93
|
-
files: ['**/*.tsx', '**/*.ts'],
|
94
|
-
rules: {
|
95
|
-
'no-static-block': 'error'
|
96
|
-
}
|
97
|
-
}
|
98
|
-
],
|
99
|
-
root: true,
|
100
|
-
env: {
|
101
|
-
es6: true,
|
102
|
-
browser: true,
|
103
|
-
node: true
|
104
|
-
},
|
105
|
-
globals: {
|
106
|
-
$w: 'readonly'
|
107
|
-
}
|
108
|
-
};
|