lucy-cli 0.7.15 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. package/README.md +29 -1
  2. package/dist/Gulpfile.d.ts +1 -0
  3. package/dist/Gulpfile.js +14 -12
  4. package/dist/gulp/backend.d.ts +2 -5
  5. package/dist/gulp/backend.js +43 -82
  6. package/dist/gulp/checks.d.ts +2 -2
  7. package/dist/gulp/checks.js +21 -22
  8. package/dist/gulp/copy.d.ts +1 -2
  9. package/dist/gulp/copy.js +29 -34
  10. package/dist/gulp/helpers.d.ts +1 -0
  11. package/dist/gulp/helpers.js +7 -0
  12. package/dist/gulp/public.d.ts +1 -2
  13. package/dist/gulp/public.js +20 -33
  14. package/dist/gulp/styles.d.ts +1 -1
  15. package/dist/gulp/styles.js +19 -6
  16. package/dist/gulp/templates.d.ts +2 -2
  17. package/dist/gulp/templates.js +27 -30
  18. package/dist/gulp/test.d.ts +2 -2
  19. package/dist/gulp/test.js +24 -50
  20. package/dist/gulp/types.js +9 -18
  21. package/dist/gulp/watchers.d.ts +0 -6
  22. package/dist/gulp/watchers.js +27 -61
  23. package/dist/helpers.d.ts +4 -0
  24. package/dist/helpers.js +19 -0
  25. package/dist/index.js +7 -1
  26. package/dist/models.d.ts +37 -0
  27. package/dist/models.js +1 -0
  28. package/files/typescript/templates/render.ts +32 -0
  29. package/lucy.jpg +0 -0
  30. package/package.json +1 -1
  31. package/settings/master-settings.json +0 -1
  32. package/settings/page-settings.json +0 -1
  33. package/settings/public-settings.json +0 -1
  34. package/src/Gulpfile.ts +13 -17
  35. package/src/gulp/backend.ts +74 -107
  36. package/src/gulp/checks.ts +32 -28
  37. package/src/gulp/copy.ts +38 -40
  38. package/src/gulp/helpers.ts +9 -0
  39. package/src/gulp/public.ts +36 -47
  40. package/src/gulp/styles.ts +32 -13
  41. package/src/gulp/templates.ts +38 -39
  42. package/src/gulp/test.ts +55 -75
  43. package/src/gulp/types.ts +28 -41
  44. package/src/gulp/watchers.ts +31 -101
  45. package/src/helpers.ts +23 -1
  46. package/src/index.ts +7 -1
  47. package/src/models.ts +35 -0
package/src/gulp/test.ts CHANGED
@@ -1,82 +1,62 @@
1
1
  import gulp from 'gulp';
2
- import { blue, red } from '../index.js';
2
+ import { blue, orange, red } from '../index.js';
3
3
  import gulpJest from 'gulp-jest';
4
+ import { TaskOptions } from '../Gulpfile.js';
4
5
  const jest = gulpJest.default;
5
6
 
6
- export function test() {
7
- return () => {
8
- return gulp.src([
9
- 'typescript/backend/**/*.spec.ts',
10
- ])
11
- .pipe(jest({
12
- verbose: true,
13
- extensionsToTreatAsEsm: ['.ts'],
14
- transform: {
15
- '^.+\\.tsx?$': [
16
- 'ts-jest',
17
- {
18
- tsconfig: './typescript/tsconfig.json',
19
- usESM: true,
20
- },
21
- ],
22
- },
23
- preset: 'ts-jest',
24
- setupFilesAfterEnv: [],
25
- testEnvironment: 'node',
26
- collectCoverage: true,
27
- coverageDirectory: '../coverage',
28
- coverageReporters: ['clover', 'json', 'lcov', 'text'],
29
- rootDir: './typescript',
30
- testMatch: ['**/*.spec.ts'],
31
- passWithNoTests: true,
32
- moduleNameMapper: {
33
- 'public/(.*)': '<rootDir>/public/$1'
34
- }
35
- }))
36
- .on('error', function () {
37
- console.log("💩" + red.underline.bold(' => Tests failed!'));
38
- this.emit('end');
39
- })
40
- .on('end', function() { console.log("🐶" + blue.underline(' => Test succeeded!'));
7
+ export function test(options: TaskOptions) {
8
+ const folders = ['typescript'];
9
+ if (options.modulesSync){
10
+ for (const module of Object.keys(options.modulesSync)) {
11
+ folders.push(module);
41
12
  }
42
- )}
43
- }
13
+ }
14
+
15
+ // Create tasks for each folder
16
+ const tasks = folders.map((folder) => {
17
+ const taskName = `tests-${folder}`; // Create a unique name for each task
18
+ const task = () =>
19
+ gulp.src([
20
+ `${folder}/backend/**/*.spec.ts`,
21
+ ])
22
+ .pipe(jest({
23
+ verbose: true,
24
+ extensionsToTreatAsEsm: ['.ts'],
25
+ transform: {
26
+ '^.+\\.tsx?$': [
27
+ 'ts-jest',
28
+ {
29
+ tsconfig: `./${folder}/tsconfig.json`,
30
+ usESM: true,
31
+ },
32
+ ],
33
+ },
34
+ preset: 'ts-jest',
35
+ setupFilesAfterEnv: [],
36
+ testEnvironment: 'node',
37
+ collectCoverage: true,
38
+ coverageDirectory: './coverage',
39
+ coverageReporters: ['clover', 'json', 'lcov', 'text'],
40
+ rootDir: `./${folder}`,
41
+ testMatch: ['**/*.spec.ts'],
42
+ passWithNoTests: true,
43
+ moduleNameMapper: {
44
+ 'public/(.*)': '<rootDir>/public/$1'
45
+ }
46
+ }))
47
+ .on('error', function () {
48
+ console.log("💩" + red.underline.bold(` => Tests for ${orange(folder)} failed!`));
49
+ this.emit('end');
50
+ })
51
+ .on('end', function () {
52
+ console.log("🐶" + blue.underline(` => Tests for ${orange(folder)} succeeded!`));
53
+ });
44
54
 
45
- export function testLib() {
46
- return () => {
47
- return gulp.src([
48
- 'lib/backend/**/*.spec.ts',
49
- ])
50
- .pipe(jest({
51
- verbose: true,
52
- extensionsToTreatAsEsm: ['.ts'],
53
- transform: {
54
- '^.+\\.tsx?$': [
55
- 'ts-jest',
56
- {
57
- tsconfig: './lib/tsconfig.json',
58
- usESM: true,
59
- },
60
- ],
61
- },
62
- preset: 'ts-jest',
63
- setupFilesAfterEnv: [],
64
- testEnvironment: 'node',
65
- collectCoverage: true,
66
- passWithNoTests: true,
67
- coverageDirectory: './coverage',
68
- coverageReporters: ['clover', 'json', 'lcov', 'text'],
69
- rootDir: './lib',
70
- testMatch: ['**/*.spec.ts'],
71
- moduleNameMapper: {
72
- 'public/(.*)': '<rootDir>/public/$1'
73
- }
74
- }))
75
- .on('error', function () {
76
- console.log("💩" + red.underline.bold(' => Test (LIB) failed!'));
77
- this.emit('end');
78
- })
79
- .on('end', function() { console.log("🐶" + blue.underline(' => Test (LIB) succeeded!'));
80
- }
81
- )}
55
+ // Register the task with Gulp
56
+ Object.defineProperty(task, 'name', { value: taskName }); // Set a unique name for debugging
57
+ return task;
58
+ });
59
+
60
+ // Run all tasks in parallel
61
+ return gulp.parallel(...tasks);
82
62
  }
package/src/gulp/types.ts CHANGED
@@ -9,6 +9,7 @@ import merge from 'merge-stream';
9
9
  import * as insert from 'gulp-insert';
10
10
  import { blue, red, yellow } from '../index.js';
11
11
  import tap from 'gulp-tap';
12
+ import { TSConfig } from '../models';
12
13
 
13
14
  export function updateWixTypes(options: TaskOptions) {
14
15
  return () => {
@@ -111,29 +112,29 @@ export function updateWixTypes(options: TaskOptions) {
111
112
  count ++;
112
113
  if (file.dirname.endsWith('public')) {
113
114
  return stream.pipe(jeditor(publicSettings))
114
- .pipe(jeditor((json: any) => cleanTsConfig(json)))
115
- .pipe(jeditor((json: any) => processJson(json)))
116
- .pipe(replace('"../backend.d.ts",', '', replaceOptions))
117
- .pipe(replace('"../../../src/backend/\\*\\*/\\*.web.js",', '', replaceOptions));
115
+ .pipe(jeditor((json: any) => cleanTsConfig(json)))
116
+ .pipe(jeditor((json: any) => processJson(json)))
117
+ .pipe(replace('"../backend.d.ts",', '', replaceOptions))
118
+ .pipe(replace('"../../../src/backend/\\*\\*/\\*.web.js",', '', replaceOptions));
118
119
  }
119
120
  if (file.dirname.endsWith('backend')) {
120
121
  return stream.pipe(jeditor(backendSettings))
121
- .pipe(jeditor((json: any) => cleanTsConfig(json)))
122
- .pipe(jeditor((json: any) => processJson(json)))
122
+ .pipe(jeditor((json: any) => cleanTsConfig(json)))
123
+ .pipe(jeditor((json: any) => processJson(json)))
123
124
  };
124
125
  if (file.dirname.endsWith('masterPage')) {
125
126
  return stream.pipe(jeditor(masterSettings))
126
- .pipe(jeditor((json: any) => cleanTsConfig(json)))
127
- .pipe(jeditor((json: any) => processJson(json)))
128
- .pipe(replace('"../backend.d.ts",', '', replaceOptions))
129
- .pipe(replace('"../../../src/backend/\\*\\*/\\*.web.js",', '', replaceOptions));
130
- };
131
-
132
- return stream.pipe(jeditor(pageSettings))
133
127
  .pipe(jeditor((json: any) => cleanTsConfig(json)))
134
128
  .pipe(jeditor((json: any) => processJson(json)))
135
129
  .pipe(replace('"../backend.d.ts",', '', replaceOptions))
136
130
  .pipe(replace('"../../../src/backend/\\*\\*/\\*.web.js",', '', replaceOptions));
131
+ };
132
+
133
+ return stream.pipe(jeditor(pageSettings))
134
+ .pipe(jeditor((json: any) => cleanTsConfig(json)))
135
+ .pipe(jeditor((json: any) => processJson(json)))
136
+ .pipe(replace('"../backend.d.ts",', '', replaceOptions))
137
+ .pipe(replace('"../../../src/backend/\\*\\*/\\*.web.js",', '', replaceOptions));
137
138
  }))
138
139
  .pipe(replace('masterPage.masterPage.js', 'masterPage.ts', replaceOptions))
139
140
  .pipe(replace('/src/', '/typescript/', replaceOptions))
@@ -259,33 +260,19 @@ function processJson(obj: any): any {
259
260
  }
260
261
  }
261
262
 
262
- function cleanTsConfig(json: any): any {
263
- // Process the paths object to remove duplicates
264
- if (json.compilerOptions?.paths) {
265
- for (const key in json.compilerOptions.paths) {
266
- if (Array.isArray(json.compilerOptions.paths[key])) {
267
- const uniquePaths = [...new Set(json.compilerOptions.paths[key])];
268
- json.compilerOptions.paths[key] = uniquePaths.length > 0 ? uniquePaths : undefined;
269
- }
270
- }
271
- }
272
-
273
- // Process the include array to remove duplicates
274
- if (Array.isArray(json.include)) {
275
- const uniqueIncludes = [...new Set(json.include)];
276
- json.include = uniqueIncludes.length > 0 ? uniqueIncludes : undefined;
277
- }
278
-
279
- // Remove empty or undefined fields
280
- if (json.compilerOptions?.paths) {
281
- json.compilerOptions.paths = Object.fromEntries(
282
- Object.entries(json.compilerOptions.paths).filter(([_, value]) => value !== undefined)
283
- );
284
- }
285
-
286
- if (json.include?.length === 0) {
287
- delete json.include;
288
- }
263
+ function cleanTsConfig(json: TSConfig): TSConfig {
264
+ // const paths: Record<string, string[]> = {};
265
+ if (json.compilerOptions?.paths) {
266
+ for (const [key, value] of Object.entries(json.compilerOptions.paths)) {
267
+ const uniquePaths = new Set(value);
268
+ json.compilerOptions.paths[key] = Array.from(uniquePaths);
269
+ // paths[key] = Array.from(uniquePaths);
270
+ }
271
+ // json.compilerOptions.paths = paths;
272
+ }
273
+ json.include = Array.from(new Set(json.include));
274
+ json.exclude = Array.from(new Set(json.exclude));
275
+ json.files = Array.from(new Set(json.files));
289
276
 
290
- return json;
277
+ return json;
291
278
  }
@@ -1,100 +1,55 @@
1
1
  import gulp from 'gulp';
2
2
  import { TaskOptions } from '../Gulpfile.js';
3
3
  import { green } from '../index.js';
4
- import { buildBackend, buildBackendJSW, buildBackendJSWLib, buildBackendLib } from './backend.js';
5
- import { buildPublic, buildPublicLib } from './public.js';
4
+ import { buildBackend, buildBackendJSW } from './backend.js';
5
+ import { buildPublic } from './public.js';
6
6
  import { buildPages } from './pages.js';
7
- import { copyFiles, copyFilesLib } from './copy.js';
8
- import { previewTemplates, previewTemplatesLib } from './templates.js';
9
- import { checkPages, checkTs, checkTsLib } from './checks.js';
10
- import { testLib, test } from './test.js';
7
+ import { copyFiles } from './copy.js';
8
+ import { previewTemplates } from './templates.js';
9
+ import { checkPages, checkTs } from './checks.js';
10
+ import { test } from './test.js';
11
11
 
12
12
  let taskOptions: TaskOptions;
13
13
 
14
14
  export function watchSCSS() {
15
15
  return gulp.watch([
16
- 'typescript/styles/**/*.scss',
17
- 'lib/styles/**/*.scss'],
16
+ '*/styles/**/*.scss'
17
+ ],
18
18
  gulp.parallel('scss')
19
19
  );
20
20
  }
21
21
 
22
22
  export function watchBackend() {
23
23
  return gulp.watch([
24
- 'typescript/backend/**/*.ts',
25
- 'typescript/backend/**/*.tsx',
26
- '!typescript/backend/**/*.spec.ts',
27
- '!typescript/backend/**/*.jsw.ts',
24
+ '*/backend/**/*.ts',
25
+ '*/backend/**/*.tsx',
26
+ '!*/backend/**/*.spec.ts',
27
+ '!*/backend/**/*.jsw.ts',
28
+ '!src/**/**',
28
29
  ], gulp.parallel(
29
- test(),
30
- checkTs(),
30
+ test(taskOptions),
31
+ checkTs(taskOptions),
31
32
  buildBackend(taskOptions),
32
33
  )
33
34
  );
34
35
  }
35
36
 
36
- export function watchBackendLib() {
37
- return gulp.watch([
38
- 'lib/backend/**/*.ts',
39
- 'lib/backend/**/*.tsx',
40
- '!lib/backend/**/*.spec.ts',
41
- '!lib/backend/**/*.jsw.ts',
42
- ], gulp.parallel(
43
- testLib(),
44
- checkTsLib(),
45
- buildBackendLib(taskOptions)
46
- )
47
- );
48
- }
49
-
50
- export function watchJSW() {
51
- return gulp.watch(['typescript/backend/**/*.jsw.ts'],
52
- gulp.parallel(
53
- test(),
54
- checkTs(),
55
- buildBackendJSW(taskOptions)
56
- )
57
- );
58
- }
59
-
60
- export function watchJSWLib() {
61
- return gulp.watch(['lib/backend/**/*.jsw.ts'],
62
- gulp.parallel(
63
- testLib(),
64
- checkTsLib(),
65
- buildBackendJSWLib(taskOptions)
66
- )
67
- );
68
- }
69
-
70
37
  export function watchPublic() {
71
38
  return gulp.watch([
72
- 'typescript/public/**/*.ts',
73
- 'typescript/public/**/*.tsx',
39
+ '*/public/**/*.ts',
40
+ '*/public/**/*.tsx',
74
41
  ], gulp.parallel(
75
- test(),
76
- checkTs(),
42
+ test(taskOptions),
43
+ checkTs(taskOptions),
77
44
  buildPublic(taskOptions),
78
45
  )
79
46
  );
80
47
  }
81
48
 
82
- export function watchPublicLib() {
83
- return gulp.watch([
84
- 'lib/public/**/*.ts',
85
- 'lib/public/**/*.tsx',
86
- ], gulp.parallel(
87
- testLib(),
88
- checkTsLib(),
89
- buildPublicLib(taskOptions),
90
- )
91
- );
92
- }
93
-
94
49
  export function watchPages() {
95
50
  return gulp.watch('typescript/pages/**/*.ts',
96
51
  gulp.parallel(
97
- checkTs(),
52
+ checkTs(taskOptions),
98
53
  buildPages(taskOptions),
99
54
  )
100
55
  );
@@ -102,42 +57,23 @@ export function watchPages() {
102
57
 
103
58
  export function watchFiles() {
104
59
  return gulp.watch([
105
- 'typescript/backend/**/*',
106
- 'typescript/public/**/*',
107
- 'typescript/pages/**/*',
108
- '!typescript/**/*.ts',
60
+ '*/backend/**/*',
61
+ '*/public/**/*',
62
+ '*/pages/**/*',
63
+ '!*/**/*.ts',
64
+ '!*/**/*.tsx',
109
65
  ], gulp.parallel(copyFiles(taskOptions)));
110
66
  }
111
67
 
112
- export function watchFilesLib() {
113
- return gulp.watch([
114
- 'lib/backend/**/*',
115
- 'lib/public/**/*',
116
- 'lib/pages/**/*',
117
- '!lib/**/*.ts',
118
- ], gulp.parallel(copyFilesLib(taskOptions)));
119
- }
120
-
121
68
  export function watchTemplates() {
122
69
  return gulp.watch([
123
- 'typescript/backend/templates/**/*.tsx',
124
- 'typescript/backend/templates/data/*.json',
125
- '!typescript/backend/templates/render.ts',
126
- ], gulp.parallel(
127
- previewTemplates(),
128
- test()
129
- )
130
- );
131
- }
132
-
133
- export function watchTemplatesLib() {
134
- return gulp.watch([
135
- 'lib/backend/templates/**/*.tsx',
136
- 'lib/backend/templates/data/*.json',
137
- '!lib/backend/templates/render.ts',
70
+ '*/backend/templates/**/*.tsx',
71
+ '*/backend/templates/data/*.json',
72
+ '!*/backend/templates/render.ts',
138
73
  ], gulp.parallel(
139
- previewTemplatesLib(),
140
- testLib(),
74
+ previewTemplates(taskOptions),
75
+ test(taskOptions),
76
+ checkTs(taskOptions),
141
77
  )
142
78
  );
143
79
  }
@@ -160,16 +96,10 @@ export function watchAll(options: TaskOptions) {
160
96
  return gulp.parallel(
161
97
  watchSCSS,
162
98
  watchBackend,
163
- watchBackendLib,
164
- watchJSW,
165
- watchJSWLib,
166
99
  watchPublic,
167
- watchPublicLib,
168
100
  watchPages,
169
- watchFilesLib,
170
101
  watchFiles,
171
102
  watchTemplates,
172
- watchTemplatesLib,
173
103
  watchTypes,
174
104
  );
175
105
  }
package/src/helpers.ts CHANGED
@@ -7,6 +7,7 @@ import { spawnSync } from 'child_process';
7
7
  import path from 'path';
8
8
  import { fileURLToPath } from 'url';
9
9
  import { ModuleSettings, ProjectSettings } from '.';
10
+ import { exec } from 'child_process';
10
11
 
11
12
  import { blue, green, orange, red } from './index.js';
12
13
 
@@ -76,4 +77,25 @@ export async function runGulp(moduleSettings: ModuleSettings, projectSettings: P
76
77
 
77
78
  // Check if 'dev' task exists
78
79
  gulpfile.runTask(task, moduleSettings, projectSettings)
79
- }
80
+ }
81
+
82
+
83
+ /**
84
+ * Clean up and run a command before exiting the process.
85
+ */
86
+ export function handleExit() {
87
+ const cwd = process.cwd();
88
+ const command = `watchman watch-del '${cwd}'`;
89
+
90
+ console.log("🐕" + blue.underline(' => Cleaning up...'));
91
+ exec(command, (error, stdout, stderr) => {
92
+ if (error) {
93
+ console.error(`💩 Failed to run cleanup: ${error.message}`);
94
+ return;
95
+ }
96
+ if (stderr) {
97
+ console.error(`⚠️ Watchman stderr: ${stderr}`);
98
+ }
99
+ console.log(`✅ Watchman cleanup success: ${stdout}`);
100
+ });
101
+ }
package/src/index.ts CHANGED
@@ -11,7 +11,7 @@ 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 } from './helpers.js';
14
+ import { runGulp, installPackages, handleExit } from './helpers.js';
15
15
  import { prepare } from './prepare.js';
16
16
 
17
17
  export type LucySettings = {
@@ -70,6 +70,11 @@ const __filename = fileURLToPath(import.meta.url);
70
70
  // eslint-disable-next-line @typescript-eslint/naming-convention
71
71
  const __dirname = dirname(__filename);
72
72
 
73
+ process.on('SIGINT', () => {
74
+ console.log("🐕 Received Ctrl+C, cleaning up...");
75
+ handleExit();
76
+ process.exit(); // Exit the process explicitly
77
+ });
73
78
 
74
79
  /**
75
80
  * Main function
@@ -169,6 +174,7 @@ async function main(): Promise<void> {
169
174
 
170
175
  if(moduleSettings.args.includes('-l')) moduleSettings.lockVersion = true;
171
176
 
177
+ console.log("🐕" + magenta.underline(' => Lucy CLI => RUNNING: ' + orange('Press Ctrl+C to stop.')));
172
178
  // INFO: Run commands
173
179
  if(moduleSettings.args.includes('init')){
174
180
  if(projectSettings.lucySettings?.initialized && !moduleSettings.force) {
package/src/models.ts ADDED
@@ -0,0 +1,35 @@
1
+ export type TSConfig = {
2
+ compilerOptions?: {
3
+ target?: string; // e.g., "ES5", "ES6", "ES2015", "ESNext"
4
+ module?: string; // e.g., "CommonJS", "ES6", "ESNext"
5
+ lib?: string[]; // e.g., ["ES2015", "DOM"]
6
+ outDir?: string;
7
+ rootDir?: string;
8
+ strict?: boolean;
9
+ esModuleInterop?: boolean;
10
+ allowJs?: boolean;
11
+ checkJs?: boolean;
12
+ declaration?: boolean;
13
+ declarationMap?: boolean;
14
+ sourceMap?: boolean;
15
+ removeComments?: boolean;
16
+ noImplicitAny?: boolean;
17
+ moduleResolution?: "node" | "classic";
18
+ resolveJsonModule?: boolean;
19
+ skipLibCheck?: boolean;
20
+ types?: string[]; // e.g., ["node", "jest"]
21
+ typeRoots?: string[]; // e.g., ["./types"]
22
+ jsx?: "preserve" | "react" | "react-jsx" | "react-jsxdev" | "react-native";
23
+ incremental?: boolean;
24
+ noEmit?: boolean;
25
+ paths?: Record<string, string[]>; // Aliases for module paths
26
+ [key: string]: any; // Allow additional compiler options
27
+ };
28
+ include?: string[]; // Glob patterns to include
29
+ exclude?: string[]; // Glob patterns to exclude
30
+ files?: string[]; // Specific files to include
31
+ extends?: string; // Path to a base tsconfig.json
32
+ references?: { path: string }[]; // Project references
33
+ compileOnSave?: boolean;
34
+ [key: string]: any; // Allow additional top-level options
35
+ };