@servicetitan/startup 28.5.0 → 30.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 (136) hide show
  1. package/bin/index.js +1 -1
  2. package/dist/cli/commands/convert-eslint-config.d.ts +21 -0
  3. package/dist/cli/commands/convert-eslint-config.d.ts.map +1 -0
  4. package/dist/cli/commands/convert-eslint-config.js +235 -0
  5. package/dist/cli/commands/convert-eslint-config.js.map +1 -0
  6. package/dist/cli/commands/get-command.d.ts.map +1 -1
  7. package/dist/cli/commands/get-command.js +6 -0
  8. package/dist/cli/commands/get-command.js.map +1 -1
  9. package/dist/cli/commands/init.d.ts.map +1 -1
  10. package/dist/cli/commands/init.js +4 -3
  11. package/dist/cli/commands/init.js.map +1 -1
  12. package/dist/cli/commands/lint.d.ts +1 -1
  13. package/dist/cli/commands/lint.js +2 -2
  14. package/dist/cli/commands/mfe-package-clean.d.ts +5 -1
  15. package/dist/cli/commands/mfe-package-clean.d.ts.map +1 -1
  16. package/dist/cli/commands/mfe-package-clean.js +46 -36
  17. package/dist/cli/commands/mfe-package-clean.js.map +1 -1
  18. package/dist/cli/commands/mfe-package-publish.d.ts +1 -1
  19. package/dist/cli/commands/mfe-package-publish.d.ts.map +1 -1
  20. package/dist/cli/commands/mfe-package-publish.js +3 -13
  21. package/dist/cli/commands/mfe-package-publish.js.map +1 -1
  22. package/dist/cli/commands/mfe-publish.d.ts.map +1 -1
  23. package/dist/cli/commands/mfe-publish.js +6 -5
  24. package/dist/cli/commands/mfe-publish.js.map +1 -1
  25. package/dist/cli/commands/run-task.d.ts +13 -0
  26. package/dist/cli/commands/run-task.d.ts.map +1 -0
  27. package/dist/cli/commands/run-task.js +53 -0
  28. package/dist/cli/commands/run-task.js.map +1 -0
  29. package/dist/cli/index.js +13 -4
  30. package/dist/cli/index.js.map +1 -1
  31. package/dist/cli/tasks/cli-task.d.ts +16 -0
  32. package/dist/cli/tasks/cli-task.d.ts.map +1 -0
  33. package/dist/cli/tasks/cli-task.js +58 -0
  34. package/dist/cli/tasks/cli-task.js.map +1 -0
  35. package/dist/cli/tasks/swc-compile-package.d.ts +12 -0
  36. package/dist/cli/tasks/swc-compile-package.d.ts.map +1 -0
  37. package/dist/cli/tasks/swc-compile-package.js +66 -0
  38. package/dist/cli/tasks/swc-compile-package.js.map +1 -0
  39. package/dist/cli/tasks/task.d.ts +42 -0
  40. package/dist/cli/tasks/task.d.ts.map +1 -0
  41. package/dist/cli/tasks/task.js +113 -0
  42. package/dist/cli/tasks/task.js.map +1 -0
  43. package/dist/cli/tasks/tsc-compile-package.d.ts +12 -0
  44. package/dist/cli/tasks/tsc-compile-package.d.ts.map +1 -0
  45. package/dist/cli/tasks/tsc-compile-package.js +42 -0
  46. package/dist/cli/tasks/tsc-compile-package.js.map +1 -0
  47. package/dist/cli/tasks/tsc-compile.d.ts +16 -0
  48. package/dist/cli/tasks/tsc-compile.d.ts.map +1 -0
  49. package/dist/cli/tasks/tsc-compile.js +48 -0
  50. package/dist/cli/tasks/tsc-compile.js.map +1 -0
  51. package/dist/cli/utils/bundle.js +1 -1
  52. package/dist/cli/utils/bundle.js.map +1 -1
  53. package/dist/cli/utils/cli-npm.d.ts +10 -3
  54. package/dist/cli/utils/cli-npm.d.ts.map +1 -1
  55. package/dist/cli/utils/cli-npm.js +13 -15
  56. package/dist/cli/utils/cli-npm.js.map +1 -1
  57. package/dist/cli/utils/cli-os.d.ts.map +1 -1
  58. package/dist/cli/utils/cli-os.js +2 -2
  59. package/dist/cli/utils/cli-os.js.map +1 -1
  60. package/dist/cli/utils/eslint.d.ts.map +1 -1
  61. package/dist/cli/utils/eslint.js +13 -12
  62. package/dist/cli/utils/eslint.js.map +1 -1
  63. package/dist/cli/utils/is-module-installed.js +1 -1
  64. package/dist/cli/utils/is-module-installed.js.map +1 -1
  65. package/dist/cli/utils/publish.d.ts.map +1 -1
  66. package/dist/cli/utils/tsc.d.ts +3 -2
  67. package/dist/cli/utils/tsc.d.ts.map +1 -1
  68. package/dist/cli/utils/tsc.js +20 -16
  69. package/dist/cli/utils/tsc.js.map +1 -1
  70. package/dist/utils/get-configuration.d.ts +3 -1
  71. package/dist/utils/get-configuration.d.ts.map +1 -1
  72. package/dist/utils/get-configuration.js +2 -0
  73. package/dist/utils/get-configuration.js.map +1 -1
  74. package/dist/utils/get-destination-folders.d.ts.map +1 -1
  75. package/dist/utils/get-destination-folders.js +9 -13
  76. package/dist/utils/get-destination-folders.js.map +1 -1
  77. package/dist/utils/get-folders.js +2 -2
  78. package/dist/utils/get-folders.js.map +1 -1
  79. package/dist/utils/get-jest-config.d.ts.map +1 -1
  80. package/dist/utils/log.d.ts +1 -0
  81. package/dist/utils/log.d.ts.map +1 -1
  82. package/dist/utils/log.js +3 -0
  83. package/dist/utils/log.js.map +1 -1
  84. package/dist/webpack/configs/plugins/ignore-plugin/check-resource.d.ts.map +1 -1
  85. package/dist/webpack/configs/plugins/ignore-plugin/check-resource.js +1 -1
  86. package/dist/webpack/configs/plugins/ignore-plugin/check-resource.js.map +1 -1
  87. package/dist/webpack/utils/hash-mod.d.ts.map +1 -1
  88. package/dist/webpack/utils/testing/execute.d.ts.map +1 -1
  89. package/dist/webpack/utils/testing/get-compiler.d.ts.map +1 -1
  90. package/package.json +28 -24
  91. package/src/cli/commands/__tests__/convert-eslint-config.test.ts +455 -0
  92. package/src/cli/commands/__tests__/lint.test.ts +2 -2
  93. package/src/cli/commands/__tests__/mfe-package-clean.test.ts +143 -73
  94. package/src/cli/commands/__tests__/mfe-package-publish.test.ts +27 -20
  95. package/src/cli/commands/__tests__/mfe-publish.test.ts +18 -7
  96. package/src/cli/commands/convert-eslint-config.ts +289 -0
  97. package/src/cli/commands/get-command.ts +6 -0
  98. package/src/cli/commands/init.ts +4 -3
  99. package/src/cli/commands/lint.ts +3 -3
  100. package/src/cli/commands/mfe-package-clean.ts +53 -52
  101. package/src/cli/commands/mfe-package-publish.ts +7 -21
  102. package/src/cli/commands/mfe-publish.ts +6 -5
  103. package/src/cli/commands/run-task.ts +41 -0
  104. package/src/cli/index.ts +16 -4
  105. package/src/cli/tasks/__tests__/cli-task.test.ts +115 -0
  106. package/src/cli/tasks/__tests__/swc-compile.test.ts +192 -0
  107. package/src/cli/tasks/__tests__/task.test.ts +88 -0
  108. package/src/cli/tasks/__tests__/tsc-compile-package.test.ts +72 -0
  109. package/src/cli/tasks/__tests__/tsc-compile.test.ts +156 -0
  110. package/src/cli/tasks/cli-task.ts +64 -0
  111. package/src/cli/tasks/swc-cli.d.ts +3 -0
  112. package/src/cli/tasks/swc-compile-package.ts +70 -0
  113. package/src/cli/tasks/task.ts +112 -0
  114. package/src/cli/tasks/tsc-compile-package.ts +47 -0
  115. package/src/cli/tasks/tsc-compile.ts +64 -0
  116. package/src/cli/utils/__tests__/assets-copy.test.ts +1 -1
  117. package/src/cli/utils/__tests__/bundle.test.ts +1 -1
  118. package/src/cli/utils/__tests__/cli-npm.test.ts +39 -26
  119. package/src/cli/utils/__tests__/cli-os.test.ts +2 -2
  120. package/src/cli/utils/__tests__/eslint.test.ts +37 -8
  121. package/src/cli/utils/__tests__/styles-copy.test.ts +1 -1
  122. package/src/cli/utils/__tests__/tsc.test.ts +34 -55
  123. package/src/cli/utils/bundle.ts +1 -1
  124. package/src/cli/utils/cli-npm.ts +25 -16
  125. package/src/cli/utils/cli-os.ts +2 -2
  126. package/src/cli/utils/eslint.ts +16 -13
  127. package/src/cli/utils/is-module-installed.ts +1 -1
  128. package/src/cli/utils/tsc.ts +25 -20
  129. package/src/utils/__tests__/get-destination-folders.test.ts +1 -1
  130. package/src/utils/__tests__/get-folders.test.ts +6 -18
  131. package/src/utils/__tests__/log.test.ts +6 -0
  132. package/src/utils/get-configuration.ts +2 -0
  133. package/src/utils/get-destination-folders.ts +11 -17
  134. package/src/utils/get-folders.ts +2 -2
  135. package/src/utils/log.ts +4 -0
  136. package/src/webpack/configs/plugins/ignore-plugin/check-resource.ts +1 -1
@@ -2,11 +2,12 @@ import { fs, vol } from 'memfs';
2
2
  import { ESLint } from 'eslint';
3
3
 
4
4
  import { eslint } from '../eslint';
5
+ import { getDestinationFolders } from '../../../utils/get-destination-folders';
5
6
 
6
7
  jest.mock('fs', () => fs);
7
8
  jest.mock('eslint');
8
9
  jest.mock('../../../utils/get-destination-folders', () => ({
9
- getDestinationFolders: () => [],
10
+ getDestinationFolders: jest.fn(),
10
11
  }));
11
12
 
12
13
  describe(`[startup] utils:${eslint.name}`, () => {
@@ -37,19 +38,30 @@ describe(`[startup] utils:${eslint.name}`, () => {
37
38
  eslintArgs = { paths: ['foo', 'bar'] };
38
39
  eslintResults = [mockResult];
39
40
  eslintErrors = [];
41
+ jest.mocked(getDestinationFolders).mockReturnValue([]);
40
42
  });
41
43
 
42
44
  const subject = async () => eslint(eslintArgs);
43
45
 
44
- test('lints .ts and .tsx files', async () => {
46
+ test.each(['.vscode/', '**/.yalc/', '**/*.css.d.ts', '**/*.scss.d.ts', '**/*.less.d.ts'])(
47
+ 'ignores %s',
48
+ async pattern => {
49
+ await subject();
50
+
51
+ const ignorePatterns = jest.mocked(ESLint).mock.calls[0][0]?.ignorePatterns;
52
+ expect(ignorePatterns).toContain(pattern);
53
+ }
54
+ );
55
+
56
+ test('ignores output folders', async () => {
57
+ const outputFolders = ['../foo/out/', 'dist/', 'packages/bar/out/', 'packages/foo/dist/'];
58
+
59
+ jest.mocked(getDestinationFolders).mockReturnValue(outputFolders);
60
+
45
61
  await subject();
46
62
 
47
- expect(ESLint).toHaveBeenCalledWith(
48
- expect.objectContaining({
49
- extensions: ['.ts', '.tsx'],
50
- })
51
- );
52
- expect(mockESLint.lintFiles).toHaveBeenCalledWith(eslintArgs.paths);
63
+ const ignorePatterns = jest.mocked(ESLint).mock.calls[0][0]?.ignorePatterns;
64
+ outputFolders.forEach(dir => expect(ignorePatterns).toContain(dir));
53
65
  });
54
66
 
55
67
  describe('when instructed to fix issues', () => {
@@ -58,6 +70,7 @@ describe(`[startup] utils:${eslint.name}`, () => {
58
70
  test('applies fixes', async () => {
59
71
  await subject();
60
72
 
73
+ expect(ESLint).toHaveBeenCalledWith(expect.objectContaining({ fix: true }));
61
74
  expect(ESLint.outputFixes).toHaveBeenCalledWith(eslintResults);
62
75
  });
63
76
  });
@@ -99,4 +112,20 @@ describe(`[startup] utils:${eslint.name}`, () => {
99
112
  expect(mockESLint.lintFiles).not.toHaveBeenCalled();
100
113
  });
101
114
  });
115
+
116
+ describe('with custom ESLint config', () => {
117
+ const eslintConfig: any = { foo: 'bar' };
118
+
119
+ const config = JSON.stringify({
120
+ cli: { lint: { eslint: { ...eslintConfig } } },
121
+ });
122
+
123
+ beforeEach(() => vol.fromJSON({ 'package.json': config }));
124
+
125
+ test('passes through custom config', async () => {
126
+ await subject();
127
+
128
+ expect(ESLint).toHaveBeenCalledWith(expect.objectContaining(eslintConfig));
129
+ });
130
+ });
102
131
  });
@@ -38,7 +38,7 @@ describe('[startup] Cli Utils (Styles)', () => {
38
38
  test('copies styles from source to destination in watch mode', async () => {
39
39
  try {
40
40
  await subject();
41
- } catch (error: any) {
41
+ } catch {
42
42
  // ignore rejected promise that terminates watch()
43
43
  }
44
44
 
@@ -1,84 +1,63 @@
1
1
  import execa from 'execa';
2
- import { fs, vol } from 'memfs';
3
- import { Package, getPackagesGraph, getTsConfig } from '../../../utils';
4
- import { createPackage } from '../../../__mocks__';
2
+ import { lernaExec } from '../lerna-exec';
5
3
 
6
4
  import { tsc, tscWatch } from '../tsc';
5
+ import { createPackage } from '../../../__mocks__';
7
6
 
8
- jest.mock('fs', () => fs);
9
7
  jest.mock('execa', () => jest.fn());
10
- jest.mock('../../../utils', () => ({
11
- ...jest.requireActual('../../../utils'),
12
- log: { info: jest.fn(), debug: jest.fn() }, // suppress test output
13
- getPackagesGraph: jest.fn(),
8
+ jest.mock('../lerna-exec', () => ({
9
+ lernaExec: jest.fn(),
14
10
  }));
15
11
 
16
12
  describe('[startup] Cli Utils', () => {
17
- let packages: Package[];
13
+ const packages = ['foo', 'bar'].map(name => createPackage({ name }));
18
14
 
19
15
  beforeEach(() => {
20
- jest.resetAllMocks();
21
- jest.mocked(getPackagesGraph).mockReturnValue({});
22
- packages = [
23
- createPackage({ name: 'foo', location: 'packages/foo' }),
24
- createPackage({ name: 'bar', location: 'packages/bar' }),
25
- ];
26
- vol.fromJSON({
27
- 'packages/foo/tsconfig.json': JSON.stringify({}),
28
- 'packages/bar/tsconfig.json': JSON.stringify({}),
29
- });
16
+ jest.clearAllMocks();
30
17
  });
31
18
 
32
- afterEach(() => vol.reset());
19
+ function itRunsTscCompile(watch = false, typeCheckOnly = false) {
20
+ expect(execa).toHaveBeenCalledWith(
21
+ 'startup',
22
+ [
23
+ 'task',
24
+ 'tsc-compile',
25
+ ...packages.map(({ name }) => `--scope=${name}`),
26
+ watch ? '--watch' : undefined,
27
+ typeCheckOnly ? '--type-check-only' : undefined,
28
+ ].filter(i => i !== undefined),
29
+ { stdio: 'inherit' }
30
+ );
31
+ }
32
+
33
+ function itRunsTscCompilePackage(watch = false) {
34
+ expect(lernaExec).toHaveBeenCalledWith({
35
+ cmd: 'startup task tsc-compile-package',
36
+ scope: packages.map(({ name }) => name),
37
+ parallel: true,
38
+ stream: true,
39
+ ...(watch ? { '--': ['--watch'] } : {}),
40
+ });
41
+ }
33
42
 
34
43
  describe(`${tsc.name}`, () => {
35
44
  const subject = async () => tsc(packages);
36
45
 
37
- test('transpiles packages', async () => {
46
+ test('compiles and type checks packages', async () => {
38
47
  await subject();
39
48
 
40
- expect(execa).toHaveBeenCalledWith(
41
- 'tsc',
42
- ['-b', ...packages.map(({ location }) => getTsConfig(location))],
43
- { stdio: 'inherit' }
44
- );
45
- });
46
-
47
- describe('when package is dependency of another', () => {
48
- beforeEach(() => {
49
- jest.mocked(getPackagesGraph).mockReturnValue({
50
- [packages[0].name]: [packages[1].name], // packages[0] depends on packages[1]
51
- });
52
- });
53
-
54
- test('transpiles only parent packages', async () => {
55
- await subject();
56
-
57
- expect(execa).toHaveBeenCalledWith(
58
- expect.anything(),
59
- ['-b', getTsConfig(packages[0].location)],
60
- expect.anything()
61
- );
62
- });
49
+ itRunsTscCompile();
63
50
  });
64
51
  });
65
52
 
66
53
  describe(`${tscWatch.name}`, () => {
67
54
  const subject = async () => tscWatch(packages);
68
55
 
69
- test('transpiles packages in watch mode', async () => {
56
+ test('compiles and type checks packages in watch mode', async () => {
70
57
  await subject();
71
58
 
72
- expect(execa).toHaveBeenCalledWith(
73
- 'tsc',
74
- [
75
- '-b',
76
- '-w',
77
- '--preserveWatchOutput',
78
- ...packages.map(({ location }) => getTsConfig(location)),
79
- ],
80
- { stdio: 'inherit' }
81
- );
59
+ itRunsTscCompilePackage(true);
60
+ itRunsTscCompile(true, true);
82
61
  });
83
62
  });
84
63
  });
@@ -113,7 +113,7 @@ async function run(config: Configuration) {
113
113
  }
114
114
 
115
115
  if (stats.hasErrors()) {
116
- return reject(stats.toString('errors-only'));
116
+ return reject(new Error(stats.toString('errors-only')));
117
117
  }
118
118
 
119
119
  compiler.close(() => resolve(stats));
@@ -1,10 +1,18 @@
1
1
  import { runCommand, runCommandOutput } from './cli-os';
2
2
 
3
+ export interface Version {
4
+ name: string;
5
+ date: Date;
6
+ tag?: string;
7
+ }
8
+
9
+ const NPM_TIMEOUT = 10000;
10
+
3
11
  export function npmGetPackageVersions(registry: string, packageName: string): string[] {
4
12
  try {
5
13
  const v = runCommandOutput(
6
14
  `npm show ${packageName} versions --registry ${registry} --json`,
7
- { timeout: 10000 }
15
+ { timeout: NPM_TIMEOUT }
8
16
  );
9
17
 
10
18
  return JSON.parse(v);
@@ -13,17 +21,22 @@ export function npmGetPackageVersions(registry: string, packageName: string): st
13
21
  }
14
22
  }
15
23
 
16
- export function npmGetPackageVersionDates(registry: string, packageName: string): [string, Date][] {
24
+ export function npmGetPackageVersionsDetails(registry: string, packageName: string): Version[] {
17
25
  try {
18
- const v = runCommandOutput(`npm view ${packageName} time --registry ${registry} --json`, {
19
- timeout: 10000,
20
- });
21
- const map = JSON.parse(v);
26
+ const result = runCommandOutput(
27
+ `npm view ${packageName} time dist-tags --registry ${registry} --json`,
28
+ { timeout: NPM_TIMEOUT }
29
+ );
22
30
 
23
- return Object.keys(map).reduce(
24
- (out, version) => [...out, [version, new Date(map[version])]],
25
- []
31
+ const { time, 'dist-tags': distTags } = JSON.parse(result);
32
+
33
+ const tags = Object.fromEntries(
34
+ Object.entries(distTags).map(([tag, version]) => [version, tag])
26
35
  );
36
+
37
+ return Object.keys(time).reduce((out, version) => {
38
+ return [...out, { name: version, date: new Date(time[version]), tag: tags[version] }];
39
+ }, []);
27
40
  } catch {
28
41
  return [];
29
42
  }
@@ -31,16 +44,12 @@ export function npmGetPackageVersionDates(registry: string, packageName: string)
31
44
 
32
45
  export async function npmUnpublish(registry: string, packageName: string, packageVersion: string) {
33
46
  await runCommand(`npm unpublish ${packageName}@${packageVersion} --registry ${registry}`, {
34
- timeout: 10000,
47
+ timeout: NPM_TIMEOUT,
35
48
  });
36
49
  }
37
50
 
38
- export async function npmPublishDry() {
39
- await runCommand('npm publish --dry-run');
40
- }
41
-
42
- export async function npmPublish(tag?: string) {
43
- await runCommand(['npm publish', !!tag && `--tag ${tag}`]);
51
+ export async function npmPublish({ dry, tag }: { dry?: boolean; tag?: string }) {
52
+ await runCommand(['npm publish', !!tag && `--tag ${tag}`, !!dry && `--dry-run`]);
44
53
  }
45
54
 
46
55
  export async function npmPackageSet(key: string, value: string) {
@@ -25,7 +25,7 @@ export const runCommand = (
25
25
  const commandName = commandArray.shift();
26
26
 
27
27
  if (!commandName) {
28
- reject();
28
+ reject(new Error('invalid command'));
29
29
 
30
30
  return;
31
31
  }
@@ -48,7 +48,7 @@ export const runCommand = (
48
48
  }
49
49
 
50
50
  if (code) {
51
- reject();
51
+ reject(new Error(`command exited with code: ${code}`));
52
52
  } else {
53
53
  resolve();
54
54
  }
@@ -1,6 +1,6 @@
1
1
  import { ESLint } from 'eslint';
2
2
 
3
- import { getDestinationFolders, getESLintConfiguration } from '../../utils';
3
+ import { getDestinationFolders, getESLintConfiguration, log } from '../../utils';
4
4
 
5
5
  interface Args {
6
6
  fix?: boolean;
@@ -14,21 +14,24 @@ export async function eslint({ fix, paths }: Args) {
14
14
  return;
15
15
  }
16
16
 
17
- const eslint = new ESLint({
17
+ const options: ESLint.Options = {
18
18
  errorOnUnmatchedPattern: false,
19
- extensions: ['.ts', '.tsx'],
20
- baseConfig: {
21
- ignorePatterns: [
22
- 'node_modules',
23
- '*.css.d.ts',
24
- '*.scss.d.ts',
25
- '*.less.d.ts',
26
- ...getDestinationFolders(),
27
- ],
28
- },
19
+ ignorePatterns: [
20
+ // **/node_modules/ is excluded by default
21
+ '.vscode/',
22
+ '**/.yalc/',
23
+ '**/*.css.d.ts',
24
+ '**/*.scss.d.ts',
25
+ '**/*.less.d.ts',
26
+ ...getDestinationFolders(),
27
+ ],
29
28
  fix,
30
29
  ...config,
31
- });
30
+ };
31
+
32
+ log.debug('eslint-options', () => JSON.stringify(options, null, 2));
33
+
34
+ const eslint = new ESLint(options);
32
35
 
33
36
  let files = paths;
34
37
  if (files.length === 0) {
@@ -2,7 +2,7 @@ export function isModuleInstalled(name: string): boolean {
2
2
  try {
3
3
  require.resolve(name);
4
4
  return true;
5
- } catch (e) {
5
+ } catch {
6
6
  return false;
7
7
  }
8
8
  }
@@ -1,6 +1,7 @@
1
1
  import execa from 'execa';
2
2
 
3
- import { getPackagesGraph, getTsConfig, log, Package } from '../../utils';
3
+ import { log, Package } from '../../utils';
4
+ import { lernaExec } from './lerna-exec';
4
5
 
5
6
  export function tsc(packages: Package[]) {
6
7
  log.info('Building TypeScript files...');
@@ -8,26 +9,30 @@ export function tsc(packages: Package[]) {
8
9
  }
9
10
 
10
11
  export function tscWatch(packages: Package[]) {
11
- return transpile(packages, ['-w', '--preserveWatchOutput']);
12
+ return transpile(packages, true);
12
13
  }
13
14
 
14
- async function transpile(packages: Package[], options: string[] = []) {
15
- const args = [
16
- '-b',
17
- ...options,
18
- ...collapsePackages(packages).map(({ location }) => getTsConfig(location)),
19
- ];
20
- log.debug('tsc', `Running tsc ${args.join(' ')}`);
21
- await execa('tsc', args, { stdio: 'inherit' });
22
- }
23
-
24
- /**
25
- * Exclude dependant packages as they will be built through project references
26
- */
27
- function collapsePackages(packages: Package[]) {
28
- const dependencies = new Set(
29
- Object.values(getPackagesGraph({ scope: packages.map(({ name }) => name) })).flat()
30
- );
15
+ async function transpile(packages: Package[], watch = false) {
16
+ const packageNames = packages.map(({ name }) => name);
17
+ const packageScopes = packageNames.map(name => `--scope=${name}`);
18
+ if (watch) {
19
+ return Promise.all([
20
+ lernaExec({
21
+ 'cmd': 'startup task tsc-compile-package',
22
+ 'scope': packageNames,
23
+ 'parallel': true,
24
+ 'stream': true,
25
+ '--': ['--watch'],
26
+ }),
27
+ execa(
28
+ 'startup',
29
+ ['task', 'tsc-compile', ...packageScopes, '--watch', '--type-check-only'],
30
+ { stdio: 'inherit' }
31
+ ),
32
+ ]);
33
+ }
31
34
 
32
- return packages.filter(({ name }) => !dependencies.has(name));
35
+ return execa('startup', ['task', 'tsc-compile', ...packageScopes], {
36
+ stdio: 'inherit',
37
+ });
33
38
  }
@@ -35,7 +35,7 @@ describe('[startup] Utils', () => {
35
35
  }
36
36
 
37
37
  function expectedOutDirs(locations: string[]) {
38
- return locations.map(location => `/packages/${location}/${location}outDir/`);
38
+ return locations.map(location => `packages/${location}/${location}outDir/`);
39
39
  }
40
40
 
41
41
  test('returns outDir path for all packages', () => {
@@ -15,15 +15,9 @@ describe('[Startup] utils:get-folders', () => {
15
15
  'tsconfig.json': JSON.stringify({ compilerOptions: { ourDir: 'dist' } }),
16
16
  });
17
17
 
18
- let error;
19
-
20
- try {
21
- getFolders();
22
- } catch (e) {
23
- error = e;
24
- }
25
-
26
- expect(error).toBe('"compilerOptions.rootDir" must be defined in the "tsconfig.json"!');
18
+ expect(() => getFolders()).toThrow(
19
+ '"compilerOptions.rootDir" must be defined in the "tsconfig.json"!'
20
+ );
27
21
  });
28
22
 
29
23
  test('getFolders throws an exception if "compilerOptions.outDir" isn\'t defined', () => {
@@ -32,15 +26,9 @@ describe('[Startup] utils:get-folders', () => {
32
26
  'tsconfig.json': JSON.stringify({ compilerOptions: { rootDir: 'src' } }),
33
27
  });
34
28
 
35
- let error;
36
-
37
- try {
38
- getFolders();
39
- } catch (e) {
40
- error = e;
41
- }
42
-
43
- expect(error).toBe('"compilerOptions.outDir" must be defined in the "tsconfig.json"!');
29
+ expect(() => getFolders()).toThrow(
30
+ '"compilerOptions.outDir" must be defined in the "tsconfig.json"!'
31
+ );
44
32
  });
45
33
 
46
34
  test('"compilerOptions.outDir" used as the destination', () => {
@@ -14,6 +14,12 @@ describe(`[startup] Utils`, () => {
14
14
  stdoutSpy = jest.spyOn(process.stdout, 'write').mockImplementation(jest.fn());
15
15
  });
16
16
 
17
+ test('text() writes default text', () => {
18
+ log.text(message);
19
+
20
+ expect(stdoutSpy).toHaveBeenCalledWith(`${chalk(message)}\n`);
21
+ });
22
+
17
23
  test('info() writes cyan text', () => {
18
24
  log.info(message);
19
25
 
@@ -58,6 +58,7 @@ export interface NodeConfiguration {
58
58
  export enum CommandName {
59
59
  'build' = 'build',
60
60
  'bundle-package' = 'bundle-package',
61
+ 'convert-eslint-config' = 'convert-eslint-config',
61
62
  'eslint' = 'eslint',
62
63
  'init' = 'init',
63
64
  'install' = 'install',
@@ -70,6 +71,7 @@ export enum CommandName {
70
71
  'start' = 'start',
71
72
  'styles-check' = 'styles-check',
72
73
  'test' = 'test',
74
+ 'task' = 'task',
73
75
  }
74
76
  /* eslint-enable @typescript-eslint/naming-convention */
75
77
 
@@ -8,24 +8,18 @@ import { getPackages, readJson } from '.';
8
8
  */
9
9
  export function getDestinationFolders() {
10
10
  const packages = getPackages();
11
+ const cwd = process.cwd();
11
12
 
12
- return packages
13
- .map(({ location }) => {
14
- const tsConfigPath = path.join(location, 'tsconfig.json');
15
-
16
- if (!fs.existsSync(tsConfigPath)) {
17
- return '';
18
- }
19
-
13
+ return packages.reduce<string[]>((result, { location }) => {
14
+ const tsConfigPath = path.join(location, 'tsconfig.json');
15
+ if (fs.existsSync(tsConfigPath)) {
20
16
  const { outDir } = readJson(tsConfigPath).compilerOptions ?? {};
21
-
22
- if (!outDir) {
23
- return '';
17
+ if (outDir) {
18
+ result.push(
19
+ path.join(path.relative(cwd, location), outDir, '/').replace(/\\/g, '/')
20
+ );
24
21
  }
25
-
26
- return path
27
- .join('/', path.relative(process.cwd(), location), outDir, '/')
28
- .replace(/\\/g, '/');
29
- })
30
- .filter(path => !!path);
22
+ }
23
+ return result;
24
+ }, []);
31
25
  }
@@ -10,11 +10,11 @@ export function getFolders(location = './') {
10
10
  readJson(path.join(location, 'tsconfig.json')).compilerOptions ?? {};
11
11
 
12
12
  if (!rootDir) {
13
- throw '"compilerOptions.rootDir" must be defined in the "tsconfig.json"!';
13
+ throw new Error('"compilerOptions.rootDir" must be defined in the "tsconfig.json"!');
14
14
  }
15
15
 
16
16
  if (!outDir) {
17
- throw '"compilerOptions.outDir" must be defined in the "tsconfig.json"!';
17
+ throw new Error('"compilerOptions.outDir" must be defined in the "tsconfig.json"!');
18
18
  }
19
19
 
20
20
  return {
package/src/utils/log.ts CHANGED
@@ -10,6 +10,10 @@ class Log {
10
10
  this.debugMap = new Map<string, Debugger>();
11
11
  }
12
12
 
13
+ text(...text: string[]) {
14
+ process.stdout.write(chalk(...text) + '\n');
15
+ }
16
+
13
17
  info(...text: string[]) {
14
18
  process.stdout.write(chalk.bold.cyan(...text) + '\n');
15
19
  }
@@ -20,7 +20,7 @@ export function checkResource(packageContext: Context) {
20
20
  if (isOptionalReactDomPeerDependency({ resource, context })) {
21
21
  try {
22
22
  require.resolve(resource);
23
- } catch (e) {
23
+ } catch {
24
24
  return true;
25
25
  }
26
26
  }