@servicetitan/startup 27.4.0 → 28.0.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 (133) hide show
  1. package/dist/cli/commands/get-branch-configs.d.ts +4 -0
  2. package/dist/cli/commands/get-branch-configs.d.ts.map +1 -0
  3. package/dist/cli/commands/get-branch-configs.js +13 -0
  4. package/dist/cli/commands/get-branch-configs.js.map +1 -0
  5. package/dist/cli/commands/get-command.d.ts.map +1 -1
  6. package/dist/cli/commands/get-command.js +4 -2
  7. package/dist/cli/commands/get-command.js.map +1 -1
  8. package/dist/cli/commands/init.d.ts +0 -1
  9. package/dist/cli/commands/init.d.ts.map +1 -1
  10. package/dist/cli/commands/init.js +39 -9
  11. package/dist/cli/commands/init.js.map +1 -1
  12. package/dist/cli/commands/mfe-package-clean.d.ts +13 -0
  13. package/dist/cli/commands/mfe-package-clean.d.ts.map +1 -0
  14. package/dist/cli/commands/mfe-package-clean.js +113 -0
  15. package/dist/cli/commands/mfe-package-clean.js.map +1 -0
  16. package/dist/cli/commands/mfe-package-publish.d.ts +20 -0
  17. package/dist/cli/commands/mfe-package-publish.d.ts.map +1 -0
  18. package/dist/cli/commands/mfe-package-publish.js +153 -0
  19. package/dist/cli/commands/mfe-package-publish.js.map +1 -0
  20. package/dist/cli/commands/mfe-publish.d.ts +4 -29
  21. package/dist/cli/commands/mfe-publish.d.ts.map +1 -1
  22. package/dist/cli/commands/mfe-publish.js +1 -213
  23. package/dist/cli/commands/mfe-publish.js.map +1 -1
  24. package/dist/cli/utils/assets-copy.d.ts.map +1 -1
  25. package/dist/cli/utils/assets-copy.js +3 -3
  26. package/dist/cli/utils/assets-copy.js.map +1 -1
  27. package/dist/cli/utils/cli-os.d.ts +9 -2
  28. package/dist/cli/utils/cli-os.d.ts.map +1 -1
  29. package/dist/cli/utils/cli-os.js +16 -8
  30. package/dist/cli/utils/cli-os.js.map +1 -1
  31. package/dist/cli/utils/styles-copy.d.ts.map +1 -1
  32. package/dist/cli/utils/styles-copy.js +3 -3
  33. package/dist/cli/utils/styles-copy.js.map +1 -1
  34. package/dist/utils/get-folders.js +2 -2
  35. package/dist/utils/get-folders.js.map +1 -1
  36. package/dist/utils/get-jest-config.d.ts.map +1 -1
  37. package/dist/utils/get-jest-config.js +2 -10
  38. package/dist/utils/get-jest-config.js.map +1 -1
  39. package/dist/webpack/configs/dev-server-config.d.ts.map +1 -1
  40. package/dist/webpack/configs/dev-server-config.js +1 -1
  41. package/dist/webpack/configs/dev-server-config.js.map +1 -1
  42. package/dist/webpack/configs/plugins/ignore-plugin/is-optional-anvil-peer-dependency.js +1 -1
  43. package/dist/webpack/configs/plugins/ignore-plugin/is-optional-anvil-peer-dependency.js.map +1 -1
  44. package/dist/webpack/configs/plugins/index.d.ts +1 -0
  45. package/dist/webpack/configs/plugins/index.d.ts.map +1 -1
  46. package/dist/webpack/configs/plugins/index.js +1 -0
  47. package/dist/webpack/configs/plugins/index.js.map +1 -1
  48. package/dist/webpack/configs/plugins/virtual-modules-plugin.d.ts.map +1 -1
  49. package/dist/webpack/configs/plugins/virtual-modules-plugin.js +15 -5
  50. package/dist/webpack/configs/plugins/virtual-modules-plugin.js.map +1 -1
  51. package/dist/webpack/configs/plugins/watch-run-plugin.d.ts +8 -0
  52. package/dist/webpack/configs/plugins/watch-run-plugin.d.ts.map +1 -0
  53. package/dist/webpack/configs/plugins/watch-run-plugin.js +26 -0
  54. package/dist/webpack/configs/plugins/watch-run-plugin.js.map +1 -0
  55. package/dist/webpack/configs/plugins-config.d.ts.map +1 -1
  56. package/dist/webpack/configs/plugins-config.js +1 -0
  57. package/dist/webpack/configs/plugins-config.js.map +1 -1
  58. package/dist/webpack/configs/types.d.ts +16 -0
  59. package/dist/webpack/configs/types.d.ts.map +1 -1
  60. package/dist/webpack/configs/utils/generate-metadata.d.ts.map +1 -1
  61. package/dist/webpack/configs/utils/generate-metadata.js +3 -3
  62. package/dist/webpack/configs/utils/generate-metadata.js.map +1 -1
  63. package/jest/jest-preset.js +9 -0
  64. package/package.json +16 -21
  65. package/src/cli/commands/__tests__/init.test.ts +108 -28
  66. package/src/cli/commands/__tests__/mfe-package-clean.test.ts +1 -1
  67. package/src/cli/commands/__tests__/mfe-package-publish.test.ts +77 -7
  68. package/src/cli/commands/__tests__/tests.test.ts +4 -0
  69. package/src/cli/commands/get-branch-configs.ts +8 -0
  70. package/src/cli/commands/get-command.ts +3 -1
  71. package/src/cli/commands/init.ts +40 -10
  72. package/src/cli/commands/mfe-package-clean.ts +132 -0
  73. package/src/cli/commands/mfe-package-publish.ts +189 -0
  74. package/src/cli/commands/mfe-publish.ts +5 -294
  75. package/src/cli/utils/__tests__/assets-copy.test.ts +3 -7
  76. package/src/cli/utils/__tests__/cli-os.test.ts +41 -6
  77. package/src/cli/utils/__tests__/eslint.test.ts +4 -0
  78. package/src/cli/utils/__tests__/styles-copy.test.ts +3 -7
  79. package/src/cli/utils/assets-copy.ts +3 -3
  80. package/src/cli/utils/cli-os.ts +20 -8
  81. package/src/cli/utils/styles-copy.ts +3 -3
  82. package/src/utils/__tests__/get-jest-config.test.ts +1 -7
  83. package/src/utils/__tests__/load-shared-dependencies.test.ts +82 -88
  84. package/src/utils/get-folders.ts +1 -1
  85. package/src/utils/get-jest-config.ts +2 -10
  86. package/src/webpack/__tests__/create-webpack-config-shared-dependencies.test.ts +0 -1
  87. package/src/webpack/__tests__/create-webpack-config-web-component.test.ts +47 -13
  88. package/src/webpack/__tests__/create-webpack-config.test.ts +3 -2
  89. package/src/webpack/configs/dev-server-config.ts +2 -1
  90. package/src/webpack/configs/plugins/ignore-plugin/is-optional-anvil-peer-dependency.ts +1 -1
  91. package/src/webpack/configs/plugins/index.ts +1 -0
  92. package/src/webpack/configs/plugins/virtual-modules-plugin.ts +17 -5
  93. package/src/webpack/configs/plugins/watch-run-plugin.ts +23 -0
  94. package/src/webpack/configs/plugins-config.ts +2 -0
  95. package/src/webpack/configs/types.ts +19 -0
  96. package/src/webpack/configs/utils/generate-metadata.ts +5 -5
  97. package/tsconfig/base.json +1 -1
  98. package/template/.eslintrc.json +0 -3
  99. package/template/.gitignore +0 -21
  100. package/template/.npmrc +0 -3
  101. package/template/.prettierrc +0 -9
  102. package/template/.stylelintignore +0 -1
  103. package/template/.stylelintrc.json +0 -3
  104. package/template/.vscode/extensions.json +0 -18
  105. package/template/.vscode/settings.json +0 -4
  106. package/template/lerna.json +0 -4
  107. package/template/package.json +0 -32
  108. package/template/packages/application/package.json +0 -35
  109. package/template/packages/application/src/__tests__/app.test.tsx +0 -33
  110. package/template/packages/application/src/app.css +0 -3
  111. package/template/packages/application/src/app.tsx +0 -45
  112. package/template/packages/application/src/design-system.css +0 -3
  113. package/template/packages/application/src/index.tsx +0 -8
  114. package/template/packages/application/src/main-page.tsx +0 -5
  115. package/template/packages/application/src/second-page.tsx +0 -5
  116. package/template/packages/application/tsconfig.json +0 -13
  117. package/template/packages/feature-a/package.json +0 -19
  118. package/template/packages/feature-a/src/index.ts +0 -0
  119. package/template/packages/feature-a/tsconfig.json +0 -9
  120. package/template/packages/feature-b/package.json +0 -19
  121. package/template/packages/feature-b/src/index.ts +0 -0
  122. package/template/packages/feature-b/tsconfig.json +0 -9
  123. package/template/packages/feature-c/package.json +0 -19
  124. package/template/packages/feature-c/src/index.ts +0 -0
  125. package/template/packages/feature-c/tsconfig.json +0 -9
  126. package/template/setupTests.ts +0 -27
  127. package/template/tsconfig.test.json +0 -5
  128. package/template-react18/packages/application/package.json +0 -35
  129. package/template-react18/packages/application/src/index.tsx +0 -9
  130. package/template-react18/packages/feature-a/package.json +0 -19
  131. package/template-react18/packages/feature-b/package.json +0 -19
  132. package/template-react18/packages/feature-c/package.json +0 -19
  133. package/tsconfig.json +0 -13
@@ -5,10 +5,7 @@ import { assetsCopy, assetsCopyWatch } from '../assets-copy';
5
5
  import { assetExtensions } from '../index';
6
6
 
7
7
  jest.mock('cpx2', () => ({
8
- copy: jest.fn().mockImplementation((...args: any[]) => {
9
- const callback = args[args.length - 1];
10
- callback(null);
11
- }),
8
+ copySync: jest.fn(),
12
9
  watch: jest.fn(() => ({ on: (_eventName: string, listener: Function) => listener() })),
13
10
  }));
14
11
  jest.mock('../../../utils', () => ({
@@ -28,10 +25,9 @@ describe('[startup] Cli Utils (Assets)', () => {
28
25
  test('copies assets from source to destination', async () => {
29
26
  await subject();
30
27
 
31
- expect(cpx.copy).toHaveBeenCalledWith(
28
+ expect(cpx.copySync).toHaveBeenCalledWith(
32
29
  `${source}/**/*.{${assetExtensions.join()}}`,
33
- destination,
34
- expect.anything()
30
+ destination
35
31
  );
36
32
  });
37
33
  });
@@ -1,6 +1,7 @@
1
1
  import { execSync, spawn } from 'child_process';
2
2
 
3
3
  import { runCommand, runCommandOutput } from '../cli-os';
4
+ import { log } from '../../../utils';
4
5
 
5
6
  jest.mock('child_process', () => ({ execSync: jest.fn(), spawn: jest.fn() }));
6
7
  jest.mock('../../../utils', () => ({ log: { info: jest.fn() } })); // suppress log output
@@ -11,6 +12,7 @@ describe('[startup] Cli Utils (OS)', () => {
11
12
  let childProcess: ReturnType<typeof spawn>;
12
13
 
13
14
  beforeEach(() => {
15
+ jest.clearAllMocks();
14
16
  exitCode = 0;
15
17
  childProcess = {
16
18
  stderr: { pipe: jest.fn() },
@@ -25,7 +27,7 @@ describe('[startup] Cli Utils (OS)', () => {
25
27
  test('runs command', () => {
26
28
  expect(subject('foo bar')).resolves.toBe(undefined);
27
29
 
28
- expect(spawn).toHaveBeenCalledWith('foo', ['bar'], undefined);
30
+ expect(spawn).toHaveBeenCalledWith('foo', ['bar'], {});
29
31
  });
30
32
 
31
33
  test('runs command with options', async () => {
@@ -37,7 +39,7 @@ describe('[startup] Cli Utils (OS)', () => {
37
39
  test('runs command array', async () => {
38
40
  await subject(['foo', 'bar', '--baz']);
39
41
 
40
- expect(spawn).toHaveBeenCalledWith('foo', ['bar', '--baz'], undefined);
42
+ expect(spawn).toHaveBeenCalledWith('foo', ['bar', '--baz'], {});
41
43
  });
42
44
 
43
45
  test("pipes stdout and stderr to parent's streams", async () => {
@@ -60,10 +62,28 @@ describe('[startup] Cli Utils (OS)', () => {
60
62
  expect(subject(command)).rejects.toBeUndefined();
61
63
  })
62
64
  );
65
+
66
+ test('logs command and exit status', async () => {
67
+ const logInfoSpy = jest.spyOn(log, 'info');
68
+ await subject('foo');
69
+
70
+ expect(logInfoSpy).toHaveBeenCalledWith('run command foo');
71
+ expect(logInfoSpy).toHaveBeenCalledWith('command finished with code 0', 'foo');
72
+ });
73
+
74
+ test('quiet option suppresses output', async () => {
75
+ const logInfoSpy = jest.spyOn(log, 'info');
76
+ await subject('foo', { quiet: true });
77
+
78
+ expect(logInfoSpy).not.toHaveBeenCalled();
79
+ });
63
80
  });
64
81
 
65
82
  describe(`${runCommandOutput.name}`, () => {
66
- beforeEach(() => jest.mocked(execSync).mockReturnValue(''));
83
+ beforeEach(() => {
84
+ jest.clearAllMocks();
85
+ jest.mocked(execSync).mockReturnValue('');
86
+ });
67
87
 
68
88
  const subject = (...args: Parameters<typeof runCommandOutput>) => runCommandOutput(...args);
69
89
 
@@ -73,7 +93,7 @@ describe('[startup] Cli Utils (OS)', () => {
73
93
 
74
94
  expect(subject('foo bar')).toBe(result);
75
95
 
76
- expect(execSync).toHaveBeenCalledWith('foo bar', undefined);
96
+ expect(execSync).toHaveBeenCalledWith('foo bar', {});
77
97
  });
78
98
 
79
99
  test('runs command with options', () => {
@@ -85,13 +105,13 @@ describe('[startup] Cli Utils (OS)', () => {
85
105
  test('runs command array', () => {
86
106
  subject(['foo', 'bar']);
87
107
 
88
- expect(execSync).toHaveBeenCalledWith('foo bar', undefined);
108
+ expect(execSync).toHaveBeenCalledWith('foo bar', {});
89
109
  });
90
110
 
91
111
  test('ignores false and "" array values', () => {
92
112
  subject(['', 'foo', false, '', 'bar', false]);
93
113
 
94
- expect(execSync).toHaveBeenCalledWith('foo bar', undefined);
114
+ expect(execSync).toHaveBeenCalledWith('foo bar', {});
95
115
  });
96
116
 
97
117
  ['', [], ['']].forEach(command =>
@@ -99,5 +119,20 @@ describe('[startup] Cli Utils (OS)', () => {
99
119
  expect(() => subject(command)).toThrow();
100
120
  })
101
121
  );
122
+
123
+ test('logs command and result', () => {
124
+ const logInfoSpy = jest.spyOn(log, 'info');
125
+ subject('foo');
126
+
127
+ expect(logInfoSpy).toHaveBeenCalledWith('run command foo');
128
+ expect(logInfoSpy).toHaveBeenCalledWith('command finished', '');
129
+ });
130
+
131
+ test('quiet option suppresses output', () => {
132
+ const logInfoSpy = jest.spyOn(log, 'info');
133
+ subject('foo', { quiet: true });
134
+
135
+ expect(logInfoSpy).not.toHaveBeenCalled();
136
+ });
102
137
  });
103
138
  });
@@ -63,8 +63,12 @@ describe(`[startup] utils:${eslint.name}`, () => {
63
63
  });
64
64
 
65
65
  describe('when there are errors', () => {
66
+ const exitCode = process.exitCode;
67
+
66
68
  beforeEach(() => (eslintErrors = [mockResult]));
67
69
 
70
+ afterAll(() => (process.exitCode = exitCode));
71
+
68
72
  test('sets process exitCode', async () => {
69
73
  await subject();
70
74
 
@@ -5,10 +5,7 @@ import { stylesCopy, stylesCopyWatch } from '../styles-copy';
5
5
  import { styleExtensions } from '../index';
6
6
 
7
7
  jest.mock('cpx2', () => ({
8
- copy: jest.fn().mockImplementation((...args: any[]) => {
9
- const callback = args[args.length - 1];
10
- callback(null);
11
- }),
8
+ copySync: jest.fn(),
12
9
  watch: jest.fn(() => ({ on: (_eventName: string, listener: Function) => listener() })),
13
10
  }));
14
11
  jest.mock('../../../utils', () => ({
@@ -28,10 +25,9 @@ describe('[startup] Cli Utils (Styles)', () => {
28
25
  test('copies styles from source to destination', async () => {
29
26
  await subject();
30
27
 
31
- expect(cpx.copy).toHaveBeenCalledWith(
28
+ expect(cpx.copySync).toHaveBeenCalledWith(
32
29
  `${source}/**/*.{${styleExtensions.join()}}`,
33
- destination,
34
- expect.anything()
30
+ destination
35
31
  );
36
32
  });
37
33
  });
@@ -1,15 +1,15 @@
1
1
  import cpx from 'cpx2';
2
- import util from 'util';
3
2
 
4
3
  import { getFolders, log } from '../../utils';
5
4
  import { assetExtensions } from '.';
6
5
 
7
- export async function assetsCopy() {
6
+ export function assetsCopy() {
8
7
  const { source, destination } = getFolders();
9
8
 
10
9
  log.info('Copying asset files...');
11
10
 
12
- await util.promisify(cpx.copy)(`${source}/**/*.{${assetExtensions.join()}}`, destination);
11
+ cpx.copySync(`${source}/**/*.{${assetExtensions.join()}}`, destination);
12
+ return Promise.resolve();
13
13
  }
14
14
 
15
15
  export async function assetsCopyWatch() {
@@ -6,9 +6,11 @@ import {
6
6
  } from 'child_process';
7
7
  import { log } from '../../utils';
8
8
 
9
+ type RunCommandOptions = SpawnOptionsWithoutStdio & { quiet?: boolean };
10
+
9
11
  export const runCommand = (
10
12
  command: string | (string | false)[],
11
- opts?: SpawnOptionsWithoutStdio
13
+ { quiet, ...spawnOptions }: RunCommandOptions = {}
12
14
  ): Promise<void> => {
13
15
  return new Promise((resolve, reject) => {
14
16
  const commandArray: string[] = Array.isArray(command)
@@ -28,15 +30,19 @@ export const runCommand = (
28
30
  return;
29
31
  }
30
32
 
31
- log.info(`run command ${fullCommand}`);
33
+ if (!quiet) {
34
+ log.info(`run command ${fullCommand}`);
35
+ }
32
36
 
33
- const proc = spawn(commandName, commandArray, opts);
37
+ const proc = spawn(commandName, commandArray, spawnOptions);
34
38
 
35
39
  proc.stdout.pipe(process.stdout);
36
40
  proc.stderr.pipe(process.stderr);
37
41
 
38
42
  proc.on('exit', function (code: any) {
39
- log.info(`command finished with code ${code}`, fullCommand);
43
+ if (!quiet) {
44
+ log.info(`command finished with code ${code}`, fullCommand);
45
+ }
40
46
 
41
47
  if (code) {
42
48
  reject();
@@ -47,9 +53,11 @@ export const runCommand = (
47
53
  });
48
54
  };
49
55
 
56
+ type RunCommandOutputOptions = ExecSyncOptionsWithBufferEncoding & { quiet?: boolean };
57
+
50
58
  export const runCommandOutput = (
51
59
  command: string | (string | false)[],
52
- options?: ExecSyncOptionsWithBufferEncoding
60
+ { quiet, ...execSyncOptions }: RunCommandOutputOptions = {}
53
61
  ): string => {
54
62
  const commandArray: string[] = Array.isArray(command)
55
63
  ? command
@@ -66,11 +74,15 @@ export const runCommandOutput = (
66
74
  throw new Error();
67
75
  }
68
76
 
69
- log.info(`run command ${fullCommand}`);
77
+ if (!quiet) {
78
+ log.info(`run command ${fullCommand}`);
79
+ }
70
80
 
71
- const result = execSync(fullCommand, options).toString();
81
+ const result = execSync(fullCommand, execSyncOptions).toString();
72
82
 
73
- log.info('command finished', result);
83
+ if (!quiet) {
84
+ log.info('command finished', result);
85
+ }
74
86
 
75
87
  return result;
76
88
  };
@@ -1,15 +1,15 @@
1
1
  import cpx from 'cpx2';
2
- import util from 'util';
3
2
 
4
3
  import { getFolders, log } from '../../utils';
5
4
  import { styleExtensions } from '.';
6
5
 
7
- export async function stylesCopy() {
6
+ export function stylesCopy() {
8
7
  const { source, destination } = getFolders();
9
8
 
10
9
  log.info('Copying style files...');
11
10
 
12
- await util.promisify(cpx.copy)(`${source}/**/*.{${styleExtensions.join()}}`, destination);
11
+ cpx.copySync(`${source}/**/*.{${styleExtensions.join()}}`, destination);
12
+ return Promise.resolve();
13
13
  }
14
14
 
15
15
  export async function stylesCopyWatch() {
@@ -19,13 +19,6 @@ describe('[startup] Utils', () => {
19
19
  testRunner: 'jest-circus/runner',
20
20
  transformIgnorePatterns: ['node_modules/(?!(@servicetitan|@react-hook|nanoid|axios)/)'],
21
21
  modulePathIgnorePatterns: ['<rootDir>/.*/__mocks__'],
22
- transform: {
23
- '^.+\\.jsx?$': [
24
- 'babel-jest',
25
- { presets: [['@babel/preset-env', { targets: { node: 'current' } }]] },
26
- ],
27
- '^.+\\.tsx?$': ['ts-jest', { tsconfig: './tsconfig.test.json' }],
28
- },
29
22
  moduleNameMapper: {
30
23
  '\\.(css|scss|less|png|svg|jpg|jpeg|gif|woff|woff2|eot|ttf|otf)$': 'identity-obj-proxy',
31
24
  },
@@ -34,6 +27,7 @@ describe('[startup] Utils', () => {
34
27
  coveragePathIgnorePatterns: ['^.+\\.d\\.ts$'],
35
28
  coverageReporters: ['html-spa', 'text', 'json', 'cobertura', 'lcov'],
36
29
  collectCoverageFrom: ['**/*.{ts,tsx}'],
30
+ preset: expect.stringMatching(/startup[\\\/]+jest/),
37
31
  };
38
32
 
39
33
  beforeEach(() => {
@@ -1,10 +1,25 @@
1
1
  import { loadSharedDependencies } from '../load-shared-dependencies';
2
2
 
3
- describe('[Startup] utils:loadSharedDependencies', () => {
4
- const getPackageDependencies = (...excluded: string[]) =>
5
- Object.entries({
6
- '@servicetitan/confirm': '^0.0.0',
3
+ describe(`[startup] utils:${loadSharedDependencies.name}`, () => {
4
+ const defaultSharedDependencies = {
5
+ '@servicetitan/design-system': 'SharedDependencies.ServiceTitan.DesignSystem',
6
+ '@servicetitan/anvil2': 'SharedDependencies.ServiceTitan.Anvil2',
7
+ 'classnames': 'SharedDependencies.ClassNames',
8
+ 'formstate': 'SharedDependencies.FormState',
9
+ 'mobx': 'SharedDependencies.MobX',
10
+ 'mobx-react': 'SharedDependencies.MobXReact',
11
+ 'mobx-utils': 'SharedDependencies.MobXUtils',
12
+ 'react': 'SharedDependencies.React',
13
+ 'react-dom': 'SharedDependencies.ReactDOM',
14
+ };
15
+ let packageDependencies: Record<string, string> | undefined;
16
+ let sharedDependencies: Record<string, string> | undefined;
17
+
18
+ beforeEach(() => {
19
+ packageDependencies = {
20
+ // Default shared dependencies
7
21
  '@servicetitan/design-system': '^0.0.0',
22
+ '@servicetitan/anvil2': '^0.0.0',
8
23
  'classnames': '^0.0.0',
9
24
  'formstate': '^0.0.0',
10
25
  'mobx': '^0.0.0',
@@ -12,103 +27,82 @@ describe('[Startup] utils:loadSharedDependencies', () => {
12
27
  'mobx-utils': '^0.0.0',
13
28
  'react': '^0.0.0',
14
29
  'react-dom': '^0.0.0',
30
+ // Other dependencies
31
+ '@servicetitan/confirm': '^0.0.0',
15
32
  'react-input-mask': '^0.0.0',
16
- }).reduce(
17
- (out, [d, v]) => ({
18
- ...out,
19
- ...(excluded.includes(d) ? {} : { [d]: v }),
20
- }),
21
- {}
22
- );
23
-
24
- test('return default dependencies when manual are not configured', () => {
25
- expect(loadSharedDependencies(getPackageDependencies(), undefined)).toEqual({
26
- '@servicetitan/design-system': 'SharedDependencies.ServiceTitan.DesignSystem',
27
- 'classnames': 'SharedDependencies.ClassNames',
28
- 'formstate': 'SharedDependencies.FormState',
29
- 'mobx': 'SharedDependencies.MobX',
30
- 'mobx-react': 'SharedDependencies.MobXReact',
31
- 'mobx-utils': 'SharedDependencies.MobXUtils',
32
- 'react': 'SharedDependencies.React',
33
- 'react-dom': 'SharedDependencies.ReactDOM',
34
- });
33
+ };
34
+ sharedDependencies = undefined;
35
35
  });
36
36
 
37
- test('return default dependencies except not used when manual are not configured', () => {
38
- expect(loadSharedDependencies(getPackageDependencies('mobx-utils'), undefined)).toEqual({
39
- '@servicetitan/design-system': 'SharedDependencies.ServiceTitan.DesignSystem',
40
- 'classnames': 'SharedDependencies.ClassNames',
41
- 'formstate': 'SharedDependencies.FormState',
42
- 'mobx': 'SharedDependencies.MobX',
43
- 'mobx-react': 'SharedDependencies.MobXReact',
44
- 'react': 'SharedDependencies.React',
45
- 'react-dom': 'SharedDependencies.ReactDOM',
46
- });
37
+ const subject = () => loadSharedDependencies(packageDependencies, sharedDependencies);
38
+
39
+ function omit(obj: Record<string, string>, ...exclude: string[]) {
40
+ return Object.fromEntries(Object.entries(obj).filter(([key]) => !exclude.includes(key)));
41
+ }
42
+
43
+ test('returns default shared dependencies', () => {
44
+ expect(subject()).toEqual(defaultSharedDependencies);
47
45
  });
48
46
 
49
- test('return manual dependencies if set', () => {
50
- expect(
51
- loadSharedDependencies(getPackageDependencies(), {
52
- '@servicetitan/confirm': 'SharedDependencies.ServiceTitan.Confirm',
53
- 'react-input-mask': 'SharedDependencies.ReactInputMask',
54
- })
55
- ).toEqual({
56
- '@servicetitan/confirm': 'SharedDependencies.ServiceTitan.Confirm',
57
- 'react-input-mask': 'SharedDependencies.ReactInputMask',
47
+ describe('when package does not depend on default shared dependency', () => {
48
+ beforeEach(() => delete packageDependencies!['@servicetitan/design-system']);
49
+
50
+ test('omits the default shared dependency', () => {
51
+ expect(subject()).toEqual(
52
+ omit(defaultSharedDependencies, '@servicetitan/design-system')
53
+ );
58
54
  });
59
55
  });
60
56
 
61
- test('return default dependencies within manual', () => {
62
- expect(
63
- loadSharedDependencies(getPackageDependencies(), {
64
- defaults: '',
65
- })
66
- ).toEqual({
67
- '@servicetitan/design-system': 'SharedDependencies.ServiceTitan.DesignSystem',
68
- 'classnames': 'SharedDependencies.ClassNames',
69
- 'formstate': 'SharedDependencies.FormState',
70
- 'mobx': 'SharedDependencies.MobX',
71
- 'mobx-react': 'SharedDependencies.MobXReact',
72
- 'mobx-utils': 'SharedDependencies.MobXUtils',
73
- 'react': 'SharedDependencies.React',
74
- 'react-dom': 'SharedDependencies.ReactDOM',
57
+ describe('with explicit shared dependencies', () => {
58
+ beforeEach(() => (sharedDependencies = {}));
59
+
60
+ test('returns specified dependencies', () => {
61
+ expect(subject()).toEqual(sharedDependencies);
75
62
  });
76
- });
77
63
 
78
- test('clear default dependencies when configured', () => {
79
- expect(
80
- loadSharedDependencies(getPackageDependencies(), {
81
- 'defaults': '',
82
- 'mobx-utils': '',
83
- })
84
- ).toEqual({
85
- '@servicetitan/design-system': 'SharedDependencies.ServiceTitan.DesignSystem',
86
- 'classnames': 'SharedDependencies.ClassNames',
87
- 'formstate': 'SharedDependencies.FormState',
88
- 'mobx': 'SharedDependencies.MobX',
89
- 'mobx-react': 'SharedDependencies.MobXReact',
90
- 'react': 'SharedDependencies.React',
91
- 'react-dom': 'SharedDependencies.ReactDOM',
64
+ describe('when explicit shared dependencies includes "defaults"', () => {
65
+ beforeEach(() => (sharedDependencies!.defaults = ''));
66
+
67
+ test('returns default shared dependencies', () => {
68
+ expect(subject()).toEqual(defaultSharedDependencies);
69
+ });
70
+
71
+ describe('when explicit shared dependency has falsy value', () => {
72
+ beforeEach(() => {
73
+ Object.assign(sharedDependencies!, { 'classnames': false, 'mobx-utils': '' });
74
+ });
75
+
76
+ test('omits the falsy dependency', () => {
77
+ expect(subject()).toEqual(
78
+ omit(defaultSharedDependencies, 'classnames', 'mobx-utils')
79
+ );
80
+ });
81
+ });
82
+
83
+ describe('when explicit shared dependency has non-default packages', () => {
84
+ beforeEach(() => {
85
+ Object.assign(sharedDependencies!, {
86
+ '@servicetitan/confirm': 'SharedDependencies.ServiceTitan.Confirm',
87
+ 'react-input-mask': 'SharedDependencies.ReactInputMask',
88
+ });
89
+ });
90
+
91
+ test('adds the non-default packages', () => {
92
+ expect(subject()).toEqual({
93
+ ...defaultSharedDependencies,
94
+ ...omit(sharedDependencies!, 'defaults'),
95
+ });
96
+ });
97
+ });
92
98
  });
93
99
  });
94
100
 
95
- test('mixes default dependencies and configured', () => {
96
- expect(
97
- loadSharedDependencies(getPackageDependencies(), {
98
- 'defaults': '',
99
- 'mobx-utils': '',
100
- 'react-input-mask': 'SharedDependencies.ReactInputMask',
101
- 'react-something': 'SharedDependencies.ReactSomething',
102
- })
103
- ).toEqual({
104
- '@servicetitan/design-system': 'SharedDependencies.ServiceTitan.DesignSystem',
105
- 'classnames': 'SharedDependencies.ClassNames',
106
- 'formstate': 'SharedDependencies.FormState',
107
- 'mobx': 'SharedDependencies.MobX',
108
- 'mobx-react': 'SharedDependencies.MobXReact',
109
- 'react': 'SharedDependencies.React',
110
- 'react-dom': 'SharedDependencies.ReactDOM',
111
- 'react-input-mask': 'SharedDependencies.ReactInputMask',
101
+ describe('with no package dependencies', () => {
102
+ beforeEach(() => (packageDependencies = undefined));
103
+
104
+ test('returns empty object', () => {
105
+ expect(subject()).toEqual({});
112
106
  });
113
107
  });
114
108
  });
@@ -1,6 +1,6 @@
1
1
  import path from 'path';
2
2
 
3
- import { readJson } from '.';
3
+ import { readJson } from './read-json';
4
4
 
5
5
  /**
6
6
  * Returns folders of sources and compilation target
@@ -13,13 +13,6 @@ const getJestConfigBase = ({
13
13
  setupFiles?: string[];
14
14
  testPathIgnorePatterns?: string[];
15
15
  }) => {
16
- const transform = {
17
- '^.+\\.jsx?$': [
18
- 'babel-jest',
19
- { presets: [['@babel/preset-env', { targets: { node: 'current' } }]] },
20
- ],
21
- '^.+\\.tsx?$': ['ts-jest', { tsconfig: './tsconfig.test.json' }],
22
- };
23
16
  const moduleNameMapper = {
24
17
  '\\.(css|scss|less|png|svg|jpg|jpeg|gif|woff|woff2|eot|ttf|otf)$': 'identity-obj-proxy',
25
18
  };
@@ -30,7 +23,6 @@ const getJestConfigBase = ({
30
23
  testRunner: 'jest-circus/runner',
31
24
  transformIgnorePatterns: ['node_modules/(?!(@servicetitan|@react-hook|nanoid|axios)/)'],
32
25
  modulePathIgnorePatterns: ['<rootDir>/.*/__mocks__'],
33
- transform,
34
26
  moduleNameMapper,
35
27
  testPathIgnorePatterns: [
36
28
  '\\.yalc',
@@ -41,6 +33,7 @@ const getJestConfigBase = ({
41
33
  coveragePathIgnorePatterns: ['^.+\\.d\\.ts$', ...coveragePathIgnorePatterns],
42
34
  coverageReporters: ['html-spa', 'text', 'json', 'cobertura', 'lcov'],
43
35
  collectCoverageFrom: ['**/*.{ts,tsx}'],
36
+ preset: path.join(__dirname, '../../jest'),
44
37
  };
45
38
  };
46
39
 
@@ -70,7 +63,7 @@ export const getJestConfigCLI = (args: Config.Argv): Config.Argv => {
70
63
  ...args,
71
64
  };
72
65
 
73
- const { collectCoverageFrom, moduleNameMapper, transform, ...rest } = getJestConfigBase({
66
+ const { collectCoverageFrom, moduleNameMapper, ...rest } = getJestConfigBase({
74
67
  coveragePathIgnorePatterns,
75
68
  setupFiles,
76
69
  testPathIgnorePatterns,
@@ -80,7 +73,6 @@ export const getJestConfigCLI = (args: Config.Argv): Config.Argv => {
80
73
  collectCoverageFrom: JSON.stringify(collectCoverageFrom),
81
74
  globals: JSON.stringify(globals),
82
75
  moduleNameMapper: JSON.stringify(moduleNameMapper),
83
- transform: JSON.stringify(transform),
84
76
  ...rest,
85
77
  ...config,
86
78
  };
@@ -33,7 +33,6 @@ jest.mock('../../utils', () => ({
33
33
  isCustomStyleRules: jest.fn(),
34
34
  isExposeSharedDependencies: jest.fn(),
35
35
  loadSharedDependencies: jest.fn(),
36
- log: { debug: jest.fn(), info: jest.fn() },
37
36
  }));
38
37
  jest.mock('../utils', () => ({
39
38
  ...jest.requireActual('../utils'),