@servicetitan/startup 34.0.1 → 34.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 (110) hide show
  1. package/dist/cli/commands/run-task.d.ts.map +1 -1
  2. package/dist/cli/commands/run-task.js +4 -6
  3. package/dist/cli/commands/run-task.js.map +1 -1
  4. package/dist/cli/commands/run-task.test.js +4 -10
  5. package/dist/cli/commands/run-task.test.js.map +1 -1
  6. package/dist/cli/tasks/index.d.ts +4 -0
  7. package/dist/cli/tasks/index.d.ts.map +1 -0
  8. package/dist/cli/tasks/index.js +22 -0
  9. package/dist/cli/tasks/index.js.map +1 -0
  10. package/dist/cli/tasks/swc-compile-package/get-swc-options.d.ts +23 -0
  11. package/dist/cli/tasks/swc-compile-package/get-swc-options.d.ts.map +1 -0
  12. package/dist/cli/tasks/swc-compile-package/get-swc-options.js +41 -0
  13. package/dist/cli/tasks/swc-compile-package/get-swc-options.js.map +1 -0
  14. package/dist/cli/tasks/swc-compile-package/index.d.ts +3 -0
  15. package/dist/cli/tasks/swc-compile-package/index.d.ts.map +1 -0
  16. package/dist/cli/tasks/swc-compile-package/index.js +21 -0
  17. package/dist/cli/tasks/swc-compile-package/index.js.map +1 -0
  18. package/dist/cli/tasks/{swc-compile-package.d.ts → swc-compile-package/swc-compile-package.d.ts} +1 -1
  19. package/dist/cli/tasks/swc-compile-package/swc-compile-package.d.ts.map +1 -0
  20. package/dist/cli/tasks/{swc-compile-package.js → swc-compile-package/swc-compile-package.js} +35 -55
  21. package/dist/cli/tasks/swc-compile-package/swc-compile-package.js.map +1 -0
  22. package/dist/cli/tasks/tsc-compile/index.d.ts +2 -0
  23. package/dist/cli/tasks/tsc-compile/index.d.ts.map +1 -0
  24. package/dist/cli/tasks/tsc-compile/index.js +20 -0
  25. package/dist/cli/tasks/tsc-compile/index.js.map +1 -0
  26. package/dist/cli/tasks/{tsc-compile.d.ts → tsc-compile/tsc-compile.d.ts} +1 -1
  27. package/dist/cli/tasks/tsc-compile/tsc-compile.d.ts.map +1 -0
  28. package/dist/cli/tasks/{tsc-compile.js → tsc-compile/tsc-compile.js} +2 -2
  29. package/dist/cli/tasks/tsc-compile/tsc-compile.js.map +1 -0
  30. package/dist/cli/tasks/tsc-compile-package/index.d.ts +2 -0
  31. package/dist/cli/tasks/tsc-compile-package/index.d.ts.map +1 -0
  32. package/dist/cli/tasks/tsc-compile-package/index.js +20 -0
  33. package/dist/cli/tasks/tsc-compile-package/index.js.map +1 -0
  34. package/dist/cli/tasks/{tsc-compile-package.d.ts → tsc-compile-package/tsc-compile-package.d.ts} +1 -1
  35. package/dist/cli/tasks/tsc-compile-package/tsc-compile-package.d.ts.map +1 -0
  36. package/dist/cli/tasks/{tsc-compile-package.js → tsc-compile-package/tsc-compile-package.js} +2 -2
  37. package/dist/cli/tasks/tsc-compile-package/tsc-compile-package.js.map +1 -0
  38. package/dist/cli/utils/bundle.js +1 -1
  39. package/dist/cli/utils/bundle.js.map +1 -1
  40. package/dist/storybook-config/index.d.ts +3 -0
  41. package/dist/storybook-config/index.d.ts.map +1 -0
  42. package/dist/storybook-config/index.js +21 -0
  43. package/dist/storybook-config/index.js.map +1 -0
  44. package/dist/storybook-config/swc.d.ts +28 -0
  45. package/dist/storybook-config/swc.d.ts.map +1 -0
  46. package/dist/storybook-config/swc.js +36 -0
  47. package/dist/storybook-config/swc.js.map +1 -0
  48. package/dist/storybook-config/webpack-final.d.ts +4 -0
  49. package/dist/storybook-config/webpack-final.d.ts.map +1 -0
  50. package/dist/storybook-config/webpack-final.js +96 -0
  51. package/dist/storybook-config/webpack-final.js.map +1 -0
  52. package/dist/webpack/configs/index.d.ts +1 -0
  53. package/dist/webpack/configs/index.d.ts.map +1 -1
  54. package/dist/webpack/configs/index.js +1 -0
  55. package/dist/webpack/configs/index.js.map +1 -1
  56. package/dist/webpack/configs/rules-config.d.ts +2 -3
  57. package/dist/webpack/configs/rules-config.d.ts.map +1 -1
  58. package/dist/webpack/configs/rules-config.js.map +1 -1
  59. package/dist/webpack/configs/types.d.ts +6 -6
  60. package/dist/webpack/configs/types.d.ts.map +1 -1
  61. package/dist/webpack/utils/testing/get-compiler.js.map +1 -1
  62. package/package.json +18 -16
  63. package/src/cli/commands/__tests__/build.test.ts +0 -3
  64. package/src/cli/commands/__tests__/bundle-package.test.ts +0 -2
  65. package/src/cli/commands/__tests__/get-command.test.ts +0 -3
  66. package/src/cli/commands/__tests__/kendo-ui-license.test.ts +0 -2
  67. package/src/cli/commands/__tests__/lint.test.ts +0 -2
  68. package/src/cli/commands/__tests__/mfe-list.test.ts +0 -2
  69. package/src/cli/commands/__tests__/mfe-package-publish.test.ts +0 -2
  70. package/src/cli/commands/__tests__/mfe-package-rollback.test.ts +0 -2
  71. package/src/cli/commands/__tests__/mfe-publish.test.ts +0 -2
  72. package/src/cli/commands/__tests__/prepare-package.test.ts +0 -3
  73. package/src/cli/commands/__tests__/start.test.ts +0 -3
  74. package/src/cli/commands/__tests__/upload-sourcemaps.test.ts +0 -2
  75. package/src/cli/commands/run-task.test.ts +1 -6
  76. package/src/cli/commands/run-task.ts +1 -3
  77. package/src/cli/commands/test/runners/__tests__/jest.test.ts +1 -1
  78. package/src/cli/tasks/index.ts +3 -0
  79. package/src/cli/tasks/swc-compile-package/__tests__/get-swc-options.test.ts +77 -0
  80. package/src/cli/tasks/{__tests__ → swc-compile-package/__tests__}/swc-compile-package.test.ts +14 -76
  81. package/src/cli/tasks/swc-compile-package/get-swc-options.ts +34 -0
  82. package/src/cli/tasks/swc-compile-package/index.ts +2 -0
  83. package/src/cli/tasks/swc-compile-package/swc-cli.d.ts +22 -0
  84. package/src/cli/tasks/{swc-compile-package.ts → swc-compile-package/swc-compile-package.ts} +33 -52
  85. package/src/cli/tasks/{__tests__ → tsc-compile/__tests__}/tsc-compile.test.ts +1 -3
  86. package/src/cli/tasks/tsc-compile/index.ts +1 -0
  87. package/src/cli/tasks/{tsc-compile.ts → tsc-compile/tsc-compile.ts} +9 -2
  88. package/src/cli/tasks/{__tests__ → tsc-compile-package/__tests__}/tsc-compile-package.test.ts +2 -4
  89. package/src/cli/tasks/tsc-compile-package/index.ts +1 -0
  90. package/src/cli/tasks/{tsc-compile-package.ts → tsc-compile-package/tsc-compile-package.ts} +2 -2
  91. package/src/cli/utils/bundle.ts +1 -1
  92. package/src/storybook-config/__tests__/swc.test.ts +37 -0
  93. package/src/storybook-config/__tests__/webpack-final.test.ts +133 -0
  94. package/src/storybook-config/index.ts +2 -0
  95. package/src/storybook-config/swc.ts +24 -0
  96. package/src/storybook-config/webpack-final.ts +72 -0
  97. package/src/webpack/__tests__/create-webpack-config-shared-dependencies.test.ts +0 -2
  98. package/src/webpack/__tests__/create-webpack-config-web-component.test.ts +0 -2
  99. package/src/webpack/__tests__/create-webpack-config.test.ts +0 -2
  100. package/src/webpack/configs/index.ts +1 -0
  101. package/src/webpack/configs/rules-config.ts +5 -10
  102. package/src/webpack/configs/types.ts +6 -6
  103. package/src/webpack/utils/testing/get-compiler.ts +1 -1
  104. package/dist/cli/tasks/swc-compile-package.d.ts.map +0 -1
  105. package/dist/cli/tasks/swc-compile-package.js.map +0 -1
  106. package/dist/cli/tasks/tsc-compile-package.d.ts.map +0 -1
  107. package/dist/cli/tasks/tsc-compile-package.js.map +0 -1
  108. package/dist/cli/tasks/tsc-compile.d.ts.map +0 -1
  109. package/dist/cli/tasks/tsc-compile.js.map +0 -1
  110. package/src/cli/tasks/swc-cli.d.ts +0 -14
@@ -0,0 +1,77 @@
1
+ import { fs, vol } from 'memfs';
2
+ import { TSConfig } from '../../../utils';
3
+ import { getSwcOptions } from '../get-swc-options';
4
+
5
+ jest.mock('fs', () => fs);
6
+
7
+ describe(`[startup] ${getSwcOptions.name}`, () => {
8
+ let tsConfig: TSConfig;
9
+
10
+ function setTsConfig(config: Record<string, any> = {}) {
11
+ return vol.fromJSON({
12
+ 'tsconfig.json': JSON.stringify(config),
13
+ });
14
+ }
15
+
16
+ beforeEach(() => {
17
+ tsConfig = new TSConfig('tsconfig.json');
18
+ setTsConfig();
19
+ });
20
+
21
+ afterEach(() => vol.reset());
22
+
23
+ const subject = () => getSwcOptions(tsConfig);
24
+
25
+ test('returns default options', () => {
26
+ expect(subject()).toEqual({
27
+ jsc: {
28
+ parser: { syntax: 'typescript', tsx: true, decorators: true },
29
+ target: undefined,
30
+ transform: {
31
+ decoratorMetadata: undefined,
32
+ legacyDecorator: undefined,
33
+ react: { runtime: 'automatic' },
34
+ },
35
+ },
36
+ module: { type: 'es6' },
37
+ sourceMaps: undefined,
38
+ });
39
+ });
40
+
41
+ describe.each(
42
+ Object.entries({
43
+ target: 'jsc.target',
44
+ experimentalDecorators: 'jsc.transform.legacyDecorator',
45
+ emitDecoratorMetadata: 'jsc.transform.decoratorMetadata',
46
+ sourceMap: 'sourceMaps',
47
+ })
48
+ )('when tsconfig contains "compilerOptions.%s"', (compilerOption, swcOption) => {
49
+ beforeEach(() => setTsConfig({ compilerOptions: { [compilerOption]: 'foo' } }));
50
+
51
+ test(`configures swcOptions.${swcOption}`, () => {
52
+ subject();
53
+
54
+ const keys = swcOption.split('.').toReversed();
55
+ const expected = keys.slice(1).reduce(
56
+ (result, key) => {
57
+ return expect.objectContaining({ [key]: result });
58
+ },
59
+ expect.objectContaining({ [keys[0]]: 'foo' })
60
+ );
61
+ expect(subject()).toEqual(expected);
62
+ });
63
+ });
64
+
65
+ describe.each(['commonjs', 'commonJS', 'nodenext', 'NodeNext'])(
66
+ 'when compilerOptions.module is "%s"',
67
+ module => {
68
+ beforeEach(() => setTsConfig({ compilerOptions: { module } }));
69
+
70
+ test('sets module.type to "commonjs"', () => {
71
+ expect(subject()).toEqual(
72
+ expect.objectContaining({ module: { type: 'commonjs' } })
73
+ );
74
+ });
75
+ }
76
+ );
77
+ });
@@ -2,7 +2,9 @@ import { swcDir } from '@swc/cli';
2
2
  import debounce from 'debounce';
3
3
  import deepmerge from 'deepmerge';
4
4
  import { fs, vol } from 'memfs';
5
- import { getSwcCompilePackageConfiguration, log } from '../../../utils';
5
+ import { getSwcCompilePackageConfiguration, log } from '../../../../utils';
6
+ import { TSConfig } from '../../../utils';
7
+ import { getSwcOptions } from '../get-swc-options';
6
8
  import { SwcCompilePackage } from '../swc-compile-package';
7
9
 
8
10
  jest.mock('debounce', () => jest.fn());
@@ -10,11 +12,9 @@ jest.mock('fs', () => fs);
10
12
  jest.mock('@swc/cli', () => ({
11
13
  swcDir: jest.fn(),
12
14
  }));
13
- jest.mock('yargs', () => jest.fn());
14
- jest.mock('yargs/helpers', () => ({ hideBin: jest.fn() }));
15
15
 
16
- jest.mock('../../../utils', () => ({
17
- ...jest.requireActual('../../../utils'),
16
+ jest.mock('../../../../utils', () => ({
17
+ ...jest.requireActual('../../../../utils'),
18
18
  getFolders: jest.fn().mockReturnValue({
19
19
  source: 'src',
20
20
  destination: 'dist',
@@ -69,9 +69,10 @@ describe(`[startup] ${SwcCompilePackage.name} task`, () => {
69
69
  };
70
70
 
71
71
  function itCallsSwcDir(
72
+ how: string,
72
73
  packageConfig: ReturnType<typeof getSwcCompilePackageConfiguration> = {}
73
74
  ) {
74
- test('calls swcDir', () => {
75
+ test(`calls swcDir ${how}`, () => {
75
76
  subject();
76
77
 
77
78
  expect(swcDir).toHaveBeenCalledWith(
@@ -91,23 +92,7 @@ describe(`[startup] ${SwcCompilePackage.name} task`, () => {
91
92
  '**/*.stories.*',
92
93
  ],
93
94
  },
94
- swcOptions: {
95
- jsc: {
96
- parser: {
97
- syntax: 'typescript',
98
- tsx: true,
99
- decorators: true,
100
- },
101
- transform: {
102
- react: {
103
- runtime: 'automatic',
104
- },
105
- },
106
- },
107
- module: {
108
- type: 'es6',
109
- },
110
- },
95
+ swcOptions: getSwcOptions(new TSConfig('tsconfig.json')),
111
96
  callbacks: {
112
97
  onSuccess: expect.any(Function),
113
98
  onFail: expect.any(Function),
@@ -120,17 +105,18 @@ describe(`[startup] ${SwcCompilePackage.name} task`, () => {
120
105
  });
121
106
  }
122
107
 
123
- itCallsSwcDir();
108
+ itCallsSwcDir('with default config');
124
109
 
125
- describe('when package has swc-compile-package config', () => {
126
- const overrides = {
110
+ describe('with swc-compile-package config', () => {
111
+ const config = {
127
112
  cliOptions: { ignore: ['**/*.d.ts', '**/__tests__/*', '**/*.test.*'] },
128
113
  };
114
+
129
115
  beforeEach(() => {
130
- jest.mocked(getSwcCompilePackageConfiguration).mockReturnValue(overrides);
116
+ jest.mocked(getSwcCompilePackageConfiguration).mockReturnValue(config);
131
117
  });
132
118
 
133
- itCallsSwcDir(overrides);
119
+ itCallsSwcDir('with swc-compile-package config', config);
134
120
  });
135
121
 
136
122
  describe('when tsconfig contains "exclude" with "**/*.d.ts"', () => {
@@ -177,54 +163,6 @@ describe(`[startup] ${SwcCompilePackage.name} task`, () => {
177
163
  });
178
164
  });
179
165
 
180
- describe.each(
181
- Object.entries({
182
- target: 'jsc.target',
183
- experimentalDecorators: 'jsc.transform.legacyDecorator',
184
- emitDecoratorMetadata: 'jsc.transform.decoratorMetadata',
185
- sourceMap: 'sourceMaps',
186
- })
187
- )('when tsconfig contains "compilerOptions.%s"', (compilerOption, swcOption) => {
188
- beforeEach(() => {
189
- volumeFromJSON({
190
- 'tsconfig.json': { compilerOptions: { [compilerOption]: 'foo' } },
191
- });
192
- });
193
-
194
- test(`configures swcOptions.${swcOption}`, () => {
195
- subject();
196
-
197
- const keys = swcOption.split('.').toReversed();
198
- const expected = keys.slice(1).reduce(
199
- (result, key) => {
200
- return expect.objectContaining({ [key]: result });
201
- },
202
- expect.objectContaining({ [keys[0]]: 'foo' })
203
- );
204
- expect(swcDir).toHaveBeenCalledWith(expect.objectContaining({ swcOptions: expected }));
205
- });
206
- });
207
-
208
- describe('when package is commonjs', () => {
209
- beforeEach(() => {
210
- volumeFromJSON({
211
- 'tsconfig.json': { compilerOptions: { module: 'commonjs' } },
212
- });
213
- });
214
-
215
- test('swc module type is commonjs', () => {
216
- subject();
217
-
218
- expect(swcDir).toHaveBeenCalledWith(
219
- expect.objectContaining({
220
- swcOptions: expect.objectContaining({
221
- module: { type: 'commonjs' },
222
- }),
223
- })
224
- );
225
- });
226
- });
227
-
228
166
  test('onSuccess handler completes task and logs completion message', async () => {
229
167
  const task = subject();
230
168
 
@@ -0,0 +1,34 @@
1
+ import type { SwcOptions } from '@swc/cli';
2
+ import { TSConfig } from '../../utils';
3
+
4
+ type JscConfig = NonNullable<SwcOptions['jsc']>;
5
+
6
+ export function getSwcOptions(tsConfig: TSConfig) {
7
+ const target = tsConfig.getValue<JscConfig['target']>('compilerOptions.target');
8
+ const legacyDecorator = tsConfig.getValue<boolean>('compilerOptions.experimentalDecorators');
9
+ const decoratorMetadata = tsConfig.getValue<boolean>('compilerOptions.emitDecoratorMetadata');
10
+ const sourceMaps = tsConfig.getValue<SwcOptions['sourceMaps']>('compilerOptions.sourceMap');
11
+ const module = tsConfig.getValue<string>('compilerOptions.module')?.toLowerCase();
12
+
13
+ return {
14
+ jsc: {
15
+ parser: {
16
+ syntax: 'typescript',
17
+ tsx: true,
18
+ decorators: true,
19
+ },
20
+ target,
21
+ transform: {
22
+ legacyDecorator,
23
+ decoratorMetadata,
24
+ react: {
25
+ runtime: 'automatic',
26
+ },
27
+ },
28
+ },
29
+ sourceMaps,
30
+ module: {
31
+ type: module === 'commonjs' || module === 'nodenext' ? 'commonjs' : 'es6',
32
+ },
33
+ } satisfies SwcOptions;
34
+ }
@@ -0,0 +1,2 @@
1
+ export * from './get-swc-options';
2
+ export * from './swc-compile-package';
@@ -0,0 +1,22 @@
1
+ declare module '@swc/cli' {
2
+ import type { Config } from '@swc/types';
3
+
4
+ interface Options {
5
+ cliOptions?: {
6
+ extensions?: string[];
7
+ filenames?: string[];
8
+ ignore?: string[];
9
+ outDir?: string;
10
+ stripLeadingPaths?: boolean;
11
+ watch?: boolean;
12
+ };
13
+ swcOptions?: Config;
14
+ callbacks?: {
15
+ [key: string]: Function;
16
+ };
17
+ }
18
+
19
+ type SwcOptions = NonNullable<Options['swcOptions']>;
20
+
21
+ function swcDir(options: Options): void;
22
+ }
@@ -1,9 +1,11 @@
1
- import { Options, swcDir } from '@swc/cli';
1
+ import type { Options } from '@swc/cli';
2
+ import { swcDir } from '@swc/cli';
2
3
  import debounce from 'debounce';
3
4
  import deepmerge from 'deepmerge';
4
- import { getFolders, getSwcCompilePackageConfiguration, getTsConfig, log } from '../../utils';
5
- import { TSConfig } from '../utils';
6
- import { Task } from './task';
5
+ import { getFolders, getSwcCompilePackageConfiguration, getTsConfig, log } from '../../../utils';
6
+ import { TSConfig } from '../../utils';
7
+ import { Task } from '../task';
8
+ import { getSwcOptions } from './get-swc-options';
7
9
 
8
10
  interface Args {
9
11
  watch?: boolean;
@@ -13,8 +15,6 @@ function overwriteMerge(_destinationArray: unknown[], sourceArray: unknown[]) {
13
15
  return sourceArray;
14
16
  }
15
17
 
16
- const typedefsPattern = '**/*.d.ts';
17
-
18
18
  export class SwcCompilePackage extends Task {
19
19
  constructor({ watch }: Args) {
20
20
  super({ name: 'swc-compile-package', global: false, watch });
@@ -58,60 +58,41 @@ export class SwcCompilePackage extends Task {
58
58
  }
59
59
 
60
60
  private getConfig(): Options {
61
- const { source, destination } = getFolders();
62
61
  const packageConfig = getSwcCompilePackageConfiguration();
63
62
  const tsConfig = new TSConfig(getTsConfig());
64
- const target = tsConfig.getValue('compilerOptions.target');
65
- const legacyDecorator = tsConfig.getValue('compilerOptions.experimentalDecorators');
66
- const decoratorMetadata = tsConfig.getValue('compilerOptions.emitDecoratorMetadata');
67
- const sourceMaps = tsConfig.getValue('compilerOptions.sourceMap');
68
- const module = tsConfig.getValue<string>('compilerOptions.module')?.toLowerCase();
69
- const ignore = tsConfig.getValue('exclude', [
70
- '**/*.d.ts',
71
- '**/__tests__/*',
72
- '**/*.test.*',
73
- '**/__mocks__/*',
74
- '**/*.stories.*',
75
- ]);
76
-
77
- if (!ignore.includes(typedefsPattern)) {
78
- ignore.push(typedefsPattern);
79
- }
80
63
 
81
64
  return deepmerge(
82
65
  {
83
- cliOptions: {
84
- watch: this.watch,
85
- outDir: destination,
86
- stripLeadingPaths: true,
87
- extensions: ['.ts', '.tsx'],
88
- filenames: [source],
89
- ignore,
90
- },
91
- swcOptions: {
92
- jsc: {
93
- parser: {
94
- syntax: 'typescript',
95
- tsx: true,
96
- decorators: true,
97
- },
98
- target,
99
- transform: {
100
- legacyDecorator,
101
- decoratorMetadata,
102
- react: {
103
- runtime: 'automatic',
104
- },
105
- },
106
- },
107
- sourceMaps,
108
- module: {
109
- type: module === 'commonjs' || module === 'nodenext' ? 'commonjs' : 'es6',
110
- },
111
- },
66
+ cliOptions: getCliOptions(tsConfig, { watch: this.watch }),
67
+ swcOptions: getSwcOptions(tsConfig),
112
68
  },
113
69
  packageConfig,
114
70
  { arrayMerge: overwriteMerge, clone: false }
115
71
  );
116
72
  }
117
73
  }
74
+
75
+ function getCliOptions(tsConfig: TSConfig, { watch }: { watch?: boolean }): Options['cliOptions'] {
76
+ const { source, destination } = getFolders();
77
+ const typedefsPattern = '**/*.d.ts';
78
+ const ignore = tsConfig.getValue('exclude', [
79
+ typedefsPattern,
80
+ '**/__tests__/*',
81
+ '**/*.test.*',
82
+ '**/__mocks__/*',
83
+ '**/*.stories.*',
84
+ ]);
85
+
86
+ if (!ignore.includes(typedefsPattern)) {
87
+ ignore.push(typedefsPattern);
88
+ }
89
+
90
+ return {
91
+ extensions: ['.ts', '.tsx'],
92
+ filenames: [source],
93
+ ignore,
94
+ outDir: destination,
95
+ stripLeadingPaths: true,
96
+ watch,
97
+ };
98
+ }
@@ -1,7 +1,7 @@
1
1
  import execa from 'execa';
2
2
  import { fs, vol } from 'memfs';
3
3
  import path from 'path';
4
- import { log } from '../../../utils';
4
+ import { log } from '../../../../utils';
5
5
  import { TscCompile } from '../tsc-compile';
6
6
 
7
7
  jest.mock('fs', () => fs);
@@ -14,8 +14,6 @@ jest.mock('execa', () =>
14
14
  })
15
15
  )
16
16
  );
17
- jest.mock('yargs', () => jest.fn());
18
- jest.mock('yargs/helpers', () => ({ hideBin: jest.fn() }));
19
17
 
20
18
  describe(`[startup] ${TscCompile.name} task`, () => {
21
19
  let options: ConstructorParameters<typeof TscCompile>[0];
@@ -0,0 +1 @@
1
+ export * from './tsc-compile';
@@ -1,5 +1,12 @@
1
- import { getPackages, getPackagesGraph, getTsConfig, log, Package, PackageType } from '../../utils';
2
- import { CliTask } from './cli-task';
1
+ import {
2
+ getPackages,
3
+ getPackagesGraph,
4
+ getTsConfig,
5
+ log,
6
+ Package,
7
+ PackageType,
8
+ } from '../../../utils';
9
+ import { CliTask } from '../cli-task';
3
10
 
4
11
  interface Args {
5
12
  ignore?: string | string[];
@@ -10,8 +10,6 @@ jest.mock('execa', () =>
10
10
  })
11
11
  )
12
12
  );
13
- jest.mock('yargs', () => jest.fn());
14
- jest.mock('yargs/helpers', () => ({ hideBin: jest.fn() }));
15
13
 
16
14
  const tsConfig = 'tsconfig.build.json';
17
15
 
@@ -31,8 +29,8 @@ const tscOptions = [
31
29
  tsConfig,
32
30
  ];
33
31
 
34
- jest.mock('../../../utils', () => ({
35
- ...jest.requireActual('../../../utils'),
32
+ jest.mock('../../../../utils', () => ({
33
+ ...jest.requireActual('../../../../utils'),
36
34
  getFolders: jest.fn().mockReturnValue({
37
35
  source: 'src',
38
36
  destination: 'dist',
@@ -0,0 +1 @@
1
+ export * from './tsc-compile-package';
@@ -1,5 +1,5 @@
1
- import { getTsConfig } from '../../utils';
2
- import { CliTask } from './cli-task';
1
+ import { getTsConfig } from '../../../utils';
2
+ import { CliTask } from '../cli-task';
3
3
 
4
4
  interface Args {
5
5
  watch?: boolean;
@@ -187,5 +187,5 @@ async function runWatch(config: Configuration) {
187
187
  }
188
188
 
189
189
  function createWebpackCompiler(config: Configuration) {
190
- return webpack(config)!; // webpack only potentially returns null when given a callback argument
190
+ return webpack(config);
191
191
  }
@@ -0,0 +1,37 @@
1
+ import { SwcOptions } from '@swc/cli';
2
+ import { fs, vol } from 'memfs';
3
+ import { getSwcOptions } from '../../cli/tasks';
4
+ import { TSConfig } from '../../cli/utils';
5
+ import { swc } from '../swc';
6
+
7
+ jest.mock('fs', () => fs);
8
+
9
+ describe(`[startup/storybook-config] ${swc.name}`, () => {
10
+ const config: SwcOptions = { env: { bugfixes: true } };
11
+ let tsConfig: TSConfig;
12
+
13
+ function setTsConfig(config: Record<string, any> = {}) {
14
+ return vol.fromJSON({
15
+ 'tsconfig.json': JSON.stringify(config),
16
+ });
17
+ }
18
+
19
+ beforeEach(() => {
20
+ tsConfig = new TSConfig('tsconfig.json');
21
+ setTsConfig();
22
+ });
23
+
24
+ const subject = () => swc(config);
25
+
26
+ test('merges default swc config with input config', () => {
27
+ expect(subject()).toEqual({ ...config, ...getSwcOptions(tsConfig) });
28
+ });
29
+
30
+ describe('when tsConfig contains compilerOptions.target', () => {
31
+ beforeEach(() => setTsConfig({ compilerOptions: { target: '2018' } }));
32
+
33
+ test('omits target from result', () => {
34
+ expect(subject().jsc.target).toBeUndefined();
35
+ });
36
+ });
37
+ });
@@ -0,0 +1,133 @@
1
+ import type { Configuration } from 'webpack';
2
+ import { Overrides, rulesConfig } from '../../webpack/configs';
3
+ import { miniCssExtractPlugin } from '../../webpack/configs/plugins';
4
+ import { webpackFinal } from '../webpack-final';
5
+
6
+ jest.mock('../../webpack/configs');
7
+ jest.mock('../../webpack/configs/plugins');
8
+
9
+ describe(`[startup/storybook-config] ${webpackFinal.name}`, () => {
10
+ const mockRules: any[] = [
11
+ { test: /\.module\.css$/, use: ['style-loader', 'css-loader'] },
12
+ { test: /\.module\.less$/, use: ['style-loader', 'less-loader'] },
13
+ { test: /\.less$/, use: ['less-loader'] },
14
+ { test: /\.svg$/, use: ['svg-loader'] },
15
+ { test: /\.css$/, use: ['css-loader'] },
16
+ ];
17
+ const mockMiniCssExtractPlugin: any = { name: 'MiniCssExtractPlugin' };
18
+ let config: Configuration;
19
+ let overrides: Overrides | undefined;
20
+
21
+ beforeEach(() => {
22
+ jest.clearAllMocks();
23
+ jest.mocked(rulesConfig).mockReturnValue({ rules: mockRules });
24
+ jest.mocked(miniCssExtractPlugin).mockReturnValue(mockMiniCssExtractPlugin);
25
+ config = {};
26
+ overrides = undefined;
27
+ });
28
+
29
+ const subject = () => webpackFinal(config, overrides);
30
+
31
+ function toRegExp(extension: string) {
32
+ return new RegExp(`${extension.replaceAll('.', '\\.')}$`);
33
+ }
34
+
35
+ test.each(['.module.css', '.module.less', '.less', '.svg'])(
36
+ 'adds %s rules to config',
37
+ extension => {
38
+ expect(subject().module!.rules).toContainEqual(
39
+ expect.objectContaining({ test: toRegExp(extension) })
40
+ );
41
+ }
42
+ );
43
+
44
+ test.each(['.css'])('excludes %s rules from config', extension => {
45
+ expect(subject().module!.rules).not.toContainEqual(
46
+ expect.objectContaining({ test: toRegExp(extension) })
47
+ );
48
+ });
49
+
50
+ test('adds MiniCssExtractPlugin to config', () => {
51
+ expect(subject().plugins).toEqual([mockMiniCssExtractPlugin]);
52
+ });
53
+
54
+ describe('when config contains rules', () => {
55
+ const configRules: any = [false, null, { test: /.foo$/ }, { test: '.bar' }];
56
+
57
+ beforeEach(() => (config = { module: { rules: configRules } }));
58
+
59
+ test('appends rules to config', () => {
60
+ expect(subject().module!.rules).toEqual([
61
+ ...configRules,
62
+ ...mockRules.filter(({ test }) => test.toString() !== '/\\.css$/'),
63
+ ]);
64
+ });
65
+ });
66
+
67
+ describe('when config contains plugins', () => {
68
+ const configPlugin: any = { name: 'MockPlugin' };
69
+
70
+ beforeEach(() => (config.plugins = [configPlugin]));
71
+
72
+ test('appends MiniCssExtractPlugin to config', () => {
73
+ expect(subject().plugins).toEqual([configPlugin, mockMiniCssExtractPlugin]);
74
+ });
75
+
76
+ describe('when MiniCssExtractPlugin is disabled', () => {
77
+ beforeEach(() => jest.mocked(miniCssExtractPlugin).mockReturnValue(undefined));
78
+
79
+ test('returns only configured plugins', () => {
80
+ expect(subject().plugins).toEqual(config.plugins);
81
+ });
82
+ });
83
+ });
84
+
85
+ describe('when in production mode', () => {
86
+ beforeEach(() => (config.mode = 'production'));
87
+
88
+ test('creates production rules', () => {
89
+ subject();
90
+
91
+ expect(rulesConfig).toHaveBeenCalledWith(
92
+ expect.objectContaining({ isProduction: true }),
93
+ expect.anything()
94
+ );
95
+ });
96
+ });
97
+
98
+ describe('with overrides', () => {
99
+ beforeEach(() => (overrides = { plugins: { MiniCssExtractPlugin: {} } }));
100
+
101
+ test('passes overrides through to miniCssExtractPlug', () => {
102
+ subject();
103
+
104
+ expect(miniCssExtractPlugin).toHaveBeenCalledWith(expect.anything(), overrides);
105
+ });
106
+
107
+ test('passes overrides through to rulesConfig', () => {
108
+ subject();
109
+
110
+ expect(rulesConfig).toHaveBeenCalledWith(expect.anything(), overrides);
111
+ });
112
+ });
113
+
114
+ describe('when config contains .css rule', () => {
115
+ const cssRule = { test: /\.css$/, use: ['css-loader'] };
116
+
117
+ beforeEach(() => (config = { module: { rules: [cssRule] } }));
118
+
119
+ test('transforms css rule to exclude .module.css', () => {
120
+ expect(subject().module!.rules![0]).toEqual({ ...cssRule, exclude: /\.module.css$/ });
121
+ });
122
+ });
123
+
124
+ describe('when config contains .svg rule', () => {
125
+ const svgRule = { test: /\.svg$/, use: ['svg-loader'] };
126
+
127
+ beforeEach(() => (config = { module: { rules: [svgRule] } }));
128
+
129
+ test('disables svg rule', () => {
130
+ expect(subject().module!.rules![0]).toEqual({ ...svgRule, exclude: /\.svg$/i });
131
+ });
132
+ });
133
+ });
@@ -0,0 +1,2 @@
1
+ export * from './swc';
2
+ export * from './webpack-final';
@@ -0,0 +1,24 @@
1
+ import type { SwcOptions } from '@swc/cli';
2
+ import { inspect } from 'node:util';
3
+ import { getSwcOptions } from '../cli/tasks';
4
+ import { TSConfig } from '../cli/utils';
5
+ import { getTsConfig, log } from '../utils';
6
+
7
+ export function swc(config: SwcOptions) {
8
+ const tsConfig = new TSConfig(getTsConfig());
9
+ const swcOptions = getSwcOptions(tsConfig);
10
+
11
+ /*
12
+ * We cannot set 'jsc.target' because Storybook always sets 'env'
13
+ * (see https://github.com/storybookjs/storybook/blob/24db05a0e4b499a99fb5a53b5a70fa894fa6a8c8/code/builders/builder-webpack5/src/presets/custom-webpack-preset.ts#L19)
14
+ * and 'env' and 'jsc.target' cannot be used together
15
+ */
16
+ if (swcOptions.jsc.target) {
17
+ delete swcOptions.jsc.target;
18
+ }
19
+
20
+ /* istanbul ignore next: debug only */
21
+ log.debug('storybook-config:swc', () => inspect({ swcOptions }, { depth: null }));
22
+
23
+ return { ...config, ...swcOptions };
24
+ }