@servicetitan/startup 27.4.0 → 28.1.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.
- package/dist/cli/commands/get-command.d.ts.map +1 -1
- package/dist/cli/commands/get-command.js +4 -2
- package/dist/cli/commands/get-command.js.map +1 -1
- package/dist/cli/commands/init.d.ts +0 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +39 -9
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/mfe-package-clean.d.ts +14 -0
- package/dist/cli/commands/mfe-package-clean.d.ts.map +1 -0
- package/dist/cli/commands/mfe-package-clean.js +124 -0
- package/dist/cli/commands/mfe-package-clean.js.map +1 -0
- package/dist/cli/commands/mfe-package-publish.d.ts +20 -0
- package/dist/cli/commands/mfe-package-publish.d.ts.map +1 -0
- package/dist/cli/commands/mfe-package-publish.js +153 -0
- package/dist/cli/commands/mfe-package-publish.js.map +1 -0
- package/dist/cli/commands/mfe-publish.d.ts +6 -30
- package/dist/cli/commands/mfe-publish.d.ts.map +1 -1
- package/dist/cli/commands/mfe-publish.js +14 -226
- package/dist/cli/commands/mfe-publish.js.map +1 -1
- package/dist/cli/utils/assets-copy.d.ts.map +1 -1
- package/dist/cli/utils/assets-copy.js +3 -3
- package/dist/cli/utils/assets-copy.js.map +1 -1
- package/dist/cli/utils/cli-os.d.ts +9 -2
- package/dist/cli/utils/cli-os.d.ts.map +1 -1
- package/dist/cli/utils/cli-os.js +16 -8
- package/dist/cli/utils/cli-os.js.map +1 -1
- package/dist/cli/utils/styles-copy.d.ts.map +1 -1
- package/dist/cli/utils/styles-copy.js +3 -3
- package/dist/cli/utils/styles-copy.js.map +1 -1
- package/dist/utils/get-branch-configs.d.ts +3 -0
- package/dist/utils/get-branch-configs.d.ts.map +1 -0
- package/dist/utils/get-branch-configs.js +18 -0
- package/dist/utils/get-branch-configs.js.map +1 -0
- package/dist/utils/get-configuration.d.ts +13 -3
- package/dist/utils/get-configuration.d.ts.map +1 -1
- package/dist/utils/get-configuration.js +28 -5
- package/dist/utils/get-configuration.js.map +1 -1
- package/dist/utils/get-folders.js +2 -2
- package/dist/utils/get-folders.js.map +1 -1
- package/dist/utils/get-jest-config.d.ts.map +1 -1
- package/dist/utils/get-jest-config.js +2 -10
- package/dist/utils/get-jest-config.js.map +1 -1
- package/dist/webpack/configs/dev-server-config.d.ts.map +1 -1
- package/dist/webpack/configs/dev-server-config.js +1 -1
- package/dist/webpack/configs/dev-server-config.js.map +1 -1
- package/dist/webpack/configs/plugins/ignore-plugin/is-optional-anvil-peer-dependency.js +1 -1
- package/dist/webpack/configs/plugins/ignore-plugin/is-optional-anvil-peer-dependency.js.map +1 -1
- package/dist/webpack/configs/plugins/index.d.ts +1 -0
- package/dist/webpack/configs/plugins/index.d.ts.map +1 -1
- package/dist/webpack/configs/plugins/index.js +1 -0
- package/dist/webpack/configs/plugins/index.js.map +1 -1
- package/dist/webpack/configs/plugins/virtual-modules-plugin.d.ts.map +1 -1
- package/dist/webpack/configs/plugins/virtual-modules-plugin.js +15 -5
- package/dist/webpack/configs/plugins/virtual-modules-plugin.js.map +1 -1
- package/dist/webpack/configs/plugins/watch-run-plugin.d.ts +8 -0
- package/dist/webpack/configs/plugins/watch-run-plugin.d.ts.map +1 -0
- package/dist/webpack/configs/plugins/watch-run-plugin.js +26 -0
- package/dist/webpack/configs/plugins/watch-run-plugin.js.map +1 -0
- package/dist/webpack/configs/plugins-config.d.ts.map +1 -1
- package/dist/webpack/configs/plugins-config.js +1 -0
- package/dist/webpack/configs/plugins-config.js.map +1 -1
- package/dist/webpack/configs/types.d.ts +16 -0
- package/dist/webpack/configs/types.d.ts.map +1 -1
- package/dist/webpack/configs/utils/generate-metadata.d.ts.map +1 -1
- package/dist/webpack/configs/utils/generate-metadata.js +3 -3
- package/dist/webpack/configs/utils/generate-metadata.js.map +1 -1
- package/jest/jest-preset.js +9 -0
- package/package.json +18 -23
- package/src/cli/commands/__tests__/init.test.ts +108 -28
- package/src/cli/commands/__tests__/mfe-package-clean.test.ts +45 -6
- package/src/cli/commands/__tests__/mfe-package-publish.test.ts +77 -7
- package/src/cli/commands/__tests__/mfe-publish.test.ts +19 -1
- package/src/cli/commands/__tests__/tests.test.ts +4 -0
- package/src/cli/commands/get-command.ts +3 -1
- package/src/cli/commands/init.ts +40 -10
- package/src/cli/commands/mfe-package-clean.ts +143 -0
- package/src/cli/commands/mfe-package-publish.ts +189 -0
- package/src/cli/commands/mfe-publish.ts +18 -298
- package/src/cli/utils/__tests__/assets-copy.test.ts +3 -7
- package/src/cli/utils/__tests__/cli-os.test.ts +41 -6
- package/src/cli/utils/__tests__/eslint.test.ts +4 -0
- package/src/cli/utils/__tests__/styles-copy.test.ts +3 -7
- package/src/cli/utils/assets-copy.ts +3 -3
- package/src/cli/utils/cli-os.ts +20 -8
- package/src/cli/utils/styles-copy.ts +3 -3
- package/src/utils/__tests__/get-branch-configs.test.ts +36 -0
- package/src/utils/__tests__/get-configuration.test.ts +65 -0
- package/src/utils/__tests__/get-jest-config.test.ts +1 -7
- package/src/utils/__tests__/load-shared-dependencies.test.ts +82 -88
- package/src/utils/get-branch-configs.ts +17 -0
- package/src/utils/get-configuration.ts +45 -7
- package/src/utils/get-folders.ts +1 -1
- package/src/utils/get-jest-config.ts +2 -10
- package/src/webpack/__tests__/create-webpack-config-shared-dependencies.test.ts +0 -1
- package/src/webpack/__tests__/create-webpack-config-web-component.test.ts +47 -13
- package/src/webpack/__tests__/create-webpack-config.test.ts +3 -2
- package/src/webpack/configs/dev-server-config.ts +2 -1
- package/src/webpack/configs/plugins/ignore-plugin/is-optional-anvil-peer-dependency.ts +1 -1
- package/src/webpack/configs/plugins/index.ts +1 -0
- package/src/webpack/configs/plugins/virtual-modules-plugin.ts +17 -5
- package/src/webpack/configs/plugins/watch-run-plugin.ts +23 -0
- package/src/webpack/configs/plugins-config.ts +2 -0
- package/src/webpack/configs/types.ts +19 -0
- package/src/webpack/configs/utils/generate-metadata.ts +5 -5
- package/tsconfig/base.json +1 -1
- package/template/.eslintrc.json +0 -3
- package/template/.gitignore +0 -21
- package/template/.npmrc +0 -3
- package/template/.prettierrc +0 -9
- package/template/.stylelintignore +0 -1
- package/template/.stylelintrc.json +0 -3
- package/template/.vscode/extensions.json +0 -18
- package/template/.vscode/settings.json +0 -4
- package/template/lerna.json +0 -4
- package/template/package.json +0 -32
- package/template/packages/application/package.json +0 -35
- package/template/packages/application/src/__tests__/app.test.tsx +0 -33
- package/template/packages/application/src/app.css +0 -3
- package/template/packages/application/src/app.tsx +0 -45
- package/template/packages/application/src/design-system.css +0 -3
- package/template/packages/application/src/index.tsx +0 -8
- package/template/packages/application/src/main-page.tsx +0 -5
- package/template/packages/application/src/second-page.tsx +0 -5
- package/template/packages/application/tsconfig.json +0 -13
- package/template/packages/feature-a/package.json +0 -19
- package/template/packages/feature-a/src/index.ts +0 -0
- package/template/packages/feature-a/tsconfig.json +0 -9
- package/template/packages/feature-b/package.json +0 -19
- package/template/packages/feature-b/src/index.ts +0 -0
- package/template/packages/feature-b/tsconfig.json +0 -9
- package/template/packages/feature-c/package.json +0 -19
- package/template/packages/feature-c/src/index.ts +0 -0
- package/template/packages/feature-c/tsconfig.json +0 -9
- package/template/setupTests.ts +0 -27
- package/template/tsconfig.test.json +0 -5
- package/template-react18/packages/application/package.json +0 -35
- package/template-react18/packages/application/src/index.tsx +0 -9
- package/template-react18/packages/feature-a/package.json +0 -19
- package/template-react18/packages/feature-b/package.json +0 -19
- package/template-react18/packages/feature-c/package.json +0 -19
- package/tsconfig.json +0 -13
|
@@ -5,10 +5,7 @@ import { stylesCopy, stylesCopyWatch } from '../styles-copy';
|
|
|
5
5
|
import { styleExtensions } from '../index';
|
|
6
6
|
|
|
7
7
|
jest.mock('cpx2', () => ({
|
|
8
|
-
|
|
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.
|
|
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
|
|
6
|
+
export function assetsCopy() {
|
|
8
7
|
const { source, destination } = getFolders();
|
|
9
8
|
|
|
10
9
|
log.info('Copying asset files...');
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
cpx.copySync(`${source}/**/*.{${assetExtensions.join()}}`, destination);
|
|
12
|
+
return Promise.resolve();
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export async function assetsCopyWatch() {
|
package/src/cli/utils/cli-os.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
33
|
+
if (!quiet) {
|
|
34
|
+
log.info(`run command ${fullCommand}`);
|
|
35
|
+
}
|
|
32
36
|
|
|
33
|
-
const proc = spawn(commandName, commandArray,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
77
|
+
if (!quiet) {
|
|
78
|
+
log.info(`run command ${fullCommand}`);
|
|
79
|
+
}
|
|
70
80
|
|
|
71
|
-
const result = execSync(fullCommand,
|
|
81
|
+
const result = execSync(fullCommand, execSyncOptions).toString();
|
|
72
82
|
|
|
73
|
-
|
|
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
|
|
6
|
+
export function stylesCopy() {
|
|
8
7
|
const { source, destination } = getFolders();
|
|
9
8
|
|
|
10
9
|
log.info('Copying style files...');
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
cpx.copySync(`${source}/**/*.{${styleExtensions.join()}}`, destination);
|
|
12
|
+
return Promise.resolve();
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export async function stylesCopyWatch() {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { fs, vol } from 'memfs';
|
|
2
|
+
|
|
3
|
+
import { getBranchesConfigs } from '../get-branch-configs';
|
|
4
|
+
|
|
5
|
+
jest.mock('fs', () => fs);
|
|
6
|
+
|
|
7
|
+
describe(`[Startup] ${getBranchesConfigs.name}`, () => {
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
vol.reset();
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
const subject = () => getBranchesConfigs();
|
|
13
|
+
|
|
14
|
+
test('returns default configs', () => {
|
|
15
|
+
expect(subject()).toEqual({
|
|
16
|
+
develop: { publishTag: 'dev' },
|
|
17
|
+
dev: { publishTag: 'dev' },
|
|
18
|
+
next: { publishTag: 'next' },
|
|
19
|
+
master: { publishTag: 'prod' },
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe('when "branches" configs', () => {
|
|
24
|
+
beforeEach(() => {
|
|
25
|
+
vol.fromJSON({
|
|
26
|
+
'package.json': JSON.stringify({
|
|
27
|
+
cli: { 'web-component': { branches: { qa: { publishTag: 'qs' } } } },
|
|
28
|
+
}),
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test('returns configs', () => {
|
|
33
|
+
expect(subject()).toEqual({ qa: { publishTag: 'qs' } });
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { fs, vol } from 'memfs';
|
|
2
|
+
import path from 'path';
|
|
2
3
|
|
|
3
4
|
import {
|
|
4
5
|
getConfiguration,
|
|
@@ -6,6 +7,8 @@ import {
|
|
|
6
7
|
getESLintConfiguration,
|
|
7
8
|
getJestConfiguration,
|
|
8
9
|
getStylelintConfiguration,
|
|
10
|
+
getWebComponentBranchConfigs,
|
|
11
|
+
getWebComponentConfiguration,
|
|
9
12
|
isBundle,
|
|
10
13
|
isCustomStyleRules,
|
|
11
14
|
isDevServerDisabled,
|
|
@@ -183,6 +186,67 @@ describe('[startup] Utils', () => {
|
|
|
183
186
|
});
|
|
184
187
|
});
|
|
185
188
|
|
|
189
|
+
describe(`${getWebComponentConfiguration.name}`, () => {
|
|
190
|
+
const subject = () => getWebComponentConfiguration();
|
|
191
|
+
|
|
192
|
+
itReturns(subject, undefined);
|
|
193
|
+
|
|
194
|
+
test('returns undefined', () => {
|
|
195
|
+
expect(subject()).toEqual(undefined);
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
describe('with "cli.web-component true"', () => {
|
|
199
|
+
beforeEach(() => mockPackageJson({ cli: { 'web-component': true } }));
|
|
200
|
+
|
|
201
|
+
test('returns empty object', () => {
|
|
202
|
+
expect(subject()).toEqual({});
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
describe('with "cli.web-component.{}"', () => {
|
|
207
|
+
beforeEach(() => {
|
|
208
|
+
mockPackageJson({ cli: { 'web-component': { branches: { foo: 'bar' } } } });
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
test('returns web-component config', () => {
|
|
212
|
+
expect(subject()).toEqual({ branches: { foo: 'bar' } });
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
describe('with "cli.web-component.path"', () => {
|
|
217
|
+
beforeEach(() => {
|
|
218
|
+
vol.fromJSON({
|
|
219
|
+
...packageJsonFS({ cli: { 'web-component': './config.json' } }),
|
|
220
|
+
'config.json': '',
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
jest.doMock(path.resolve('./config.json'), () => ({ branches: { foo: 'bar' } }), {
|
|
224
|
+
virtual: true,
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
test('returns web-component config', () => {
|
|
229
|
+
expect(subject()).toEqual({ branches: { foo: 'bar' } });
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
describe(`${getWebComponentBranchConfigs.name}`, () => {
|
|
235
|
+
const subject = () => getWebComponentBranchConfigs();
|
|
236
|
+
|
|
237
|
+
itReturns(subject, undefined);
|
|
238
|
+
|
|
239
|
+
describe('with "cli.web-component.branches"', () => {
|
|
240
|
+
const content = { cli: { 'web-component': { branches: { foo: 'bar' } } } };
|
|
241
|
+
|
|
242
|
+
beforeEach(() => mockPackageJson(content));
|
|
243
|
+
|
|
244
|
+
test('returns "cli.web-component.branches"', () => {
|
|
245
|
+
expect(subject()).toEqual(content.cli['web-component'].branches);
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
|
|
186
250
|
describe.each([
|
|
187
251
|
{
|
|
188
252
|
fn: isBundle,
|
|
@@ -221,6 +285,7 @@ describe('[startup] Utils', () => {
|
|
|
221
285
|
{ cli: { 'web-component': true } },
|
|
222
286
|
{ cli: { 'web-component': { legacyRoot: true } } },
|
|
223
287
|
{ cli: { 'web-component': { legacyRoot: false } } },
|
|
288
|
+
{ cli: { 'web-component': { branches: { develop: { publishTag: 'qa' } } } } },
|
|
224
289
|
],
|
|
225
290
|
},
|
|
226
291
|
{
|
|
@@ -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(
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
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
|
-
}
|
|
17
|
-
|
|
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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
'
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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
|
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { getWebComponentBranchConfigs, WebComponentBranchConfigs } from './index';
|
|
2
|
+
|
|
3
|
+
function getDefaultConfigs(): Record<string, WebComponentBranchConfigs> {
|
|
4
|
+
return {
|
|
5
|
+
develop: { publishTag: 'dev' },
|
|
6
|
+
dev: { publishTag: 'dev' },
|
|
7
|
+
next: { publishTag: 'next' },
|
|
8
|
+
master: { publishTag: 'prod' },
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function getBranchesConfigs(): Record<string, WebComponentBranchConfigs> {
|
|
13
|
+
const packageConfigs = getWebComponentBranchConfigs();
|
|
14
|
+
const defaultConfigs = getDefaultConfigs();
|
|
15
|
+
|
|
16
|
+
return packageConfigs ?? defaultConfigs;
|
|
17
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
1
2
|
import path from 'path';
|
|
2
3
|
|
|
3
4
|
import { Configuration as WebpackDevServerConfiguration } from 'webpack-dev-server';
|
|
@@ -5,6 +6,7 @@ import { ESLint } from 'eslint';
|
|
|
5
6
|
import { LinterOptions } from 'stylelint';
|
|
6
7
|
import { Config } from '@jest/types';
|
|
7
8
|
import { readJson, readJsonSafe } from './read-json';
|
|
9
|
+
import { log } from './log';
|
|
8
10
|
|
|
9
11
|
export const allowedWebpackDevServerOptions = ['headers', 'port', 'proxy', 'static'] as const;
|
|
10
12
|
|
|
@@ -71,15 +73,24 @@ export enum CommandName {
|
|
|
71
73
|
}
|
|
72
74
|
/* eslint-enable @typescript-eslint/naming-convention */
|
|
73
75
|
|
|
76
|
+
export interface WebComponentBranchConfigs {
|
|
77
|
+
publishTag?: string;
|
|
78
|
+
}
|
|
79
|
+
|
|
74
80
|
interface WebComponentOptions {
|
|
75
|
-
legacyRoot
|
|
81
|
+
legacyRoot?: boolean;
|
|
82
|
+
/**
|
|
83
|
+
* mapping of git branches to configs.
|
|
84
|
+
* Used to separate configs (ex publish tag) depending on current branch
|
|
85
|
+
*/
|
|
86
|
+
branches?: Record<string, WebComponentBranchConfigs>;
|
|
76
87
|
}
|
|
77
88
|
|
|
78
89
|
type Configuration = {
|
|
79
90
|
'legacy'?: boolean;
|
|
80
91
|
'lint'?: { eslint: ESLintConfiguration; stylelint: StylelintConfiguration };
|
|
81
92
|
'test'?: JestConfiguration;
|
|
82
|
-
'web-component'?: boolean | WebComponentOptions;
|
|
93
|
+
'web-component'?: boolean | string | WebComponentOptions;
|
|
83
94
|
'webpack'?: false | WebpackConfiguration;
|
|
84
95
|
} & {
|
|
85
96
|
[key in CommandName]: NodeConfiguration;
|
|
@@ -120,6 +131,35 @@ export function getWebpackConfiguration(locationOrJson?: LocationOrJson) {
|
|
|
120
131
|
return typeof webpack === 'object' ? webpack : {};
|
|
121
132
|
}
|
|
122
133
|
|
|
134
|
+
export function getWebComponentConfiguration(
|
|
135
|
+
locationOrJson: LocationOrJson = './'
|
|
136
|
+
): WebComponentOptions | undefined {
|
|
137
|
+
const config = getConfigurationSafe(locationOrJson)['web-component'];
|
|
138
|
+
|
|
139
|
+
if (config === true) {
|
|
140
|
+
return {};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (typeof config === 'object') {
|
|
144
|
+
return config;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (typeof config === 'string') {
|
|
148
|
+
if (fs.existsSync(config)) {
|
|
149
|
+
return require(path.resolve(config));
|
|
150
|
+
}
|
|
151
|
+
log.warning(`could not find web-component configuration: "${config}"`);
|
|
152
|
+
|
|
153
|
+
return undefined;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export function getWebComponentBranchConfigs(locationOrJson: LocationOrJson = './') {
|
|
158
|
+
const config = getWebComponentConfiguration(locationOrJson);
|
|
159
|
+
|
|
160
|
+
return config?.branches;
|
|
161
|
+
}
|
|
162
|
+
|
|
123
163
|
export function isBundle(locationOrJson?: LocationOrJson) {
|
|
124
164
|
return getConfiguration(locationOrJson).webpack !== false;
|
|
125
165
|
}
|
|
@@ -142,15 +182,13 @@ export function isLegacy(locationOrJson?: LocationOrJson) {
|
|
|
142
182
|
}
|
|
143
183
|
|
|
144
184
|
export function isLegacyRoot() {
|
|
145
|
-
|
|
146
|
-
return typeof config === 'object' && config.legacyRoot === true;
|
|
185
|
+
return getWebComponentConfiguration()?.legacyRoot === true;
|
|
147
186
|
}
|
|
148
187
|
|
|
149
188
|
export function isStyleCheckDisabled() {
|
|
150
189
|
return getWebpackConfiguration()['disable-style-check'] === true;
|
|
151
190
|
}
|
|
152
191
|
|
|
153
|
-
export function isWebComponent() {
|
|
154
|
-
|
|
155
|
-
return config === true || typeof config === 'object';
|
|
192
|
+
export function isWebComponent(locationOrJson: LocationOrJson = './') {
|
|
193
|
+
return !!getWebComponentConfiguration(locationOrJson);
|
|
156
194
|
}
|
package/src/utils/get-folders.ts
CHANGED
|
@@ -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,
|
|
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'),
|