@servicetitan/startup 22.21.0 → 23.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/build.d.ts +1 -0
- package/dist/cli/commands/build.d.ts.map +1 -1
- package/dist/cli/commands/build.js +1 -0
- package/dist/cli/commands/build.js.map +1 -1
- package/dist/cli/commands/bundle-package.d.ts +1 -0
- package/dist/cli/commands/bundle-package.d.ts.map +1 -1
- package/dist/cli/commands/bundle-package.js +1 -0
- package/dist/cli/commands/bundle-package.js.map +1 -1
- package/dist/cli/commands/init.d.ts +8 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +25 -3
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/start.d.ts +1 -0
- package/dist/cli/commands/start.d.ts.map +1 -1
- package/dist/cli/commands/start.js +1 -0
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/utils/bundle.d.ts +1 -0
- package/dist/cli/utils/bundle.d.ts.map +1 -1
- package/dist/cli/utils/bundle.js +11 -5
- package/dist/cli/utils/bundle.js.map +1 -1
- package/dist/cli/utils/compile-sass.d.ts +1 -1
- package/dist/cli/utils/compile-sass.d.ts.map +1 -1
- package/dist/cli/utils/compile-sass.js +13 -5
- package/dist/cli/utils/compile-sass.js.map +1 -1
- package/dist/cli/utils/tcm.d.ts.map +1 -1
- package/dist/cli/utils/tcm.js +14 -7
- package/dist/cli/utils/tcm.js.map +1 -1
- package/dist/utils/get-jest-config.d.ts.map +1 -1
- package/dist/utils/get-jest-config.js +18 -13
- package/dist/utils/get-jest-config.js.map +1 -1
- package/dist/webpack/configs/rules/tsx-rules.d.ts +1 -1
- package/dist/webpack/configs/rules/tsx-rules.d.ts.map +1 -1
- package/dist/webpack/configs/rules/tsx-rules.js +10 -8
- package/dist/webpack/configs/rules/tsx-rules.js.map +1 -1
- package/dist/webpack/configs/types.d.ts +1 -0
- package/dist/webpack/configs/types.d.ts.map +1 -1
- package/dist/webpack/create-webpack-config.d.ts.map +1 -1
- package/dist/webpack/create-webpack-config.js +2 -2
- package/dist/webpack/create-webpack-config.js.map +1 -1
- package/dist/webpack/types.d.ts +3 -2
- package/dist/webpack/types.d.ts.map +1 -1
- package/dist/webpack/utils/testing/normalize-errors.js +1 -1
- package/dist/webpack/utils/testing/normalize-errors.js.map +1 -1
- package/package.json +15 -13
- package/src/cli/commands/__tests__/build.test.ts +14 -0
- package/src/cli/commands/__tests__/init.test.ts +48 -17
- package/src/cli/commands/__tests__/start.test.ts +14 -0
- package/src/cli/commands/build.ts +2 -0
- package/src/cli/commands/bundle-package.ts +2 -0
- package/src/cli/commands/init.ts +26 -12
- package/src/cli/commands/start.ts +2 -0
- package/src/cli/utils/__tests__/tcm.test.ts +15 -6
- package/src/cli/utils/bundle.ts +14 -5
- package/src/cli/utils/compile-sass.ts +3 -7
- package/src/cli/utils/tcm.ts +13 -11
- package/src/utils/__tests__/get-jest-config.test.ts +15 -38
- package/src/utils/get-jest-config.ts +32 -45
- package/src/webpack/__tests__/create-webpack-config.test.ts +25 -3
- package/src/webpack/configs/rules/tsx-rules.ts +13 -9
- package/src/webpack/configs/types.ts +1 -0
- package/src/webpack/create-webpack-config.ts +3 -2
- package/src/webpack/loaders/expose-loader/__tests__/__snapshots__/index.test.ts.snap +14 -14
- package/src/webpack/types.ts +3 -2
- package/src/webpack/utils/testing/normalize-errors.ts +1 -1
- package/template/package.json +3 -3
- package/template/packages/application/package.json +6 -0
- package/template/packages/application/src/__tests__/app.test.tsx +1 -1
- package/template/packages/application/src/app.tsx +4 -3
- package/template-react18/packages/application/package.json +35 -0
- package/template-react18/packages/application/src/index.tsx +9 -0
- package/template-react18/packages/feature-a/package.json +19 -0
- package/template-react18/packages/feature-b/package.json +19 -0
- package/template-react18/packages/feature-c/package.json +19 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/webpack/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iCAAiC,EAAE,MAAM,mDAAmD,CAAC;AACtG,OAAO,EAAE,OAAO,IAAI,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,aAAa,IAAI,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AACvF,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAExC,MAAM,WAAW,OAAO;IACpB,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/webpack/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iCAAiC,EAAE,MAAM,mDAAmD,CAAC;AACtG,OAAO,EAAE,OAAO,IAAI,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,aAAa,IAAI,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AACvF,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAExC,MAAM,WAAW,OAAO;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACtB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,OAAO,CAAC,EAAE;QACN,0BAA0B,CAAC,EAAE,iCAAiC,CAAC;QAC/D,iBAAiB,CAAC,EAAE,wBAAwB,CAAC;QAC7C,oBAAoB,CAAC,EAAE,2BAA2B,CAAC;KACtD,CAAC;CACL"}
|
|
@@ -12,7 +12,7 @@ function removeCWD(str) {
|
|
|
12
12
|
return str.replace(new RegExp(cwd, 'g'), '');
|
|
13
13
|
}
|
|
14
14
|
function normalizeErrors(errors) {
|
|
15
|
-
return errors.map(error => removeCWD(error.
|
|
15
|
+
return errors.map(error => removeCWD(error.message.split('\n').slice(0, 2).join('\n')));
|
|
16
16
|
}
|
|
17
17
|
exports.normalizeErrors = normalizeErrors;
|
|
18
18
|
//# sourceMappingURL=normalize-errors.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize-errors.js","sourceRoot":"","sources":["../../../../src/webpack/utils/testing/normalize-errors.ts"],"names":[],"mappings":";;;AAEA,SAAS,SAAS,CAAC,GAAW;IAC1B,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC;IAC3C,IAAI,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAExB,IAAI,KAAK,EAAE;QACP,6CAA6C;QAC7C,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC9B,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;KACjC;IAED,OAAO,GAAG,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;AACjD,CAAC;AAED,SAAgB,eAAe,CAAC,MAAsB;IAClD,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"normalize-errors.js","sourceRoot":"","sources":["../../../../src/webpack/utils/testing/normalize-errors.ts"],"names":[],"mappings":";;;AAEA,SAAS,SAAS,CAAC,GAAW;IAC1B,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC;IAC3C,IAAI,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAExB,IAAI,KAAK,EAAE;QACP,6CAA6C;QAC7C,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC9B,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;KACjC;IAED,OAAO,GAAG,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;AACjD,CAAC;AAED,SAAgB,eAAe,CAAC,MAAsB;IAClD,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC5F,CAAC;AAFD,0CAEC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@servicetitan/startup",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "23.1.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"homepage": "https://docs.st.dev/docs/frontend/startup",
|
|
6
6
|
"repository": {
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"jest",
|
|
17
17
|
"src",
|
|
18
18
|
"template",
|
|
19
|
+
"template-react18",
|
|
19
20
|
"template/.gitignore",
|
|
20
21
|
"template/.npmrc",
|
|
21
22
|
"tsconfig",
|
|
@@ -24,7 +25,7 @@
|
|
|
24
25
|
"bin": "./bin/index.js",
|
|
25
26
|
"devDependencies": {
|
|
26
27
|
"@types/cpx": "~1.5.2",
|
|
27
|
-
"@types/eslint": "~8.
|
|
28
|
+
"@types/eslint": "~8.56.3",
|
|
28
29
|
"@types/less": "~3.0.3",
|
|
29
30
|
"@types/mini-css-extract-plugin": "~2.4.0",
|
|
30
31
|
"@types/moment-locales-webpack-plugin": "~1.2.2",
|
|
@@ -35,11 +36,11 @@
|
|
|
35
36
|
},
|
|
36
37
|
"dependencies": {
|
|
37
38
|
"@babel/preset-env": "~7.22.20",
|
|
38
|
-
"@jest/core": "~
|
|
39
|
-
"@jest/types": "~
|
|
39
|
+
"@jest/core": "~29.7.0",
|
|
40
|
+
"@jest/types": "~29.6.3",
|
|
40
41
|
"@lerna/exec": "~5.6.2",
|
|
41
|
-
"@servicetitan/eslint-config": "
|
|
42
|
-
"@servicetitan/stylelint-config": "
|
|
42
|
+
"@servicetitan/eslint-config": "23.1.0",
|
|
43
|
+
"@servicetitan/stylelint-config": "23.1.0",
|
|
43
44
|
"@swc/core": "1.3.100",
|
|
44
45
|
"@types/jest": "~27.4.0",
|
|
45
46
|
"chalk": "~4.1.2",
|
|
@@ -49,20 +50,21 @@
|
|
|
49
50
|
"debug": "^4.3.4",
|
|
50
51
|
"deepmerge": "~4.3.1",
|
|
51
52
|
"esbuild-loader": "~4.0.2",
|
|
52
|
-
"eslint": "~8.
|
|
53
|
+
"eslint": "~8.57.0",
|
|
53
54
|
"execa": "~5.1.1",
|
|
54
55
|
"fork-ts-checker-webpack-plugin": "~7.3.0",
|
|
55
56
|
"glob": "~7.2.0",
|
|
56
57
|
"html-webpack-plugin": "~5.5.3",
|
|
57
58
|
"identity-obj-proxy": "~3.0.0",
|
|
58
|
-
"jest": "~
|
|
59
|
-
"jest-circus": "~
|
|
59
|
+
"jest": "~29.7.0",
|
|
60
|
+
"jest-circus": "~29.7.0",
|
|
61
|
+
"jest-environment-jsdom": "^29.7.0",
|
|
60
62
|
"jest-fetch-mock": "~3.0.3",
|
|
61
63
|
"lerna": "~5.6.2",
|
|
62
64
|
"less": "~4.2.0",
|
|
63
65
|
"less-loader": "~10.2.0",
|
|
64
66
|
"less-plugin-npm-import": "~2.1.0",
|
|
65
|
-
"memfs": "~4.
|
|
67
|
+
"memfs": "~4.7.7",
|
|
66
68
|
"mini-css-extract-plugin": "~2.7.6",
|
|
67
69
|
"moment": "^2.29.4",
|
|
68
70
|
"moment-locales-webpack-plugin": "~1.2.0",
|
|
@@ -74,10 +76,10 @@
|
|
|
74
76
|
"style-loader": "~3.3.3",
|
|
75
77
|
"stylelint": "~14.16.1",
|
|
76
78
|
"swc-loader": "0.2.3",
|
|
77
|
-
"ts-jest": "~
|
|
79
|
+
"ts-jest": "~29.1.2",
|
|
78
80
|
"ts-loader": "~9.4.4",
|
|
79
81
|
"ts-node": "~10.9.1",
|
|
80
|
-
"typed-css-modules": "~0.
|
|
82
|
+
"typed-css-modules": "~0.8.1",
|
|
81
83
|
"typescript": "~4.7.4",
|
|
82
84
|
"username": "~5.1.0",
|
|
83
85
|
"webpack": "~5.78.0",
|
|
@@ -97,5 +99,5 @@
|
|
|
97
99
|
"cli": {
|
|
98
100
|
"webpack": false
|
|
99
101
|
},
|
|
100
|
-
"gitHead": "
|
|
102
|
+
"gitHead": "7267270e54cdb3a2926f61feb4939d057e82adb3"
|
|
101
103
|
}
|
|
@@ -73,6 +73,20 @@ describe(`[startup] ${Build.name}`, () => {
|
|
|
73
73
|
});
|
|
74
74
|
});
|
|
75
75
|
|
|
76
|
+
describe('with "code-coverage"', () => {
|
|
77
|
+
beforeEach(() => (args['code-coverage'] = true));
|
|
78
|
+
|
|
79
|
+
test('enables code-coverage', async () => {
|
|
80
|
+
await subject();
|
|
81
|
+
|
|
82
|
+
expect(exec).toHaveBeenCalledWith(
|
|
83
|
+
expect.objectContaining({
|
|
84
|
+
'--': ['--code-coverage'],
|
|
85
|
+
})
|
|
86
|
+
);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
76
90
|
describe('with "esbuild"', () => {
|
|
77
91
|
beforeEach(() => (args.esbuild = true));
|
|
78
92
|
|
|
@@ -13,32 +13,63 @@ jest.mock('cpx', () => ({
|
|
|
13
13
|
}),
|
|
14
14
|
}));
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
jest.mock('../../../utils', () => ({
|
|
17
|
+
log: { info: jest.fn() }, // suppress log output
|
|
18
|
+
}));
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
describe(`[startup] ${Init.name}`, () => {
|
|
21
|
+
let args: ConstructorParameters<typeof Init>[0];
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
expect.anything()
|
|
27
|
-
);
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
args = {};
|
|
25
|
+
vol.reset();
|
|
28
26
|
});
|
|
29
27
|
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
const subject = async () => new Init(args).execute();
|
|
29
|
+
|
|
30
|
+
function itCopies(...names: string[]) {
|
|
31
|
+
test.each(names)(`copies %s to current directory`, async (name: string) => {
|
|
32
|
+
await subject();
|
|
33
|
+
|
|
34
|
+
expect(cpx.copy).toHaveBeenCalledWith(
|
|
35
|
+
expect.stringContaining(path.join(name, '**', '{.*,*,.*/*}')),
|
|
36
|
+
process.cwd(),
|
|
37
|
+
expect.anything()
|
|
38
|
+
);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
itCopies('template');
|
|
43
|
+
|
|
44
|
+
describe('when instructed to create React 18 template', () => {
|
|
45
|
+
beforeEach(() => (args.react18 = true));
|
|
46
|
+
|
|
47
|
+
itCopies('template', 'template-react18');
|
|
48
|
+
});
|
|
32
49
|
|
|
33
|
-
|
|
50
|
+
describe('with an output location', () => {
|
|
51
|
+
beforeEach(() => (args.output = 'foo/bar'));
|
|
34
52
|
|
|
35
|
-
|
|
53
|
+
test('copies template to output location', async () => {
|
|
54
|
+
const mkdirSpy = jest.spyOn(fs, 'mkdirSync');
|
|
55
|
+
const destination = path.resolve(args.output!);
|
|
36
56
|
|
|
37
|
-
test(`moves ${gitIgnoreAlias} -> .gitignore`, async () => {
|
|
38
57
|
await subject();
|
|
39
58
|
|
|
40
|
-
expect(
|
|
41
|
-
expect(
|
|
59
|
+
expect(mkdirSpy).toHaveBeenCalledWith(destination, { recursive: true });
|
|
60
|
+
expect(cpx.copy).toHaveBeenCalledWith(
|
|
61
|
+
expect.any(String),
|
|
62
|
+
destination,
|
|
63
|
+
expect.anything()
|
|
64
|
+
);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
describe('when output location is a file', () => {
|
|
68
|
+
beforeEach(() => vol.fromJSON({ [args.output!]: '' }));
|
|
69
|
+
|
|
70
|
+
test('raises error', async () => {
|
|
71
|
+
await expect(subject()).rejects.toThrowError(/is not a directory/);
|
|
72
|
+
});
|
|
42
73
|
});
|
|
43
74
|
});
|
|
44
75
|
});
|
|
@@ -75,6 +75,20 @@ describe(`[startup] ${Start.name}`, () => {
|
|
|
75
75
|
});
|
|
76
76
|
});
|
|
77
77
|
|
|
78
|
+
describe('with "code-coverage"', () => {
|
|
79
|
+
beforeEach(() => (args['code-coverage'] = true));
|
|
80
|
+
|
|
81
|
+
test('enables code-coverage', async () => {
|
|
82
|
+
await subject();
|
|
83
|
+
|
|
84
|
+
expect(exec).toHaveBeenCalledWith(
|
|
85
|
+
expect.objectContaining({
|
|
86
|
+
'--': ['--watch', '--code-coverage'],
|
|
87
|
+
})
|
|
88
|
+
);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
78
92
|
describe('with "esbuild"', () => {
|
|
79
93
|
beforeEach(() => (args.esbuild = true));
|
|
80
94
|
|
|
@@ -6,6 +6,7 @@ import { Command, kendoUILicense } from '.';
|
|
|
6
6
|
|
|
7
7
|
interface Args {
|
|
8
8
|
'cdn-path'?: string;
|
|
9
|
+
'code-coverage'?: boolean;
|
|
9
10
|
'config'?: string;
|
|
10
11
|
'esbuild'?: boolean;
|
|
11
12
|
'experimental-bundlers'?: boolean;
|
|
@@ -51,6 +52,7 @@ export class Build implements Command {
|
|
|
51
52
|
'stream': true,
|
|
52
53
|
'--': [
|
|
53
54
|
...[this.args.config ? `--config "${this.args.config}"` : undefined],
|
|
55
|
+
...[this.args['code-coverage'] ? '--code-coverage' : undefined],
|
|
54
56
|
...[this.args.esbuild ? '--esbuild' : undefined],
|
|
55
57
|
...[this.args['experimental-bundlers'] ? '--experimental-bundlers' : undefined],
|
|
56
58
|
...[this.args.stat ? '--stat' : undefined],
|
|
@@ -6,6 +6,7 @@ import { Command } from '.';
|
|
|
6
6
|
|
|
7
7
|
interface Args {
|
|
8
8
|
'config'?: string;
|
|
9
|
+
'code-coverage'?: boolean;
|
|
9
10
|
'stat'?: boolean;
|
|
10
11
|
'watch'?: boolean;
|
|
11
12
|
'esbuild'?: boolean;
|
|
@@ -29,6 +30,7 @@ export class BundlePackage implements Command {
|
|
|
29
30
|
|
|
30
31
|
const options = {
|
|
31
32
|
config,
|
|
33
|
+
codeCoverage: this.args['code-coverage'],
|
|
32
34
|
esbuild: this.args.esbuild,
|
|
33
35
|
experimentalBundlers: this.args['experimental-bundlers'],
|
|
34
36
|
};
|
package/src/cli/commands/init.ts
CHANGED
|
@@ -3,22 +3,36 @@ import cpx from 'cpx';
|
|
|
3
3
|
import util from 'util';
|
|
4
4
|
import path from 'path';
|
|
5
5
|
|
|
6
|
-
import { logErrors } from '../../utils';
|
|
7
|
-
import { Command } from '
|
|
6
|
+
import { log, logErrors } from '../../utils';
|
|
7
|
+
import { Command } from './';
|
|
8
|
+
|
|
9
|
+
interface Args {
|
|
10
|
+
react18?: boolean;
|
|
11
|
+
output?: string;
|
|
12
|
+
}
|
|
8
13
|
|
|
9
14
|
export class Init implements Command {
|
|
15
|
+
constructor(private args: Args) {}
|
|
16
|
+
|
|
10
17
|
@logErrors
|
|
11
18
|
async execute() {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
)
|
|
16
|
-
|
|
17
|
-
if (fs.existsSync(path.join(process.cwd(), '.npmignore'))) {
|
|
18
|
-
fs.renameSync(
|
|
19
|
-
path.join(process.cwd(), '.npmignore'),
|
|
20
|
-
path.join(process.cwd(), '.gitignore')
|
|
21
|
-
);
|
|
19
|
+
const destination = path.resolve(this.args.output ?? '.');
|
|
20
|
+
if (!fs.existsSync(destination)) {
|
|
21
|
+
fs.mkdirSync(destination, { recursive: true });
|
|
22
|
+
} else if (!fs.lstatSync(destination).isDirectory()) {
|
|
23
|
+
throw new Error(`${destination} is not a directory`);
|
|
22
24
|
}
|
|
25
|
+
|
|
26
|
+
await copyFiles('template', destination);
|
|
27
|
+
|
|
28
|
+
if (this.args.react18) {
|
|
29
|
+
await copyFiles('template-react18', destination);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
log.info(`copied${this.args.react18 ? ' React 18' : ''} template to ${destination}`);
|
|
23
33
|
}
|
|
24
34
|
}
|
|
35
|
+
|
|
36
|
+
async function copyFiles(from: string, to: string) {
|
|
37
|
+
await util.promisify(cpx.copy)(path.resolve(__dirname, `../../../${from}/**/{.*,*,.*/*}`), to);
|
|
38
|
+
}
|
|
@@ -6,6 +6,7 @@ import { Command } from '.';
|
|
|
6
6
|
|
|
7
7
|
interface Args {
|
|
8
8
|
'config'?: string;
|
|
9
|
+
'code-coverage'?: boolean;
|
|
9
10
|
'esbuild'?: boolean;
|
|
10
11
|
'experimental-bundlers'?: boolean;
|
|
11
12
|
'ignore'?: string | string[];
|
|
@@ -60,6 +61,7 @@ export class Start implements Command {
|
|
|
60
61
|
'--': [
|
|
61
62
|
'--watch',
|
|
62
63
|
this.args.config ? `--config "${this.args.config}"` : undefined,
|
|
64
|
+
this.args['code-coverage'] ? '--code-coverage' : undefined,
|
|
63
65
|
this.args.esbuild ? '--esbuild' : undefined,
|
|
64
66
|
this.args['experimental-bundlers']
|
|
65
67
|
? '--experimental-bundlers'
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @jest-environment node
|
|
3
|
+
*/
|
|
2
4
|
import chokidar from 'chokidar';
|
|
5
|
+
import fs from 'fs';
|
|
3
6
|
|
|
4
7
|
import { getFolders, log } from '../../../utils';
|
|
5
8
|
import * as sassModule from '../compile-sass';
|
|
@@ -7,26 +10,32 @@ import * as sassModule from '../compile-sass';
|
|
|
7
10
|
import { styleExtensions } from '..';
|
|
8
11
|
import { tcm, tcmWatch } from '../tcm';
|
|
9
12
|
|
|
10
|
-
jest.mock('fs', () => fs);
|
|
11
13
|
jest.mock('../../../utils', () => ({
|
|
12
14
|
...jest.requireActual('../../../utils'),
|
|
13
15
|
getFolders: jest.fn(),
|
|
14
16
|
log: { error: jest.fn(), info: jest.fn() }, // suppress test output
|
|
15
17
|
}));
|
|
16
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Note: These tests don't use memfs because the typed-css-modules package
|
|
21
|
+
* uses node: URLs to import the fs modules, which bypasses the memfs filesystem
|
|
22
|
+
* (as of memfs ~4.6.0).
|
|
23
|
+
*/
|
|
24
|
+
|
|
17
25
|
describe('[startup] Cli Utils', () => {
|
|
18
|
-
const source = 'src';
|
|
26
|
+
const source = fs.mkdtempSync('src');
|
|
19
27
|
|
|
20
28
|
beforeEach(() => {
|
|
21
29
|
jest.resetAllMocks();
|
|
22
30
|
jest.mocked(getFolders).mockReturnValue({ source, destination: undefined });
|
|
31
|
+
fs.readdirSync(source).forEach(file => fs.rmSync(`${source}/${file}`));
|
|
23
32
|
});
|
|
24
33
|
|
|
25
|
-
|
|
34
|
+
afterAll(() => fs.rmSync(source, { recursive: true }));
|
|
26
35
|
|
|
27
36
|
function mockStylesModule(module: string, id = 'foo') {
|
|
28
37
|
const content = `.${id} { display: none; }`;
|
|
29
|
-
|
|
38
|
+
fs.writeFileSync(`${source}/${module}`, content);
|
|
30
39
|
}
|
|
31
40
|
|
|
32
41
|
function expectTypeDefinitions(module: string, id = 'foo') {
|
|
@@ -78,7 +87,7 @@ describe('[startup] Cli Utils', () => {
|
|
|
78
87
|
beforeEach(() => {
|
|
79
88
|
fsWatcher = { on: jest.fn() };
|
|
80
89
|
watchSpy = jest.spyOn(chokidar, 'watch').mockReturnValue(fsWatcher as any);
|
|
81
|
-
|
|
90
|
+
fs.writeFileSync(`${source}/foo.bar`, '');
|
|
82
91
|
});
|
|
83
92
|
|
|
84
93
|
const subject = () => tcmWatch();
|
package/src/cli/utils/bundle.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { Overrides, createWebpackConfig } from '../../webpack';
|
|
|
11
11
|
|
|
12
12
|
interface Options {
|
|
13
13
|
buildStat?: boolean;
|
|
14
|
+
codeCoverage?: boolean;
|
|
14
15
|
config?: string;
|
|
15
16
|
esbuild?: boolean;
|
|
16
17
|
experimentalBundlers?: boolean;
|
|
@@ -35,7 +36,7 @@ export async function bundle(options: Options = {}) {
|
|
|
35
36
|
const mode = 'production';
|
|
36
37
|
const fallback = `./${webpackProdConfigFileName}`;
|
|
37
38
|
const config = readWebpackConfig({ ...options, fallback });
|
|
38
|
-
const { buildStat, esbuild, experimentalBundlers } = options;
|
|
39
|
+
const { buildStat, codeCoverage, esbuild, experimentalBundlers } = options;
|
|
39
40
|
|
|
40
41
|
const run = async (config: Configuration) => {
|
|
41
42
|
const compiler = webpack(config);
|
|
@@ -57,7 +58,7 @@ export async function bundle(options: Options = {}) {
|
|
|
57
58
|
process.stdout.write(stats.toString(config.stats) + '\n');
|
|
58
59
|
};
|
|
59
60
|
|
|
60
|
-
const webpackOptions = { name, buildStat, esbuild, experimentalBundlers };
|
|
61
|
+
const webpackOptions = { name, buildStat, codeCoverage, esbuild, experimentalBundlers };
|
|
61
62
|
|
|
62
63
|
if (isWebComponent()) {
|
|
63
64
|
const webpackConfig: Overrides = {
|
|
@@ -80,7 +81,7 @@ export async function bundleWatch(options: Options = {}) {
|
|
|
80
81
|
const name = getName();
|
|
81
82
|
const mode = 'development';
|
|
82
83
|
const config = readWebpackConfig({ ...options, fallback: `./${webpackDevConfigFileName}` });
|
|
83
|
-
const { esbuild, experimentalBundlers } = options;
|
|
84
|
+
const { codeCoverage, esbuild, experimentalBundlers } = options;
|
|
84
85
|
|
|
85
86
|
const runServe = async ({ devServer = {}, ...config }: Configuration) => {
|
|
86
87
|
const compiler = webpack(config);
|
|
@@ -125,13 +126,21 @@ export async function bundleWatch(options: Options = {}) {
|
|
|
125
126
|
return Promise.all([
|
|
126
127
|
run(
|
|
127
128
|
createWebpackConfig(webpackConfig, {
|
|
129
|
+
codeCoverage,
|
|
128
130
|
embed: true,
|
|
129
131
|
name,
|
|
130
132
|
esbuild,
|
|
131
133
|
experimentalBundlers,
|
|
132
134
|
})
|
|
133
135
|
),
|
|
134
|
-
runServe(
|
|
136
|
+
runServe(
|
|
137
|
+
createWebpackConfig(webpackConfig, {
|
|
138
|
+
name,
|
|
139
|
+
codeCoverage,
|
|
140
|
+
esbuild,
|
|
141
|
+
experimentalBundlers,
|
|
142
|
+
})
|
|
143
|
+
),
|
|
135
144
|
]);
|
|
136
145
|
}
|
|
137
146
|
|
|
@@ -139,7 +148,7 @@ export async function bundleWatch(options: Options = {}) {
|
|
|
139
148
|
config ??
|
|
140
149
|
createWebpackConfig(
|
|
141
150
|
{ configuration: { mode } },
|
|
142
|
-
{ name, esbuild, experimentalBundlers }
|
|
151
|
+
{ name, codeCoverage, esbuild, experimentalBundlers }
|
|
143
152
|
)
|
|
144
153
|
);
|
|
145
154
|
}
|
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
1
|
import path from 'path';
|
|
3
2
|
|
|
4
3
|
import sass from 'sass';
|
|
5
4
|
|
|
6
|
-
export function compileSass(filePath: string) {
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
includePaths: [path.dirname(filePath), '../../node_modules', 'node_modules'],
|
|
10
|
-
});
|
|
11
|
-
|
|
5
|
+
export async function compileSass(filePath: string) {
|
|
6
|
+
const loadPaths = [path.dirname(filePath), '../../node_modules', 'node_modules'];
|
|
7
|
+
const result = await sass.compileAsync(filePath, { loadPaths });
|
|
12
8
|
return result.css.toString();
|
|
13
9
|
}
|
package/src/cli/utils/tcm.ts
CHANGED
|
@@ -11,10 +11,19 @@ interface RunOptions {
|
|
|
11
11
|
watch?: boolean;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
async function compile(filePath: string) {
|
|
15
|
+
if (filePath.endsWith('.less')) {
|
|
16
|
+
return compileLess(filePath);
|
|
17
|
+
}
|
|
18
|
+
if (filePath.endsWith('.scss')) {
|
|
19
|
+
return compileSass(filePath);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
14
23
|
async function run({ watch }: RunOptions = {}) {
|
|
15
24
|
const { source } = getFolders();
|
|
16
25
|
|
|
17
|
-
const filesPattern = `${source}/**/*.module.{${styleExtensions.join()}}
|
|
26
|
+
const filesPattern = `${source}/**/*.module.{${styleExtensions.join()}}`.replace(/\\/g, '/');
|
|
18
27
|
|
|
19
28
|
const creator = new DtsCreator({
|
|
20
29
|
camelCase: true,
|
|
@@ -23,15 +32,8 @@ async function run({ watch }: RunOptions = {}) {
|
|
|
23
32
|
|
|
24
33
|
const writeFile = async (filePath: string) => {
|
|
25
34
|
try {
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
filePath.endsWith('.less')
|
|
29
|
-
? await compileLess(filePath)
|
|
30
|
-
: filePath.endsWith('.scss')
|
|
31
|
-
? compileSass(filePath)
|
|
32
|
-
: undefined,
|
|
33
|
-
!!watch
|
|
34
|
-
);
|
|
35
|
+
const initialContents = await compile(filePath);
|
|
36
|
+
const content = await creator.create(filePath, initialContents, !!watch);
|
|
35
37
|
await content.writeFile();
|
|
36
38
|
} catch (error) {
|
|
37
39
|
log.error(String(error));
|
|
@@ -45,7 +47,7 @@ async function run({ watch }: RunOptions = {}) {
|
|
|
45
47
|
} else {
|
|
46
48
|
log.info('Watch ' + filesPattern + '...');
|
|
47
49
|
|
|
48
|
-
const watcher = chokidar.watch([filesPattern
|
|
50
|
+
const watcher = chokidar.watch([filesPattern], { ignoreInitial: true });
|
|
49
51
|
watcher.on('add', writeFile);
|
|
50
52
|
watcher.on('change', writeFile);
|
|
51
53
|
|
|
@@ -13,23 +13,22 @@ jest.mock('../get-configuration', () => ({
|
|
|
13
13
|
|
|
14
14
|
describe('[startup] Utils', () => {
|
|
15
15
|
const destinationFolders = ['dist'];
|
|
16
|
-
const defaultConfig = {
|
|
16
|
+
const defaultConfig: Record<string, any> = {
|
|
17
17
|
verbose: true,
|
|
18
18
|
testEnvironment: 'jsdom',
|
|
19
19
|
testRunner: 'jest-circus/runner',
|
|
20
|
-
transformIgnorePatterns: ['node_modules/(
|
|
20
|
+
transformIgnorePatterns: ['node_modules/(?!(@servicetitan|@react-hook|nanoid|axios)/)'],
|
|
21
21
|
modulePathIgnorePatterns: ['<rootDir>/.*/__mocks__'],
|
|
22
22
|
transform: {
|
|
23
23
|
'^.+\\.jsx?$': [
|
|
24
24
|
'babel-jest',
|
|
25
25
|
{ presets: [['@babel/preset-env', { targets: { node: 'current' } }]] },
|
|
26
26
|
],
|
|
27
|
-
'^.+\\.tsx?$': 'ts-jest',
|
|
27
|
+
'^.+\\.tsx?$': ['ts-jest', { tsconfig: './tsconfig.test.json' }],
|
|
28
28
|
},
|
|
29
29
|
moduleNameMapper: {
|
|
30
30
|
'\\.(css|scss|less|png|svg|jpg|jpeg|gif|woff|woff2|eot|ttf|otf)$': 'identity-obj-proxy',
|
|
31
31
|
},
|
|
32
|
-
globals: { 'ts-jest': { tsconfig: './tsconfig.test.json' } },
|
|
33
32
|
testPathIgnorePatterns: ['\\.yalc', ...destinationFolders],
|
|
34
33
|
setupFiles: [expect.stringContaining(path.join('jest', 'setup.js'))],
|
|
35
34
|
coveragePathIgnorePatterns: ['^.+\\.d\\.ts$'],
|
|
@@ -73,25 +72,6 @@ describe('[startup] Utils', () => {
|
|
|
73
72
|
}
|
|
74
73
|
);
|
|
75
74
|
|
|
76
|
-
describe.each(['globals'])(
|
|
77
|
-
'with custom "%s"',
|
|
78
|
-
(option: keyof Pick<typeof defaultConfig, 'globals'>) => {
|
|
79
|
-
const customValue = { foo: 'bar' };
|
|
80
|
-
|
|
81
|
-
beforeEach(() => {
|
|
82
|
-
jest.mocked(getJestConfiguration).mockReturnValue({ [option]: customValue });
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
test(`merges custom value with "${option}"`, () => {
|
|
86
|
-
expect(subject()).toEqual(
|
|
87
|
-
expect.objectContaining({
|
|
88
|
-
[option]: { ...defaultConfig[option], ...customValue },
|
|
89
|
-
})
|
|
90
|
-
);
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
);
|
|
94
|
-
|
|
95
75
|
describe('with other custom options', () => {
|
|
96
76
|
const customOptions = { resetMocks: true, testEnvironment: 'node' };
|
|
97
77
|
|
|
@@ -104,31 +84,28 @@ describe('[startup] Utils', () => {
|
|
|
104
84
|
});
|
|
105
85
|
|
|
106
86
|
describe(`${getJestConfigCLI.name}`, () => {
|
|
107
|
-
|
|
87
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
88
|
+
const args: Config.Argv = { _: [], $0: '', runInBand: true };
|
|
89
|
+
const globals = { foo: 'bar' };
|
|
108
90
|
|
|
109
91
|
const subject = () => getJestConfigCLI(args);
|
|
110
92
|
|
|
111
93
|
beforeEach(() => {
|
|
112
|
-
|
|
113
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
114
|
-
args = { _: [], $0: '', ...commandLineOptions };
|
|
94
|
+
jest.mocked(getJestConfiguration).mockReturnValue({ globals });
|
|
115
95
|
});
|
|
116
96
|
|
|
117
|
-
const stringified
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
];
|
|
97
|
+
const stringified = ['collectCoverageFrom', 'moduleNameMapper', 'transform'].reduce(
|
|
98
|
+
(result, key) => ({ ...result, [key]: JSON.stringify(defaultConfig[key]) }),
|
|
99
|
+
{ globals: JSON.stringify(globals) }
|
|
100
|
+
);
|
|
122
101
|
|
|
123
|
-
test(`merges command line args with default config and stringifies "${
|
|
124
|
-
|
|
125
|
-
)}"`, () => {
|
|
102
|
+
test(`merges command line args with default config and stringifies "${Object.keys(
|
|
103
|
+
stringified
|
|
104
|
+
).join('", "')}"`, () => {
|
|
126
105
|
expect(subject()).toEqual({
|
|
127
106
|
...defaultConfig,
|
|
128
107
|
...args,
|
|
129
|
-
...
|
|
130
|
-
stringified.map(option => [option, JSON.stringify(defaultConfig[option])])
|
|
131
|
-
),
|
|
108
|
+
...stringified,
|
|
132
109
|
});
|
|
133
110
|
});
|
|
134
111
|
});
|