@nlabs/lex 1.48.6 → 1.49.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 (107) hide show
  1. package/.storybook/main.ts +9 -2
  2. package/.vscode/settings.json +1 -6
  3. package/README.md +276 -4
  4. package/eslint.config.mjs +24 -0
  5. package/examples/lex.config.js +18 -8
  6. package/examples/serverless-example/README.md +109 -0
  7. package/examples/serverless-example/dist/handlers/echo.js +15 -0
  8. package/examples/serverless-example/dist/handlers/graphql.js +137 -0
  9. package/examples/serverless-example/dist/handlers/hello.js +15 -0
  10. package/examples/serverless-example/dist/handlers/test.js +17 -0
  11. package/examples/serverless-example/dist/handlers/websocket.js +14 -0
  12. package/examples/serverless-example/lex.config.mjs +74 -0
  13. package/jest.config.mjs +13 -12
  14. package/{dist → lib}/LexConfig.d.ts +14 -6
  15. package/lib/LexConfig.js +268 -0
  16. package/lib/commands/ai/ai.js +303 -0
  17. package/{dist → lib}/commands/build/build.d.ts +3 -0
  18. package/lib/commands/build/build.js +494 -0
  19. package/{dist → lib}/commands/clean/clean.js +1 -1
  20. package/lib/commands/compile/compile.js +241 -0
  21. package/lib/commands/copy/copy.js +38 -0
  22. package/{dist → lib}/commands/create/create.js +1 -1
  23. package/{dist → lib}/commands/dev/dev.d.ts +2 -0
  24. package/lib/commands/dev/dev.js +286 -0
  25. package/{dist → lib}/commands/init/init.js +1 -1
  26. package/{dist → lib}/commands/lint/lint.d.ts +4 -1
  27. package/lib/commands/lint/lint.js +993 -0
  28. package/{dist → lib}/commands/migrate/migrate.js +1 -1
  29. package/lib/commands/publish/publish.js +104 -0
  30. package/lib/commands/serverless/serverless.d.ts +17 -0
  31. package/lib/commands/serverless/serverless.js +662 -0
  32. package/lib/commands/storybook/storybook.js +249 -0
  33. package/lib/commands/test/test.js +428 -0
  34. package/lib/commands/update/update.js +128 -0
  35. package/lib/commands/versions/versions.js +41 -0
  36. package/{dist → lib}/create/changelog.js +1 -1
  37. package/{dist → lib}/index.d.ts +2 -0
  38. package/{dist → lib}/index.js +3 -1
  39. package/lib/lex.js +73 -0
  40. package/lib/storybook/index.d.ts +5 -0
  41. package/lib/types.js +1 -0
  42. package/lib/utils/aiService.d.ts +9 -0
  43. package/lib/utils/aiService.js +299 -0
  44. package/{dist → lib}/utils/app.d.ts +3 -0
  45. package/lib/utils/app.js +296 -0
  46. package/lib/utils/deepMerge.js +26 -0
  47. package/{dist → lib}/utils/file.d.ts +7 -3
  48. package/lib/utils/file.js +229 -0
  49. package/lib/utils/translations.d.ts +1 -0
  50. package/lib/utils/translations.js +74 -0
  51. package/package.json +62 -50
  52. package/postcss.config.js +5 -3
  53. package/tsconfig.build.json +2 -2
  54. package/webpack.config.js +229 -39
  55. package/dist/LexConfig.js +0 -286
  56. package/dist/commands/ai/ai.js +0 -303
  57. package/dist/commands/build/build.js +0 -404
  58. package/dist/commands/compile/compile.js +0 -234
  59. package/dist/commands/copy/copy.js +0 -38
  60. package/dist/commands/dev/dev.js +0 -74
  61. package/dist/commands/lint/lint.js +0 -811
  62. package/dist/commands/publish/publish.js +0 -104
  63. package/dist/commands/storybook/storybook.js +0 -249
  64. package/dist/commands/test/test.js +0 -429
  65. package/dist/commands/update/update.js +0 -132
  66. package/dist/commands/versions/versions.js +0 -41
  67. package/dist/lex.js +0 -70
  68. package/dist/utils/aiService.d.ts +0 -9
  69. package/dist/utils/aiService.js +0 -299
  70. package/dist/utils/app.js +0 -267
  71. package/dist/utils/deepMerge.js +0 -24
  72. package/dist/utils/file.js +0 -185
  73. package/emptyModule.js +0 -0
  74. package/eslint.config.js +0 -7
  75. /package/{dist → lib}/Button.stories.d.ts +0 -0
  76. /package/{dist → lib}/commands/ai/ai.d.ts +0 -0
  77. /package/{dist → lib}/commands/ai/index.d.ts +0 -0
  78. /package/{dist → lib}/commands/ai/index.js +0 -0
  79. /package/{dist → lib}/commands/clean/clean.d.ts +0 -0
  80. /package/{dist → lib}/commands/compile/compile.d.ts +0 -0
  81. /package/{dist → lib}/commands/config/config.d.ts +0 -0
  82. /package/{dist → lib}/commands/config/config.js +0 -0
  83. /package/{dist → lib}/commands/copy/copy.d.ts +0 -0
  84. /package/{dist → lib}/commands/create/create.d.ts +0 -0
  85. /package/{dist → lib}/commands/init/init.d.ts +0 -0
  86. /package/{dist → lib}/commands/link/link.d.ts +0 -0
  87. /package/{dist → lib}/commands/link/link.js +0 -0
  88. /package/{dist → lib}/commands/lint/autofix.d.ts +0 -0
  89. /package/{dist → lib}/commands/migrate/migrate.d.ts +0 -0
  90. /package/{dist → lib}/commands/publish/publish.d.ts +0 -0
  91. /package/{dist → lib}/commands/storybook/storybook.d.ts +0 -0
  92. /package/{dist → lib}/commands/test/test.d.ts +0 -0
  93. /package/{dist → lib}/commands/update/update.d.ts +0 -0
  94. /package/{dist → lib}/commands/upgrade/upgrade.d.ts +0 -0
  95. /package/{dist → lib}/commands/upgrade/upgrade.js +0 -0
  96. /package/{dist → lib}/commands/versions/versions.d.ts +0 -0
  97. /package/{dist → lib}/create/changelog.d.ts +0 -0
  98. /package/{dist → lib}/lex.d.ts +0 -0
  99. /package/{dist/types.js → lib/storybook/index.js} +0 -0
  100. /package/{dist → lib}/test-react/index.d.ts +0 -0
  101. /package/{dist → lib}/test-react/index.js +0 -0
  102. /package/{dist → lib}/types.d.ts +0 -0
  103. /package/{dist → lib}/utils/deepMerge.d.ts +0 -0
  104. /package/{dist → lib}/utils/log.d.ts +0 -0
  105. /package/{dist → lib}/utils/log.js +0 -0
  106. /package/{dist → lib}/utils/reactShim.d.ts +0 -0
  107. /package/{dist → lib}/utils/reactShim.js +0 -0
package/webpack.config.js CHANGED
@@ -53,19 +53,54 @@ const {
53
53
  webpack: webpackCustom
54
54
  } = lexConfig;
55
55
 
56
- // Only add plugins if they are needed
56
+ const webpackPublicPath = webpackCustom?.publicPath || './src/static';
57
+
58
+ const { publicPath: _, ...webpackConfigFiltered } = webpackCustom || {};
59
+
57
60
  const plugins = [
58
61
  new ProgressPlugin({
59
62
  activeModules: false,
60
63
  entries: true,
64
+ handler(percentage, message, ...args) {
65
+ // custom logic
66
+ },
61
67
  modules: true,
68
+ modulesCount: 5000,
69
+ profile: false,
62
70
  dependencies: true,
71
+ dependenciesCount: 10000,
63
72
  percentBy: null
64
73
  }),
65
74
  new DotenvPlugin({
75
+ allowEmptyValues: true,
66
76
  path: pathResolve(process.cwd(), '.env'),
67
- systemvars: false
68
- })
77
+ safe: false,
78
+ silent: true,
79
+ systemvars: true
80
+ }),
81
+ new webpack.ProvidePlugin({
82
+ Buffer: ['buffer', 'Buffer'],
83
+ process: 'process/browser',
84
+ global: 'global'
85
+ }),
86
+ new webpack.DefinePlugin({
87
+ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
88
+ 'global': 'global'
89
+ }),
90
+ {
91
+ apply: (compiler) => {
92
+ compiler.hooks.watchRun.tap('NotifyOnRebuild', () => {
93
+ console.log('\x1b[36m[webpack]\x1b[0m Detected file change. Rebuilding...');
94
+ });
95
+ compiler.hooks.done.tap('NotifyOnRebuild', (stats) => {
96
+ if (stats.hasErrors()) {
97
+ console.log('\x1b[31m[webpack]\x1b[0m Build failed with errors.');
98
+ } else {
99
+ console.log('\x1b[32m[webpack]\x1b[0m Build complete. Watching for changes...');
100
+ }
101
+ });
102
+ }
103
+ }
69
104
  ];
70
105
 
71
106
  const isWeb = (preset || targetEnvironment) === 'web';
@@ -76,12 +111,12 @@ if(isWeb) {
76
111
  new CompressionWebpackPlugin({algorithm: 'gzip'}),
77
112
  new ProvidePlugin({
78
113
  process: 'process/browser',
114
+ global: 'global',
79
115
  React: pathResolve(dirName, './node_modules/react')
80
116
  })
81
117
  );
82
118
  }
83
119
 
84
- // Add svg files
85
120
  const globOptions = {
86
121
  cwd: sourceFullPath,
87
122
  dot: false,
@@ -108,7 +143,6 @@ if(globSync(svgPaths, globOptions).length) {
108
143
  );
109
144
  }
110
145
 
111
- // If there is are static directories, make sure we copy the files over
112
146
  const staticPaths = [];
113
147
  const watchIgnorePaths = [
114
148
  `${sourceFullPath}/**/**.gif`,
@@ -119,6 +153,15 @@ const imagePath = `${sourceFullPath}/images/`;
119
153
  const fontPath = `${sourceFullPath}/fonts/`;
120
154
  const docPath = `${sourceFullPath}/docs/`;
121
155
 
156
+ const publicPathFull = pathResolve(process.cwd(), webpackPublicPath);
157
+ if(existsSync(publicPathFull)) {
158
+ staticPaths.push({
159
+ from: publicPathFull,
160
+ to: './'
161
+ });
162
+ watchIgnorePaths.push(publicPathFull);
163
+ }
164
+
122
165
  if(existsSync(imagePath)) {
123
166
  staticPaths.push({from: imagePath, to: './images/'});
124
167
  watchIgnorePaths.push(imagePath);
@@ -144,9 +187,33 @@ if(existsSync(`${sourceFullPath}/${lexConfig.entryHTML}`)) {
144
187
  minify: isProduction,
145
188
  scriptLoading: 'defer',
146
189
  showErrors: !isProduction,
147
- template: `${sourceFullPath}/${lexConfig.entryHTML}`
190
+ template: `${sourceFullPath}/${lexConfig.entryHTML}`,
191
+ inject: true
148
192
  })
149
193
  );
194
+
195
+ const missingAssets = [];
196
+ const requiredAssets = ['favicon.ico', 'images/logo-icon-64.png', 'manifest.json'];
197
+
198
+ requiredAssets.forEach(asset => {
199
+ if (!existsSync(`${sourceFullPath}/${asset}`)) {
200
+ missingAssets.push(asset);
201
+ }
202
+ });
203
+
204
+ if (missingAssets.length > 0) {
205
+ plugins.push(
206
+ new CopyWebpackPlugin({
207
+ patterns: missingAssets.map(asset => ({
208
+ from: pathResolve(dirName, 'emptyModule.js'),
209
+ to: `${outputFullPath}/${asset}`,
210
+ transform() {
211
+ return '';
212
+ }
213
+ }))
214
+ })
215
+ );
216
+ }
150
217
  }
151
218
 
152
219
  let outputFilename = outputFile;
@@ -166,29 +233,25 @@ if(existsSync(`${sourceFullPath}/tsconfig.json`)) {
166
233
  }));
167
234
  }
168
235
 
169
- // Loader paths
170
236
  const esbuildLoaderPath = relativeNodePath('esbuild-loader', dirName);
171
237
  const cssLoaderPath = relativeNodePath('css-loader', dirName);
172
238
  const graphqlLoaderPath = relativeNodePath('graphql-tag/loader', dirName);
173
239
  const htmlLoaderPath = relativeNodePath('html-loader', dirName);
174
240
  const postcssLoaderPath = relativeNodePath('postcss-loader', dirName);
175
- const sourceMapLoaderPath = relativeNodePath('source-map-loader', dirName);
241
+ const sourceMapLoaderPath = pathResolve(dirName, 'node_modules/source-map-loader');
176
242
  const styleLoaderPath = relativeNodePath('style-loader', dirName);
177
243
  const webpackPath = relativeNodePath('webpack', dirName);
178
244
 
179
- // Aliases
180
245
  const aliasPaths = {
181
246
  '@nlabs/arkhamjs': relativeNodePath('@nlabs/arkhamjs', process.cwd()),
182
- '@nlabs/arkhamjs-utils-react': relativeNodePath(
183
- '@nlabs/arkhamjs-utils-react',
184
- process.cwd()
185
- ),
186
- '@nlabs/utils': '/Users/nitrog7/.nvm/versions/node/v22.14.0/lib/node_modules/@nlabs/utils',
247
+ '@nlabs/arkhamjs-utils-react': relativeNodePath('@nlabs/arkhamjs-utils-react', process.cwd()),
248
+ 'buffer': relativeNodePath('buffer', dirName),
187
249
  'core-js': relativeNodePath('core-js', dirName),
188
250
  process: relativeNodePath('process', dirName),
189
251
  react: relativeNodePath('react', process.cwd()),
190
252
  'react-dom': relativeNodePath('react-dom', process.cwd()),
191
- 'regenerator-runtime': relativeNodePath('regenerator-runtime', dirName)
253
+ 'regenerator-runtime': relativeNodePath('regenerator-runtime', dirName),
254
+ 'Buffer': relativeNodePath('buffer', dirName)
192
255
  };
193
256
  const aliasKeys = Object.keys(aliasPaths);
194
257
  const alias = aliasKeys.reduce((aliases, key) => {
@@ -199,18 +262,36 @@ const alias = aliasKeys.reduce((aliases, key) => {
199
262
  return aliases;
200
263
  }, {});
201
264
 
202
- // Webpack config
203
265
  export default (webpackEnv, webpackOptions) => {
204
- const {bundleAnalyzer, watch} = webpackOptions;
266
+ const {bundleAnalyzer, watch, entry: cliEntry, mode: cliMode} = webpackOptions;
267
+ const entryValue = Array.isArray(cliEntry) ? cliEntry[0] : cliEntry;
268
+
269
+ // Debug printout for environment and mode
270
+ console.log('[Lex Webpack] NODE_ENV:', process.env.NODE_ENV);
271
+ console.log('[Lex Webpack] isProduction:', isProduction);
272
+ console.log('[Lex Webpack] cliMode:', cliMode);
273
+
205
274
  const webpackConfig = {
206
275
  bail: true,
207
276
  cache: !isProduction,
208
277
  devtool: isProduction
209
278
  ? 'inline-cheap-module-source-map'
210
279
  : 'eval-cheap-module-source-map',
211
- entry: {
212
- index: `${sourceFullPath}/${lexConfig.entryJs}`
213
- },
280
+ entry: entryValue
281
+ ? {
282
+ index: [
283
+ 'buffer',
284
+ 'process/browser',
285
+ entryValue
286
+ ]
287
+ }
288
+ : {
289
+ index: [
290
+ 'buffer',
291
+ 'process/browser',
292
+ `${sourceFullPath}/${lexConfig.entryJs}`
293
+ ]
294
+ },
214
295
  externals: isReactNative ? {'react-native': true} : undefined,
215
296
  ignoreWarnings: [/Failed to parse source map/],
216
297
  mode: isProduction ? 'production' : 'development',
@@ -252,13 +333,38 @@ export default (webpackEnv, webpackOptions) => {
252
333
  test: /\.(ts|tsx|js)$/
253
334
  },
254
335
  {
255
- exclude: /(node_modules)/,
336
+ exclude: [pathResolve(sourceFullPath, lexConfig.entryHTML)],
256
337
  include: sourceFullPath,
257
338
  test: /\.html$/,
258
339
  use: [
259
340
  {
260
341
  loader: htmlLoaderPath,
261
- options: {minimize: isProduction}
342
+ options: {
343
+ minimize: isProduction,
344
+ sources: {
345
+ list: [
346
+ '...',
347
+ {
348
+ tag: 'link',
349
+ attribute: 'href',
350
+ type: 'src',
351
+ filter: (tag, attribute, attributes) => {
352
+ const href = attributes[attribute];
353
+ return !href || !href.match(/\.(ico|png|jpg|jpeg|gif|svg|json)$/);
354
+ }
355
+ },
356
+ {
357
+ tag: 'script',
358
+ attribute: 'src',
359
+ type: 'src',
360
+ filter: (tag, attribute, attributes) => {
361
+ const src = attributes[attribute];
362
+ return !src || !src.match(/\.(ico|png|jpg|jpeg|gif|svg|json)$/);
363
+ }
364
+ }
365
+ ]
366
+ }
367
+ }
262
368
  }
263
369
  ]
264
370
  },
@@ -277,7 +383,10 @@ export default (webpackEnv, webpackOptions) => {
277
383
  options: {
278
384
  postcssOptions: {
279
385
  plugins: [
280
- postcssImport({addDependencyTo: webpack}),
386
+ postcssImport({
387
+ addDependencyTo: webpack,
388
+ path: [relativeNodePath('', dirName)]
389
+ }),
281
390
  postcssUrl(),
282
391
  postcssFor(),
283
392
  postcssPercentage({
@@ -295,14 +404,14 @@ export default (webpackEnv, webpackOptions) => {
295
404
  strict: false,
296
405
  warnings: false
297
406
  }),
407
+ postcssNesting(),
298
408
  tailwindcss(),
299
409
  autoprefixer(),
300
- postcssNesting(),
301
410
  postcssFlexbugsFixes(),
302
411
  postcssPresetEnv({
303
412
  stage: 0
304
413
  }),
305
- cssnano({autoprefixer: false}),
414
+ ...(isProduction ? [cssnano({autoprefixer: false})] : []),
306
415
  postcssBrowserReporter()
307
416
  ]
308
417
  }
@@ -312,7 +421,7 @@ export default (webpackEnv, webpackOptions) => {
312
421
  loader: esbuildLoaderPath,
313
422
  options: {
314
423
  loader: 'css',
315
- minify: true
424
+ minify: isProduction
316
425
  }
317
426
  }
318
427
  ]
@@ -323,6 +432,49 @@ export default (webpackEnv, webpackOptions) => {
323
432
  test: /\.(gif|jpg|png|svg)$/,
324
433
  type: 'asset/resource'
325
434
  },
435
+ {
436
+ test: /\.(jpg|jpeg|png|gif|webp|svg|mp4|webm|ogg|mp3|wav|flac|aac)$/,
437
+ include: publicPathFull,
438
+ type: 'asset/resource',
439
+ generator: {
440
+ filename: '[name].[hash][ext]'
441
+ },
442
+ use: isProduction ? [
443
+ {
444
+ loader: 'image-webpack-loader',
445
+ options: {
446
+ mozjpeg: {
447
+ progressive: true,
448
+ quality: 65
449
+ },
450
+ optipng: {
451
+ enabled: false
452
+ },
453
+ pngquant: {
454
+ quality: [0.65, 0.90],
455
+ speed: 4
456
+ },
457
+ gifsicle: {
458
+ interlaced: false
459
+ },
460
+ webp: {
461
+ quality: 75
462
+ }
463
+ }
464
+ }
465
+ ] : []
466
+ },
467
+ {
468
+ test: /\.json$/,
469
+ type: 'json'
470
+ },
471
+ {
472
+ test: /\.ico$/,
473
+ type: 'asset/resource',
474
+ generator: {
475
+ filename: '[name][ext]'
476
+ }
477
+ },
326
478
  {
327
479
  exclude: /(node_modules)/,
328
480
  include: sourceFullPath,
@@ -379,15 +531,17 @@ export default (webpackEnv, webpackOptions) => {
379
531
  fallback: {
380
532
  assert: relativeNodePath('assert', dirName),
381
533
  buffer: relativeNodePath('buffer', dirName),
382
- crypto: relativeNodePath('crypto-browserify', dirName),
534
+ crypto: relativeNodePath('crypto-js', dirName),
383
535
  http: relativeNodePath('stream-http', dirName),
384
536
  https: relativeNodePath('https-browserify', dirName),
385
537
  os: relativeNodePath('os-browserify/browser.js', dirName),
386
538
  path: relativeNodePath('path-browserify', dirName),
387
539
  process: relativeNodePath('process/browser.js', dirName),
540
+ randombytes: relativeNodePath('randombytes', dirName),
388
541
  stream: relativeNodePath('stream-browserify', dirName),
389
542
  util: relativeNodePath('util', dirName),
390
- vm: relativeNodePath('vm-browserify', dirName)
543
+ vm: relativeNodePath('vm-browserify', dirName),
544
+ Buffer: relativeNodePath('buffer', dirName)
391
545
  },
392
546
  mainFiles: ['index'],
393
547
  modules: [sourceFullPath, 'node_modules', relativeNodePath('', dirName), '/Users/nitrog7/.nvm/versions/node/v22.14.0/lib/node_modules'],
@@ -399,7 +553,6 @@ export default (webpackEnv, webpackOptions) => {
399
553
  target: isWeb ? 'web' : 'node'
400
554
  };
401
555
 
402
- // Add development plugins
403
556
  if(!isProduction) {
404
557
  webpackConfig.resolve.alias = {
405
558
  ...webpackConfig.resolve.alias,
@@ -422,13 +575,10 @@ export default (webpackEnv, webpackOptions) => {
422
575
  index: '/index.html',
423
576
  logger: console.log.bind(console),
424
577
  rewrites: [
425
- // wps
426
578
  {
427
579
  from: '/wps',
428
580
  to: ({parsedUrl: {pathname}}) => pathname
429
581
  },
430
-
431
- // Javascript files
432
582
  {
433
583
  from: /\.js/,
434
584
  to: ({parsedUrl: {pathname}}) => {
@@ -437,8 +587,6 @@ export default (webpackEnv, webpackOptions) => {
437
587
  return `/${pathUrl[fileIndex]}`;
438
588
  }
439
589
  },
440
-
441
- // Static files
442
590
  {
443
591
  from: /\.[css,gif,ico,jpg,json,png,svg]/,
444
592
  to: ({parsedUrl: {pathname}}) => pathname
@@ -460,7 +608,7 @@ export default (webpackEnv, webpackOptions) => {
460
608
  open: process.env.WEBPACK_DEV_OPEN === 'true',
461
609
  port: 7001,
462
610
  progress: 'minimal',
463
- static: [outputFullPath],
611
+ static: existsSync(outputFullPath) ? [outputFullPath] : [],
464
612
  status: true
465
613
  })
466
614
  );
@@ -473,14 +621,12 @@ export default (webpackEnv, webpackOptions) => {
473
621
 
474
622
  if(watch) {
475
623
  webpackConfig.bail = false;
476
- // webpackConfig.watch = true;
477
624
  webpackConfig.watchOptions = {
478
625
  aggregateTimeout: 500,
479
626
  ignored: ['node_modules/**', ...watchIgnorePaths]
480
627
  };
481
628
  }
482
629
  } else {
483
- // Create site ico files
484
630
  const siteLogo = `${sourceFullPath}/images/logo.png`;
485
631
 
486
632
  if(existsSync(siteLogo)) {
@@ -514,5 +660,49 @@ export default (webpackEnv, webpackOptions) => {
514
660
  }
515
661
  }
516
662
 
517
- return merge(webpackConfig, webpackCustom);
518
- };
663
+ if (process.env.LEX_CONFIG_DEBUG) {
664
+ console.log('\n\x1b[36m[LEX_CONFIG_DEBUG] Webpack mode:', process.env.NODE_ENV, 'isProduction:', isProduction, '\x1b[0m');
665
+ if (webpackConfig && webpackConfig.module && Array.isArray(webpackConfig.module.rules)) {
666
+ console.log('\x1b[36m[LEX_CONFIG_DEBUG] Loader chains:\x1b[0m');
667
+ webpackConfig.module.rules.forEach((rule, idx) => {
668
+ if (rule.test) {
669
+ let testStr = rule.test.toString();
670
+ let use = rule.use || rule.loader || rule.type;
671
+ if (Array.isArray(use)) {
672
+ use = use.map(u => (typeof u === 'string' ? u : u.loader || u.type)).join(' -> ');
673
+ } else if (typeof use === 'object' && use !== null) {
674
+ use = use.loader || use.type;
675
+ }
676
+ console.log(` [${idx}] ${testStr}: ${use}`);
677
+ }
678
+ });
679
+ }
680
+
681
+ if (webpackConfig && Array.isArray(webpackConfig.plugins)) {
682
+ console.log('\x1b[36m[LEX_CONFIG_DEBUG] Plugins:\x1b[0m');
683
+ webpackConfig.plugins.forEach((plugin, idx) => {
684
+ let name = plugin.constructor && plugin.constructor.name;
685
+ if (!name && typeof plugin === 'object' && plugin.apply) name = 'CustomPlugin';
686
+ if (!name && typeof plugin === 'function') name = 'FunctionPlugin';
687
+ console.log(` [${idx}] ${name}`);
688
+ });
689
+ }
690
+
691
+ if (webpackConfig && webpackConfig.module && Array.isArray(webpackConfig.module.rules)) {
692
+ const cssRule = webpackConfig.module.rules.find(rule => rule.test && rule.test.toString().includes('css'));
693
+ if (cssRule) {
694
+ let use = cssRule.use || cssRule.loader || cssRule.type;
695
+ if (Array.isArray(use)) {
696
+ use = use.map(u => (typeof u === 'string' ? u : u.loader || u.type)).join(' -> ');
697
+ } else if (typeof use === 'object' && use !== null) {
698
+ use = use.loader || use.type;
699
+ }
700
+ console.log('\x1b[36m[LEX_CONFIG_DEBUG] CSS Loader Chain:\x1b[0m', use);
701
+ } else {
702
+ console.log('\x1b[36m[LEX_CONFIG_DEBUG] No CSS loader rule found.\x1b[0m');
703
+ }
704
+ }
705
+ }
706
+
707
+ return merge(webpackConfig, webpackConfigFiltered);
708
+ };