@servicetitan/startup 31.0.0 → 31.2.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 (159) hide show
  1. package/bin/index.js +8 -0
  2. package/dist/cli/commands/build.d.ts.map +1 -1
  3. package/dist/cli/commands/build.js +1 -7
  4. package/dist/cli/commands/build.js.map +1 -1
  5. package/dist/cli/commands/prepare-package.d.ts +1 -2
  6. package/dist/cli/commands/prepare-package.d.ts.map +1 -1
  7. package/dist/cli/commands/prepare-package.js +4 -6
  8. package/dist/cli/commands/prepare-package.js.map +1 -1
  9. package/dist/cli/commands/run-task.test.js +59 -0
  10. package/dist/cli/commands/run-task.test.js.map +1 -0
  11. package/dist/cli/commands/start.d.ts.map +1 -1
  12. package/dist/cli/commands/start.js +2 -11
  13. package/dist/cli/commands/start.js.map +1 -1
  14. package/dist/cli/tasks/swc-cli.d.js +3 -0
  15. package/dist/cli/tasks/swc-cli.d.js.map +1 -0
  16. package/dist/cli/tasks/swc-compile-package.d.ts.map +1 -1
  17. package/dist/cli/tasks/swc-compile-package.js +22 -19
  18. package/dist/cli/tasks/swc-compile-package.js.map +1 -1
  19. package/dist/cli/types/cpx2.d.js +3 -0
  20. package/dist/cli/types/cpx2.d.js.map +1 -0
  21. package/dist/cli/utils/bundle.d.ts +2 -2
  22. package/dist/cli/utils/bundle.d.ts.map +1 -1
  23. package/dist/cli/utils/bundle.js +18 -4
  24. package/dist/cli/utils/bundle.js.map +1 -1
  25. package/dist/cli/utils/copy-files.d.ts +1 -1
  26. package/dist/cli/utils/copy-files.d.ts.map +1 -1
  27. package/dist/cli/utils/copy-files.js +18 -11
  28. package/dist/cli/utils/copy-files.js.map +1 -1
  29. package/dist/cli/utils/get-module-type.d.ts.map +1 -1
  30. package/dist/cli/utils/get-module-type.js +2 -16
  31. package/dist/cli/utils/get-module-type.js.map +1 -1
  32. package/dist/cli/utils/index.d.ts +1 -1
  33. package/dist/cli/utils/index.d.ts.map +1 -1
  34. package/dist/cli/utils/index.js +1 -1
  35. package/dist/cli/utils/index.js.map +1 -1
  36. package/dist/cli/utils/ts-config.d.ts +11 -0
  37. package/dist/cli/utils/ts-config.d.ts.map +1 -0
  38. package/dist/cli/utils/ts-config.js +80 -0
  39. package/dist/cli/utils/ts-config.js.map +1 -0
  40. package/dist/utils/get-configuration.d.ts +1 -0
  41. package/dist/utils/get-configuration.d.ts.map +1 -1
  42. package/dist/utils/get-configuration.js +14 -0
  43. package/dist/utils/get-configuration.js.map +1 -1
  44. package/dist/utils/log.d.ts +1 -0
  45. package/dist/utils/log.d.ts.map +1 -1
  46. package/dist/utils/log.js +9 -0
  47. package/dist/utils/log.js.map +1 -1
  48. package/dist/webpack/configs/dev-server-config.d.ts.map +1 -1
  49. package/dist/webpack/configs/dev-server-config.js +11 -0
  50. package/dist/webpack/configs/dev-server-config.js.map +1 -1
  51. package/dist/webpack/configs/index.d.ts +0 -1
  52. package/dist/webpack/configs/index.d.ts.map +1 -1
  53. package/dist/webpack/configs/index.js +0 -1
  54. package/dist/webpack/configs/index.js.map +1 -1
  55. package/dist/webpack/configs/optimization-config.js +6 -6
  56. package/dist/webpack/configs/optimization-config.js.map +1 -1
  57. package/dist/webpack/configs/output-config.d.ts.map +1 -1
  58. package/dist/webpack/configs/output-config.js +3 -2
  59. package/dist/webpack/configs/output-config.js.map +1 -1
  60. package/dist/webpack/configs/plugins/html-plugin.d.ts +1 -1
  61. package/dist/webpack/configs/plugins/html-plugin.d.ts.map +1 -1
  62. package/dist/webpack/configs/plugins/html-plugin.js +2 -2
  63. package/dist/webpack/configs/plugins/html-plugin.js.map +1 -1
  64. package/dist/webpack/configs/plugins/virtual-modules-plugin.js +14 -4
  65. package/dist/webpack/configs/plugins/virtual-modules-plugin.js.map +1 -1
  66. package/dist/webpack/configs/utils/generate-metadata.d.ts.map +1 -1
  67. package/dist/webpack/configs/utils/generate-metadata.js +4 -0
  68. package/dist/webpack/configs/utils/generate-metadata.js.map +1 -1
  69. package/dist/webpack/create-webpack-config.d.ts.map +1 -1
  70. package/dist/webpack/create-webpack-config.js +0 -1
  71. package/dist/webpack/create-webpack-config.js.map +1 -1
  72. package/dist/webpack/types.d.ts +1 -0
  73. package/dist/webpack/types.d.ts.map +1 -1
  74. package/dist/webpack/utils/index.d.ts +0 -1
  75. package/dist/webpack/utils/index.d.ts.map +1 -1
  76. package/dist/webpack/utils/index.js +0 -1
  77. package/dist/webpack/utils/index.js.map +1 -1
  78. package/package.json +7 -8
  79. package/src/cli/commands/__tests__/build.test.ts +2 -4
  80. package/src/cli/commands/__tests__/prepare-package.test.ts +5 -28
  81. package/src/cli/commands/__tests__/start.test.ts +3 -5
  82. package/src/cli/commands/build.ts +0 -2
  83. package/src/cli/commands/prepare-package.ts +4 -7
  84. package/src/cli/commands/start.ts +1 -3
  85. package/src/cli/tasks/__tests__/swc-compile-package.test.ts +71 -12
  86. package/src/cli/tasks/swc-compile-package.ts +21 -20
  87. package/src/cli/utils/__tests__/bundle.test.ts +48 -7
  88. package/src/cli/utils/__tests__/copy-files.test.ts +5 -5
  89. package/src/cli/utils/bundle.ts +27 -5
  90. package/src/cli/utils/copy-files.ts +16 -6
  91. package/src/cli/utils/get-module-type.ts +2 -18
  92. package/src/cli/utils/index.ts +1 -1
  93. package/src/cli/utils/ts-config.ts +64 -0
  94. package/src/utils/__tests__/get-configuration.test.ts +20 -0
  95. package/src/utils/__tests__/log.test.ts +8 -0
  96. package/src/utils/get-configuration.ts +12 -0
  97. package/src/utils/log.ts +10 -0
  98. package/src/webpack/__tests__/create-webpack-config-shared-dependencies.test.ts +0 -1
  99. package/src/webpack/__tests__/create-webpack-config-web-component.test.ts +17 -28
  100. package/src/webpack/__tests__/create-webpack-config.test.ts +113 -42
  101. package/src/webpack/configs/dev-server-config.ts +13 -1
  102. package/src/webpack/configs/index.ts +0 -1
  103. package/src/webpack/configs/optimization-config.ts +6 -6
  104. package/src/webpack/configs/output-config.ts +4 -2
  105. package/src/webpack/configs/plugins/html-plugin.ts +5 -2
  106. package/src/webpack/configs/plugins/virtual-modules-plugin.ts +15 -2
  107. package/src/webpack/configs/utils/__tests__/generate-metadata.test.ts +3 -1
  108. package/src/webpack/configs/utils/generate-metadata.ts +6 -1
  109. package/src/webpack/create-webpack-config.ts +0 -2
  110. package/src/webpack/types.ts +1 -0
  111. package/src/webpack/utils/index.ts +0 -1
  112. package/dist/__mocks__/create-package.d.ts +0 -3
  113. package/dist/__mocks__/create-package.d.ts.map +0 -1
  114. package/dist/__mocks__/index.d.ts +0 -2
  115. package/dist/__mocks__/index.d.ts.map +0 -1
  116. package/dist/cli/commands/review/__mocks__/expect-calls.d.ts +0 -23
  117. package/dist/cli/commands/review/__mocks__/expect-calls.d.ts.map +0 -1
  118. package/dist/cli/commands/review/__mocks__/index.d.ts +0 -2
  119. package/dist/cli/commands/review/__mocks__/index.d.ts.map +0 -1
  120. package/dist/cli/commands/review/rules/__mocks__/index.d.ts +0 -4
  121. package/dist/cli/commands/review/rules/__mocks__/index.d.ts.map +0 -1
  122. package/dist/cli/commands/review/rules/__mocks__/mock-config.d.ts +0 -7
  123. package/dist/cli/commands/review/rules/__mocks__/mock-config.d.ts.map +0 -1
  124. package/dist/cli/commands/review/rules/__mocks__/mock-packages.d.ts +0 -21
  125. package/dist/cli/commands/review/rules/__mocks__/mock-packages.d.ts.map +0 -1
  126. package/dist/cli/commands/review/rules/__mocks__/mock-project.d.ts +0 -3
  127. package/dist/cli/commands/review/rules/__mocks__/mock-project.d.ts.map +0 -1
  128. package/dist/cli/utils/style-extensions.d.ts +0 -2
  129. package/dist/cli/utils/style-extensions.d.ts.map +0 -1
  130. package/dist/cli/utils/style-extensions.js +0 -17
  131. package/dist/cli/utils/style-extensions.js.map +0 -1
  132. package/dist/cli/utils/tcm.d.ts +0 -6
  133. package/dist/cli/utils/tcm.d.ts.map +0 -1
  134. package/dist/cli/utils/tcm.js +0 -72
  135. package/dist/cli/utils/tcm.js.map +0 -1
  136. package/dist/webpack/__mocks__/file-rules.d.ts +0 -3
  137. package/dist/webpack/__mocks__/file-rules.d.ts.map +0 -1
  138. package/dist/webpack/__mocks__/index.d.ts +0 -3
  139. package/dist/webpack/__mocks__/index.d.ts.map +0 -1
  140. package/dist/webpack/__mocks__/style-rules.d.ts +0 -8
  141. package/dist/webpack/__mocks__/style-rules.d.ts.map +0 -1
  142. package/dist/webpack/configs/cache-config.d.ts +0 -6
  143. package/dist/webpack/configs/cache-config.d.ts.map +0 -1
  144. package/dist/webpack/configs/cache-config.js +0 -34
  145. package/dist/webpack/configs/cache-config.js.map +0 -1
  146. package/dist/webpack/utils/feature-cohort.d.ts +0 -5
  147. package/dist/webpack/utils/feature-cohort.d.ts.map +0 -1
  148. package/dist/webpack/utils/feature-cohort.js +0 -26
  149. package/dist/webpack/utils/feature-cohort.js.map +0 -1
  150. package/dist/webpack/utils/hash-mod.d.ts +0 -9
  151. package/dist/webpack/utils/hash-mod.d.ts.map +0 -1
  152. package/dist/webpack/utils/hash-mod.js +0 -39
  153. package/dist/webpack/utils/hash-mod.js.map +0 -1
  154. package/src/cli/utils/__tests__/tcm.test.ts +0 -195
  155. package/src/cli/utils/style-extensions.ts +0 -1
  156. package/src/cli/utils/tcm.ts +0 -66
  157. package/src/webpack/configs/cache-config.ts +0 -25
  158. package/src/webpack/utils/feature-cohort.ts +0 -19
  159. package/src/webpack/utils/hash-mod.ts +0 -32
@@ -38,7 +38,6 @@ jest.mock('../../utils', () => ({
38
38
  jest.mock('../configs/utils/get-launchdarkly-sdk-version');
39
39
  jest.mock('../utils', () => ({
40
40
  ...jest.requireActual('../utils'),
41
- featureCohort: jest.fn(),
42
41
  getCallerFile: jest.fn(),
43
42
  getModuleEntryPath: jest.fn(),
44
43
  }));
@@ -17,7 +17,7 @@ import {
17
17
  } from '../../utils';
18
18
  import { webComponentStyleRules } from '../__mocks__';
19
19
  import { generateMetadata } from '../configs/utils';
20
- import { featureCohort, getCallerFile, splitByEntry } from '../utils';
20
+ import { getCallerFile, splitByEntry } from '../utils';
21
21
 
22
22
  import { createWebpackConfig } from '../index';
23
23
 
@@ -45,7 +45,6 @@ jest.mock('../../utils', () => ({
45
45
  jest.mock('../configs/utils/generate-metadata');
46
46
  jest.mock('../utils', () => ({
47
47
  ...jest.requireActual('../utils'),
48
- featureCohort: jest.fn(),
49
48
  getCallerFile: jest.fn(),
50
49
  }));
51
50
 
@@ -322,6 +321,22 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
322
321
  });
323
322
  });
324
323
 
324
+ describe('when headless option is set to true', () => {
325
+ beforeEach(() => (options.headless = true));
326
+
327
+ test(`omits design system and registers headless`, () => {
328
+ expect(subject().plugins).toContainEqual(
329
+ new VirtualModulesPlugin({
330
+ [indexPath()]: [
331
+ "import { registerHeadless } from '@servicetitan/web-components';",
332
+ "import { connectedCallback, disconnectedCallback } from './headless';",
333
+ 'registerHeadless(connectedCallback, disconnectedCallback);',
334
+ ].join('\n'),
335
+ })
336
+ );
337
+ });
338
+ });
339
+
325
340
  describe.each([webpackDevConfigFileName, webpackProdConfigFileName])(
326
341
  'when invoked from "%s"',
327
342
  configFileName => {
@@ -333,32 +348,6 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
333
348
  }
334
349
  );
335
350
 
336
- describe('when featureCohort is active', () => {
337
- beforeEach(() => {
338
- jest.mocked(featureCohort).mockImplementation((_: number[], fn: Function) => fn());
339
- });
340
-
341
- test('configures "cache"', () => {
342
- expect(subject().cache).toEqual({
343
- type: 'filesystem',
344
- name: `${packageName}__full`,
345
- profile: true,
346
- });
347
- });
348
-
349
- describe('when embed option is set to true', () => {
350
- beforeEach(() => (options.embed = true));
351
-
352
- test('changes "cache.name" suffix to "__light"', () => {
353
- expect(subject().cache).toEqual(
354
- expect.objectContaining({
355
- name: `${packageName}__light`,
356
- })
357
- );
358
- });
359
- });
360
- });
361
-
362
351
  describe('when mode is production', () => {
363
352
  beforeEach(() =>
364
353
  Object.assign((overrides.configuration ??= {}), { mode: 'production' })
@@ -29,7 +29,7 @@ import {
29
29
  log,
30
30
  } from '../../utils';
31
31
  import { fileRules, productionStyleRules, styleRules } from '../__mocks__';
32
- import { featureCohort, splitByEntry } from '../utils';
32
+ import { splitByEntry } from '../utils';
33
33
 
34
34
  import { createWebpackConfig } from '../index';
35
35
 
@@ -65,11 +65,12 @@ jest.mock('../../utils', () => ({
65
65
  isExposeSharedDependencies: jest.fn(),
66
66
  isWebComponent: jest.fn(),
67
67
  loadSharedDependencies: jest.fn(),
68
- log: { debug: jest.fn(), info: jest.fn(), warning: jest.fn() },
69
- }));
70
- jest.mock('../utils', () => ({
71
- ...jest.requireActual('../utils'),
72
- featureCohort: jest.fn(),
68
+ log: {
69
+ debug: jest.fn(),
70
+ info: jest.fn(),
71
+ warning: jest.fn(),
72
+ timestamp: '10:40:00.000',
73
+ },
73
74
  }));
74
75
 
75
76
  describe(`[startup] ${createWebpackConfig.name}`, () => {
@@ -155,6 +156,15 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
155
156
 
156
157
  const subject = () => createWebpackConfig(overrides, options);
157
158
 
159
+ function expectDevServerToBe(devServer: WebpackDevServer.Configuration) {
160
+ expect(subject().devServer).toEqual(
161
+ expect.objectContaining({
162
+ ...devServer,
163
+ setupMiddlewares: expect.any(Function),
164
+ })
165
+ );
166
+ }
167
+
158
168
  test('configures "entry"', () => {
159
169
  expect(subject().entry).toEqual({ main: [`./${destination}/index`] });
160
170
  });
@@ -172,9 +182,7 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
172
182
  });
173
183
 
174
184
  test('configures "output.path"', () => {
175
- expect(subject().output!.path).toEqual(
176
- expect.stringContaining(path.join(destination, 'bundle'))
177
- );
185
+ expect(subject().output!.path).toEqual(path.join(process.cwd(), destination, 'bundle'));
178
186
  });
179
187
 
180
188
  test('configures "optimization"', () => {
@@ -214,7 +222,75 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
214
222
  };
215
223
 
216
224
  test('configures "devServer"', () => {
217
- expect(subject().devServer).toEqual(defaultDefServerConfig);
225
+ expectDevServerToBe(defaultDefServerConfig);
226
+ });
227
+
228
+ describe('devServer.setupMiddlewares', () => {
229
+ const middlewares: WebpackDevServer.Middleware[] = [];
230
+ let mockDevServer: any;
231
+
232
+ const setupMiddlewaresSubject = () => {
233
+ const { devServer } = subject();
234
+
235
+ return devServer?.setupMiddlewares?.(middlewares, mockDevServer);
236
+ };
237
+
238
+ describe('when devServer.app is defined', () => {
239
+ beforeEach(() => {
240
+ mockDevServer = { app: { use: jest.fn() } };
241
+ });
242
+
243
+ test('calls app.use once to add logging middleware', () => {
244
+ setupMiddlewaresSubject();
245
+ expect(mockDevServer.app.use).toHaveBeenCalledTimes(1);
246
+ });
247
+
248
+ test('returns the original middlewares array', () => {
249
+ expect(setupMiddlewaresSubject()).toBe(middlewares);
250
+ });
251
+
252
+ describe('when request is handled', () => {
253
+ const request = { method: 'GET', url: '/test' };
254
+ const nextMockFn = jest.fn();
255
+
256
+ const simulateRequest = () => {
257
+ const middlewareFn = mockDevServer.app.use.mock.calls[0][0];
258
+
259
+ middlewareFn(request, {}, nextMockFn);
260
+ };
261
+
262
+ beforeEach(() => {
263
+ setupMiddlewaresSubject();
264
+ simulateRequest();
265
+ });
266
+
267
+ test('logs the request with expected format', () => {
268
+ expect(log.info).toHaveBeenCalledWith(
269
+ `[${log.timestamp}]: ${request.method} ${request.url}`
270
+ );
271
+ });
272
+
273
+ test('calls next middleware', () => {
274
+ expect(nextMockFn).toHaveBeenCalled();
275
+ });
276
+ });
277
+ });
278
+
279
+ describe('when devServer.app is not defined', () => {
280
+ beforeEach(() => {
281
+ mockDevServer = { app: undefined };
282
+ });
283
+
284
+ test('logs a warning that webpack-dev-server is not defined', () => {
285
+ setupMiddlewaresSubject();
286
+
287
+ expect(log.warning).toHaveBeenCalledWith('webpack-dev-server app is not defined');
288
+ });
289
+
290
+ test('returns the original middlewares array', () => {
291
+ expect(setupMiddlewaresSubject()).toBe(middlewares);
292
+ });
293
+ });
218
294
  });
219
295
 
220
296
  describe('when "devServer" is disabled', () => {
@@ -240,7 +316,7 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
240
316
  beforeEach(() => (configuration = { webpack: options }));
241
317
 
242
318
  test('adds allowed options to "devServer" configuration', () => {
243
- expect(subject().devServer).toEqual({
319
+ expectDevServerToBe({
244
320
  ...defaultDefServerConfig,
245
321
  headers: options.headers,
246
322
  port: options.port,
@@ -253,7 +329,7 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
253
329
  beforeEach(() => (configuration.webpack = { devServer: options }));
254
330
 
255
331
  test('adds all options to "devServer" configuration', () => {
256
- expect(subject().devServer).toEqual({
332
+ expectDevServerToBe({
257
333
  ...defaultDefServerConfig,
258
334
  ...options,
259
335
  });
@@ -471,6 +547,27 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
471
547
  );
472
548
  });
473
549
  });
550
+
551
+ describe('headless option is true', () => {
552
+ beforeEach(() => setOptions({ headless: true }));
553
+
554
+ test('configures "output.path"', () => {
555
+ expect(subject().output!.path).toEqual(
556
+ path.join(process.cwd(), destination, 'bundle', 'headless')
557
+ );
558
+ });
559
+
560
+ describe('when mode is "production"', () => {
561
+ beforeEach(() => {
562
+ overrides.configuration ??= {};
563
+ Object.assign(overrides.configuration, { mode: 'production' });
564
+ });
565
+
566
+ test('omits optimization.runtimeChunk', () => {
567
+ expect(subject().optimization?.runtimeChunk).toBeUndefined();
568
+ });
569
+ });
570
+ });
474
571
  });
475
572
  });
476
573
 
@@ -487,40 +584,14 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
487
584
  )
488
585
  );
489
586
  });
490
- });
491
-
492
- describe('when featureCohort is active', () => {
493
- beforeEach(() => {
494
- jest.mocked(featureCohort).mockImplementation((_: number[], fn: Function) => fn());
495
- });
496
-
497
- test('configures "cache"', () => {
498
- expect(subject().cache).toEqual({
499
- type: 'filesystem',
500
- name: packageName,
501
- profile: true,
502
- });
503
- });
504
587
 
505
588
  describe('when package is web component', () => {
506
589
  beforeEach(() => jest.mocked(isWebComponent).mockReturnValue(true));
507
590
 
508
- function itAppendsSuffixToPackageName(suffix: string) {
509
- test(`appends "${suffix}" to package name`, () => {
510
- expect(subject().cache).toEqual(
511
- expect.objectContaining({
512
- name: `${packageName}${suffix}`,
513
- })
514
- );
515
- });
516
- }
517
-
518
- itAppendsSuffixToPackageName('__full');
519
-
520
- describe('when embed option is set to true', () => {
521
- beforeEach(() => setOptions({ embed: true }));
522
-
523
- itAppendsSuffixToPackageName('__light');
591
+ test('configures "output.path"', () => {
592
+ expect(subject().output!.path).toEqual(
593
+ path.join(process.cwd(), destination, 'bundle', 'light')
594
+ );
524
595
  });
525
596
  });
526
597
  });
@@ -19,7 +19,7 @@ export function devServerConfig(context: Context, overrides: Overrides): Result
19
19
  return;
20
20
  }
21
21
 
22
- const devServer = {
22
+ const devServer: DevServerConfig = {
23
23
  hot: false,
24
24
  port: 8080,
25
25
  historyApiFallback: true,
@@ -28,6 +28,18 @@ export function devServerConfig(context: Context, overrides: Overrides): Result
28
28
  'Access-Control-Allow-Origin': '*',
29
29
  'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept',
30
30
  },
31
+ setupMiddlewares: (middlewares, devServer) => {
32
+ if (devServer.app) {
33
+ devServer.app.use((request, _, next) => {
34
+ log.info(`[${log.timestamp}]: ${request.method} ${request.url}`);
35
+ next();
36
+ });
37
+ } else {
38
+ log.warning('webpack-dev-server app is not defined');
39
+ }
40
+
41
+ return middlewares;
42
+ },
31
43
  ...getDevServerConfig(),
32
44
  };
33
45
 
@@ -1,5 +1,4 @@
1
1
  export * from './amd-config';
2
- export * from './cache-config';
3
2
  export * from './dev-server-config';
4
3
  export * from './devtool-config';
5
4
  export * from './entry.config';
@@ -8,7 +8,7 @@ type ConfigWithCacheGroups = Config & { splitChunks: { cacheGroups: Record<strin
8
8
  type Result = Pick<Configuration, 'optimization'>;
9
9
 
10
10
  export function optimizationConfig(context: Context, _: Overrides): Result {
11
- const { isProduction } = context;
11
+ const { headless, isProduction } = context;
12
12
 
13
13
  const optimization: ConfigWithCacheGroups = {
14
14
  chunkIds: isProduction ? 'deterministic' : 'named',
@@ -17,7 +17,7 @@ export function optimizationConfig(context: Context, _: Overrides): Result {
17
17
  splitChunks: { cacheGroups: {} },
18
18
  };
19
19
 
20
- if (isProduction) {
20
+ if (!headless && isProduction) {
21
21
  optimization.runtimeChunk = 'single';
22
22
  }
23
23
 
@@ -58,8 +58,8 @@ function minimizeConfig(optimization: ConfigWithCacheGroups, context: Context) {
58
58
  }
59
59
 
60
60
  function sharedDependenciesConfig(optimization: ConfigWithCacheGroups, context: Context) {
61
- const { isExposeSharedDependencies } = context;
62
- if (!isExposeSharedDependencies) {
61
+ const { headless, isExposeSharedDependencies } = context;
62
+ if (!isExposeSharedDependencies || headless) {
63
63
  return;
64
64
  }
65
65
 
@@ -80,8 +80,8 @@ function sharedDependenciesConfig(optimization: ConfigWithCacheGroups, context:
80
80
  }
81
81
 
82
82
  function webComponentConfig(optimization: ConfigWithCacheGroups, context: Context) {
83
- const { isWebComponent, isProduction } = context;
84
- if (!isWebComponent) {
83
+ const { headless, isWebComponent, isProduction } = context;
84
+ if (!isWebComponent || headless) {
85
85
  return;
86
86
  }
87
87
 
@@ -6,12 +6,14 @@ type Config = Configuration['output'];
6
6
  type Result = Pick<Configuration, 'output'>;
7
7
 
8
8
  export function outputConfig(context: Context, _: Overrides): Result {
9
- const { destination, embed, isProduction, isWebComponent, name } = context;
9
+ const { destination, embed, headless, isProduction, isWebComponent, name } = context;
10
+
11
+ const bundleDir = headless ? 'headless' : embed ? 'light' : 'full';
10
12
 
11
13
  const output: Config = {
12
14
  filename: '[name].bundle.js',
13
15
  path: isWebComponent
14
- ? path.join(process.cwd(), `${destination}/bundle/${embed ? 'light' : 'full'}`)
16
+ ? path.join(process.cwd(), `${destination}/bundle/${bundleDir}`)
15
17
  : path.join(process.cwd(), `${destination}/bundle`),
16
18
  };
17
19
 
@@ -3,10 +3,13 @@ import HtmlWebpackPlugin, { Options as HtmlWebpackPluginOptions } from 'html-web
3
3
  import { splitByEntry } from '../../utils';
4
4
  import { Context, Overrides } from '../types';
5
5
 
6
- export function htmlPlugin({ embed, isWebComponent, name }: Context, { plugins }: Overrides) {
6
+ export function htmlPlugin(
7
+ { embed, headless, isWebComponent, name }: Context,
8
+ { plugins }: Overrides
9
+ ) {
7
10
  const { HtmlWebpackPlugin: htmlWebpackPluginOptions = {} } = plugins ?? {};
8
11
 
9
- if (embed) {
12
+ if (embed || headless) {
10
13
  return;
11
14
  }
12
15
 
@@ -34,7 +34,11 @@ function designSystemCode() {
34
34
  }
35
35
 
36
36
  function indexCode(context: Context) {
37
- const { embed = false, isLegacyRoot, sharedDependencies } = context;
37
+ const { embed = false, headless, isLegacyRoot, sharedDependencies } = context;
38
+ if (headless) {
39
+ return headlessIndex();
40
+ }
41
+
38
42
  const options = `{ legacyRoot: ${isLegacyRoot}, sharedDependenciesNames: ${JSON.stringify(
39
43
  Object.keys(sharedDependencies)
40
44
  )} }`;
@@ -46,11 +50,20 @@ function indexCode(context: Context) {
46
50
  ].join('\n');
47
51
  }
48
52
 
49
- function needsToIncludeDesignSystem({ embed, packageData, sharedDependencies }: Context) {
53
+ function needsToIncludeDesignSystem({ embed, headless, packageData, sharedDependencies }: Context) {
50
54
  return (
55
+ !headless &&
51
56
  // Depends on design system
52
57
  !!packageData.dependencies['@servicetitan/design-system'] &&
53
58
  // ... and is not light bundle with private copy of design system
54
59
  !(embed && !!sharedDependencies['@servicetitan/design-system'])
55
60
  );
56
61
  }
62
+
63
+ function headlessIndex() {
64
+ return [
65
+ "import { registerHeadless } from '@servicetitan/web-components';",
66
+ "import { connectedCallback, disconnectedCallback } from './headless';",
67
+ 'registerHeadless(connectedCallback, disconnectedCallback);',
68
+ ].join('\n');
69
+ }
@@ -67,12 +67,14 @@ describe(`[startup] ${generateMetadata.name}`, () => {
67
67
  describe('when package has entrypoints', () => {
68
68
  const full = { css: 'foo', js: 'bar ' };
69
69
  const light = { css: 'baz', js: 'qux' };
70
+ const headless = { css: 'quux', js: 'waldo' };
70
71
 
71
72
  beforeEach(() => {
72
73
  vol.fromJSON({
73
74
  ...packageFS(),
74
75
  [`${destination}/bundle/full/entrypoints.json`]: JSON.stringify(full),
75
76
  [`${destination}/bundle/light/entrypoints.json`]: JSON.stringify(light),
77
+ [`${destination}/bundle/headless/entrypoints.json`]: JSON.stringify(headless),
76
78
  });
77
79
  });
78
80
 
@@ -80,7 +82,7 @@ describe(`[startup] ${generateMetadata.name}`, () => {
80
82
  subject();
81
83
 
82
84
  expect(generatedMetadata(destination)).toEqual(
83
- expect.objectContaining({ entrypoints: { full, light } })
85
+ expect.objectContaining({ entrypoints: { full, light, headless } })
84
86
  );
85
87
  });
86
88
  });
@@ -15,6 +15,7 @@ export function generateMetadata(context: Context) {
15
15
 
16
16
  const full = readJsonSafe(path.join(destination, 'bundle', 'full', 'entrypoints.json'));
17
17
  const light = readJsonSafe(path.join(destination, 'bundle', 'light', 'entrypoints.json'));
18
+ const headless = readJsonSafe(path.join(destination, 'bundle', 'headless', 'entrypoints.json'));
18
19
  const metadata: Metadata = {
19
20
  name,
20
21
  version: packageData.version,
@@ -25,7 +26,11 @@ export function generateMetadata(context: Context) {
25
26
  },
26
27
  sharedDependencies,
27
28
  dependencies: packageData.dependencies,
28
- entrypoints: { ...(full ? { full } : {}), ...(light ? { light } : {}) },
29
+ entrypoints: {
30
+ ...(full ? { full } : {}),
31
+ ...(light ? { light } : {}),
32
+ ...(headless ? { headless } : {}),
33
+ },
29
34
  };
30
35
 
31
36
  const outputFile = path.join(destination, 'metadata.json');
@@ -17,7 +17,6 @@ import {
17
17
  import {
18
18
  Context,
19
19
  amdConfig,
20
- cacheConfig,
21
20
  devServerConfig,
22
21
  devtoolConfig,
23
22
  entryConfig,
@@ -67,7 +66,6 @@ export function createWebpackConfig(overrides: Overrides, options: Options = {})
67
66
  const result = merge(
68
67
  [
69
68
  amdConfig,
70
- cacheConfig,
71
69
  devServerConfig,
72
70
  devtoolConfig,
73
71
  entryConfig,
@@ -6,6 +6,7 @@ export interface Options {
6
6
  buildStat?: boolean;
7
7
  codeCoverage?: boolean;
8
8
  embed?: boolean;
9
+ headless?: boolean;
9
10
  name?: string;
10
11
  }
11
12
 
@@ -1,4 +1,3 @@
1
- export * from './feature-cohort';
2
1
  export * from './get-caller-filename';
3
2
  export * from './get-module-entry-path';
4
3
  export * from './split-by-entry';
@@ -1,3 +0,0 @@
1
- import { Package } from '../utils';
2
- export declare function createPackage(props: Partial<Package>): Package;
3
- //# sourceMappingURL=create-package.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"create-package.d.ts","sourceRoot":"","sources":["../../src/__mocks__/create-package.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAe,MAAM,UAAU,CAAC;AAEhD,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAU9D"}
@@ -1,2 +0,0 @@
1
- export * from './create-package';
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/__mocks__/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC"}
@@ -1,23 +0,0 @@
1
- /**
2
- * Asserts that a sequence of mock function calls occurred in the specified order,
3
- * with the specified arguments for each call.
4
- *
5
- * Each argument to this function should be either:
6
- * - a mock function (jest.Mock), or
7
- * - an array where the first element is a mock function and the rest are the expected arguments for that call.
8
- *
9
- * For each call, this function checks:
10
- * - The mock was called with the expected arguments (if provided).
11
- * - The call order is strictly increasing (i.e., each call happened after the previous one).
12
- *
13
- * @example
14
- * expectCalls(
15
- * [mockA, 1, 2],
16
- * [mockB, 'foo'],
17
- * mockC
18
- * );
19
- *
20
- * @param {...any[]} calls - Sequence of [mockFn, ...args] or mockFn to check call order and arguments.
21
- */
22
- export declare function expectCalls(...calls: any[]): void;
23
- //# sourceMappingURL=expect-calls.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"expect-calls.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/review/__mocks__/expect-calls.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,wBAAgB,WAAW,CAAC,GAAG,KAAK,EAAE,GAAG,EAAE,QAqB1C"}
@@ -1,2 +0,0 @@
1
- export * from './expect-calls';
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/review/__mocks__/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC"}
@@ -1,4 +0,0 @@
1
- export * from './mock-config';
2
- export * from './mock-packages';
3
- export * from './mock-project';
4
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/cli/commands/review/rules/__mocks__/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC"}
@@ -1,7 +0,0 @@
1
- import { ReviewConfiguration } from '../../types';
2
- export declare function mockConfig({ id, level, exclude, }: {
3
- id: string;
4
- level?: 'error' | 'warn';
5
- exclude: string | string[];
6
- }): ReviewConfiguration;
7
- //# sourceMappingURL=mock-config.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mock-config.d.ts","sourceRoot":"","sources":["../../../../../../src/cli/commands/review/rules/__mocks__/mock-config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD,wBAAgB,UAAU,CAAC,EACvB,EAAE,EACF,KAAe,EACf,OAAY,GACf,EAAE;IACC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAC9B,GAAG,mBAAmB,CAEtB"}
@@ -1,21 +0,0 @@
1
- import { Dependencies, Package } from '../../types';
2
- /**
3
- * Generates an array of mock Package objects based on a dependencies map.
4
- *
5
- * Each dependency entry can specify multiple versions, and each version can be used by multiple package names.
6
- * The resulting packages will have their dependencies set accordingly.
7
- *
8
- * @param {Dependencies} dependencies - An object mapping dependency names to version maps,
9
- * where each version maps to an array of package names that depend on that version.
10
- *
11
- * @returns {Package[]} An array of Package objects with the specified dependencies.
12
- *
13
- * @example
14
- * const deps = {
15
- * lodash: { '4.17.21': ['foo', 'bar'], '4.17.20': ['baz'] }
16
- * };
17
- * const pkgs = mockPackages(deps);
18
- * // pkgs will include packages 'foo', 'bar', and 'baz' with appropriate lodash dependencies.
19
- */
20
- export declare function mockPackages(dependencies: Dependencies): Package[];
21
- //# sourceMappingURL=mock-packages.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mock-packages.d.ts","sourceRoot":"","sources":["../../../../../../src/cli/commands/review/rules/__mocks__/mock-packages.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEpD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,YAAY,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,EAAE,CAmBlE"}
@@ -1,3 +0,0 @@
1
- import { Project } from '../../types';
2
- export declare function mockProject(project: Partial<Project>): Project;
3
- //# sourceMappingURL=mock-project.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mock-project.d.ts","sourceRoot":"","sources":["../../../../../../src/cli/commands/review/rules/__mocks__/mock-project.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAQ9D"}
@@ -1,2 +0,0 @@
1
- export declare const styleExtensions: string[];
2
- //# sourceMappingURL=style-extensions.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"style-extensions.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/style-extensions.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,UAA0B,CAAC"}