@servicetitan/startup 32.2.0 → 32.3.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 (239) hide show
  1. package/dist/cli/commands/build.d.ts +36 -7
  2. package/dist/cli/commands/build.d.ts.map +1 -1
  3. package/dist/cli/commands/build.js +35 -10
  4. package/dist/cli/commands/build.js.map +1 -1
  5. package/dist/cli/commands/bundle-package.d.ts +9 -10
  6. package/dist/cli/commands/bundle-package.d.ts.map +1 -1
  7. package/dist/cli/commands/bundle-package.js +6 -22
  8. package/dist/cli/commands/bundle-package.js.map +1 -1
  9. package/dist/cli/commands/clean.d.ts +2 -2
  10. package/dist/cli/commands/clean.d.ts.map +1 -1
  11. package/dist/cli/commands/clean.js +16 -4
  12. package/dist/cli/commands/clean.js.map +1 -1
  13. package/dist/cli/commands/convert-eslint-config.d.ts +2 -2
  14. package/dist/cli/commands/convert-eslint-config.d.ts.map +1 -1
  15. package/dist/cli/commands/convert-eslint-config.js +3 -4
  16. package/dist/cli/commands/convert-eslint-config.js.map +1 -1
  17. package/dist/cli/commands/eslint.d.ts +3 -5
  18. package/dist/cli/commands/eslint.d.ts.map +1 -1
  19. package/dist/cli/commands/eslint.js +2 -18
  20. package/dist/cli/commands/eslint.js.map +1 -1
  21. package/dist/cli/commands/get-command.d.ts.map +1 -1
  22. package/dist/cli/commands/get-command.js +2 -0
  23. package/dist/cli/commands/get-command.js.map +1 -1
  24. package/dist/cli/commands/index.d.ts +0 -1
  25. package/dist/cli/commands/index.d.ts.map +1 -1
  26. package/dist/cli/commands/index.js +0 -1
  27. package/dist/cli/commands/index.js.map +1 -1
  28. package/dist/cli/commands/init.d.ts +10 -6
  29. package/dist/cli/commands/init.d.ts.map +1 -1
  30. package/dist/cli/commands/init.js +9 -8
  31. package/dist/cli/commands/init.js.map +1 -1
  32. package/dist/cli/commands/install.d.ts +21 -7
  33. package/dist/cli/commands/install.d.ts.map +1 -1
  34. package/dist/cli/commands/install.js +33 -11
  35. package/dist/cli/commands/install.js.map +1 -1
  36. package/dist/cli/commands/kendo-ui-license.d.ts +3 -3
  37. package/dist/cli/commands/kendo-ui-license.d.ts.map +1 -1
  38. package/dist/cli/commands/kendo-ui-license.js +17 -5
  39. package/dist/cli/commands/kendo-ui-license.js.map +1 -1
  40. package/dist/cli/commands/lint.d.ts +31 -12
  41. package/dist/cli/commands/lint.d.ts.map +1 -1
  42. package/dist/cli/commands/lint.js +34 -13
  43. package/dist/cli/commands/lint.js.map +1 -1
  44. package/dist/cli/commands/mfe-list.d.ts +46 -0
  45. package/dist/cli/commands/mfe-list.d.ts.map +1 -0
  46. package/dist/cli/commands/mfe-list.js +200 -0
  47. package/dist/cli/commands/mfe-list.js.map +1 -0
  48. package/dist/cli/commands/mfe-package-clean.d.ts +29 -5
  49. package/dist/cli/commands/mfe-package-clean.d.ts.map +1 -1
  50. package/dist/cli/commands/mfe-package-clean.js +28 -5
  51. package/dist/cli/commands/mfe-package-clean.js.map +1 -1
  52. package/dist/cli/commands/mfe-package-publish.d.ts +37 -5
  53. package/dist/cli/commands/mfe-package-publish.d.ts.map +1 -1
  54. package/dist/cli/commands/mfe-package-publish.js +36 -5
  55. package/dist/cli/commands/mfe-package-publish.js.map +1 -1
  56. package/dist/cli/commands/mfe-publish.d.ts +17 -4
  57. package/dist/cli/commands/mfe-publish.d.ts.map +1 -1
  58. package/dist/cli/commands/mfe-publish.js +37 -7
  59. package/dist/cli/commands/mfe-publish.js.map +1 -1
  60. package/dist/cli/commands/prepare-package.d.ts +3 -5
  61. package/dist/cli/commands/prepare-package.d.ts.map +1 -1
  62. package/dist/cli/commands/prepare-package.js +2 -18
  63. package/dist/cli/commands/prepare-package.js.map +1 -1
  64. package/dist/cli/commands/review/review.d.ts +14 -6
  65. package/dist/cli/commands/review/review.d.ts.map +1 -1
  66. package/dist/cli/commands/review/review.js +27 -23
  67. package/dist/cli/commands/review/review.js.map +1 -1
  68. package/dist/cli/commands/run-task.d.ts +10 -6
  69. package/dist/cli/commands/run-task.d.ts.map +1 -1
  70. package/dist/cli/commands/run-task.js +16 -13
  71. package/dist/cli/commands/run-task.js.map +1 -1
  72. package/dist/cli/commands/start.d.ts +28 -7
  73. package/dist/cli/commands/start.d.ts.map +1 -1
  74. package/dist/cli/commands/start.js +27 -10
  75. package/dist/cli/commands/start.js.map +1 -1
  76. package/dist/cli/commands/styles-check.d.ts +2 -2
  77. package/dist/cli/commands/styles-check.d.ts.map +1 -1
  78. package/dist/cli/commands/styles-check.js +2 -1
  79. package/dist/cli/commands/styles-check.js.map +1 -1
  80. package/dist/cli/commands/test/tests.d.ts +14 -5
  81. package/dist/cli/commands/test/tests.d.ts.map +1 -1
  82. package/dist/cli/commands/test/tests.js +26 -13
  83. package/dist/cli/commands/test/tests.js.map +1 -1
  84. package/dist/cli/commands/types.d.ts +13 -4
  85. package/dist/cli/commands/types.d.ts.map +1 -1
  86. package/dist/cli/commands/types.js +28 -0
  87. package/dist/cli/commands/types.js.map +1 -1
  88. package/dist/cli/commands/upload-sourcemaps.d.ts +3 -5
  89. package/dist/cli/commands/upload-sourcemaps.d.ts.map +1 -1
  90. package/dist/cli/commands/upload-sourcemaps.js +5 -20
  91. package/dist/cli/commands/upload-sourcemaps.js.map +1 -1
  92. package/dist/cli/index.js +48 -39
  93. package/dist/cli/index.js.map +1 -1
  94. package/dist/cli/tasks/swc-compile-package.d.ts +2 -2
  95. package/dist/cli/tasks/swc-compile-package.d.ts.map +1 -1
  96. package/dist/cli/tasks/swc-compile-package.js.map +1 -1
  97. package/dist/cli/tasks/tsc-compile-package.d.ts +2 -2
  98. package/dist/cli/tasks/tsc-compile-package.d.ts.map +1 -1
  99. package/dist/cli/tasks/tsc-compile-package.js +1 -1
  100. package/dist/cli/tasks/tsc-compile-package.js.map +1 -1
  101. package/dist/cli/tasks/tsc-compile.d.ts +2 -2
  102. package/dist/cli/tasks/tsc-compile.d.ts.map +1 -1
  103. package/dist/cli/tasks/tsc-compile.js.map +1 -1
  104. package/dist/cli/utils/bundle.js +1 -1
  105. package/dist/cli/utils/bundle.js.map +1 -1
  106. package/dist/cli/utils/cli-npm.d.ts +14 -0
  107. package/dist/cli/utils/cli-npm.d.ts.map +1 -1
  108. package/dist/cli/utils/cli-npm.js +44 -0
  109. package/dist/cli/utils/cli-npm.js.map +1 -1
  110. package/dist/cli/utils/cli-os.d.ts +2 -2
  111. package/dist/cli/utils/cli-os.d.ts.map +1 -1
  112. package/dist/cli/utils/cli-os.js +13 -9
  113. package/dist/cli/utils/cli-os.js.map +1 -1
  114. package/dist/cli/utils/eslint.d.ts +2 -1
  115. package/dist/cli/utils/eslint.d.ts.map +1 -1
  116. package/dist/cli/utils/eslint.js.map +1 -1
  117. package/dist/cli/utils/index.d.ts +1 -0
  118. package/dist/cli/utils/index.d.ts.map +1 -1
  119. package/dist/cli/utils/index.js +1 -0
  120. package/dist/cli/utils/index.js.map +1 -1
  121. package/dist/cli/utils/is-tty.d.ts +2 -0
  122. package/dist/cli/utils/is-tty.d.ts.map +1 -0
  123. package/dist/cli/utils/is-tty.js +15 -0
  124. package/dist/cli/utils/is-tty.js.map +1 -0
  125. package/dist/cli/utils/maybe-create-git-folder.d.ts +1 -1
  126. package/dist/cli/utils/maybe-create-git-folder.d.ts.map +1 -1
  127. package/dist/cli/utils/maybe-create-git-folder.js +5 -5
  128. package/dist/cli/utils/maybe-create-git-folder.js.map +1 -1
  129. package/dist/cli/utils/process-tree.d.ts.map +1 -1
  130. package/dist/cli/utils/process-tree.js +2 -2
  131. package/dist/cli/utils/process-tree.js.map +1 -1
  132. package/dist/cli/utils/set-node-options.d.ts.map +1 -1
  133. package/dist/cli/utils/set-node-options.js +2 -1
  134. package/dist/cli/utils/set-node-options.js.map +1 -1
  135. package/dist/utils/find-packages.d.ts +1 -0
  136. package/dist/utils/find-packages.d.ts.map +1 -1
  137. package/dist/utils/find-packages.js.map +1 -1
  138. package/dist/utils/format-relative-date.d.ts +2 -0
  139. package/dist/utils/format-relative-date.d.ts.map +1 -0
  140. package/dist/utils/format-relative-date.js +60 -0
  141. package/dist/utils/format-relative-date.js.map +1 -0
  142. package/dist/utils/get-configuration.d.ts +1 -0
  143. package/dist/utils/get-configuration.d.ts.map +1 -1
  144. package/dist/utils/get-configuration.js +1 -0
  145. package/dist/utils/get-configuration.js.map +1 -1
  146. package/dist/utils/get-packages.d.ts +3 -5
  147. package/dist/utils/get-packages.d.ts.map +1 -1
  148. package/dist/utils/get-packages.js +1 -4
  149. package/dist/utils/get-packages.js.map +1 -1
  150. package/dist/utils/get-startup-version.d.ts.map +1 -1
  151. package/dist/utils/get-startup-version.js +1 -1
  152. package/dist/utils/get-startup-version.js.map +1 -1
  153. package/dist/utils/index.d.ts +1 -0
  154. package/dist/utils/index.d.ts.map +1 -1
  155. package/dist/utils/index.js +1 -0
  156. package/dist/utils/index.js.map +1 -1
  157. package/dist/webpack/configs/loaders/style-loader.d.ts +1 -1
  158. package/dist/webpack/configs/loaders/style-loader.d.ts.map +1 -1
  159. package/dist/webpack/configs/loaders/style-loader.js +2 -2
  160. package/dist/webpack/configs/loaders/style-loader.js.map +1 -1
  161. package/dist/webpack/configs/optimization-config.js +5 -5
  162. package/dist/webpack/configs/optimization-config.js.map +1 -1
  163. package/dist/webpack/configs/output-config.d.ts.map +1 -1
  164. package/dist/webpack/configs/output-config.js +14 -7
  165. package/dist/webpack/configs/output-config.js.map +1 -1
  166. package/dist/webpack/configs/plugins/assets-manifest-plugin.d.ts.map +1 -1
  167. package/dist/webpack/configs/plugins/assets-manifest-plugin.js +10 -3
  168. package/dist/webpack/configs/plugins/assets-manifest-plugin.js.map +1 -1
  169. package/package.json +9 -8
  170. package/src/cli/commands/__tests__/build.test.ts +1 -1
  171. package/src/cli/commands/__tests__/bundle-package.test.ts +22 -2
  172. package/src/cli/commands/__tests__/install.test.ts +42 -4
  173. package/src/cli/commands/__tests__/lint.test.ts +1 -1
  174. package/src/cli/commands/__tests__/mfe-list.test.ts +394 -0
  175. package/src/cli/commands/__tests__/mfe-publish.test.ts +25 -0
  176. package/src/cli/commands/__tests__/start.test.ts +1 -1
  177. package/src/cli/commands/build.ts +14 -10
  178. package/src/cli/commands/bundle-package.ts +19 -13
  179. package/src/cli/commands/clean.ts +2 -4
  180. package/src/cli/commands/convert-eslint-config.ts +3 -5
  181. package/src/cli/commands/eslint.ts +3 -5
  182. package/src/cli/commands/get-command.ts +2 -0
  183. package/src/cli/commands/index.ts +0 -1
  184. package/src/cli/commands/init.ts +7 -8
  185. package/src/cli/commands/install.ts +24 -11
  186. package/src/cli/commands/kendo-ui-license.ts +4 -6
  187. package/src/cli/commands/lint.ts +19 -19
  188. package/src/cli/commands/mfe-list.ts +173 -0
  189. package/src/cli/commands/mfe-package-clean.ts +25 -4
  190. package/src/cli/commands/mfe-package-publish.ts +33 -4
  191. package/src/cli/commands/mfe-publish.ts +37 -6
  192. package/src/cli/commands/prepare-package.ts +3 -5
  193. package/src/cli/commands/review/review.ts +9 -9
  194. package/src/cli/commands/run-task.ts +15 -11
  195. package/src/cli/commands/start.ts +12 -10
  196. package/src/cli/commands/styles-check.ts +2 -2
  197. package/src/cli/commands/test/__tests__/tests.test.ts +1 -1
  198. package/src/cli/commands/test/tests.ts +20 -10
  199. package/src/cli/commands/types.ts +14 -4
  200. package/src/cli/commands/upload-sourcemaps.ts +3 -5
  201. package/src/cli/index.ts +59 -36
  202. package/src/cli/tasks/swc-compile-package.ts +2 -2
  203. package/src/cli/tasks/tsc-compile-package.ts +4 -3
  204. package/src/cli/tasks/tsc-compile.ts +2 -2
  205. package/src/cli/utils/__tests__/bundle.test.ts +13 -0
  206. package/src/cli/utils/__tests__/cli-npm.test.ts +89 -0
  207. package/src/cli/utils/__tests__/is-tty.test.ts +17 -0
  208. package/src/cli/utils/__tests__/maybe-create-git-folder.test.ts +10 -17
  209. package/src/cli/utils/__tests__/set-node-options.test.ts +10 -10
  210. package/src/cli/utils/bundle.ts +1 -1
  211. package/src/cli/utils/cli-npm.ts +34 -0
  212. package/src/cli/utils/cli-os.ts +12 -25
  213. package/src/cli/utils/eslint.ts +2 -1
  214. package/src/cli/utils/index.ts +1 -0
  215. package/src/cli/utils/is-tty.ts +3 -0
  216. package/src/cli/utils/maybe-create-git-folder.ts +4 -7
  217. package/src/cli/utils/process-tree.ts +4 -2
  218. package/src/cli/utils/set-node-options.ts +2 -1
  219. package/src/utils/__tests__/format-relative-date.test.ts +61 -0
  220. package/src/utils/__tests__/get-packages.test.ts +3 -0
  221. package/src/utils/find-packages.ts +1 -0
  222. package/src/utils/format-relative-date.ts +33 -0
  223. package/src/utils/get-configuration.ts +1 -0
  224. package/src/utils/get-packages.ts +3 -9
  225. package/src/utils/get-startup-version.ts +1 -3
  226. package/src/utils/index.ts +1 -0
  227. package/src/webpack/__mocks__/style-rules.ts +3 -3
  228. package/src/webpack/__tests__/create-webpack-config-shared-dependencies.test.ts +6 -14
  229. package/src/webpack/__tests__/create-webpack-config-web-component.test.ts +52 -29
  230. package/src/webpack/configs/loaders/style-loader.ts +5 -2
  231. package/src/webpack/configs/optimization-config.ts +5 -5
  232. package/src/webpack/configs/output-config.ts +10 -5
  233. package/src/webpack/configs/plugins/assets-manifest-plugin.ts +11 -4
  234. package/dist/cli/commands/get-user-commands.d.ts +0 -7
  235. package/dist/cli/commands/get-user-commands.d.ts.map +0 -1
  236. package/dist/cli/commands/get-user-commands.js +0 -27
  237. package/dist/cli/commands/get-user-commands.js.map +0 -1
  238. package/src/cli/commands/__tests__/get-user-commands.test.ts +0 -27
  239. package/src/cli/commands/get-user-commands.ts +0 -19
@@ -1,6 +1,6 @@
1
1
  import os from 'os';
2
2
  import { getConfigurationSafe } from '../../../utils';
3
- import { Command } from '../../commands';
3
+ import { Command } from '../../commands/types';
4
4
 
5
5
  import { setNodeOptions } from '../set-node-options';
6
6
 
@@ -13,15 +13,11 @@ jest.mock('../../../utils', () => ({
13
13
  getConfigurationSafe: jest.fn(() => ({})),
14
14
  }));
15
15
 
16
- class MockCommand implements Command {
17
- get greedy() {
16
+ class MockCommand extends Command {
17
+ static get greedy() {
18
18
  return true;
19
19
  }
20
20
 
21
- description() {
22
- return 'mock command';
23
- }
24
-
25
21
  async execute() {
26
22
  return Promise.resolve();
27
23
  }
@@ -33,12 +29,16 @@ describe(`[startup] utils:${setNodeOptions.name}`, () => {
33
29
  const originalNodeOptions = process.env.NODE_OPTIONS;
34
30
  const maxOldSpaceSize = `--max_old_space_size=${DEFAULT_SIZE}`;
35
31
  const commandName: any = 'mock';
36
- const command = new MockCommand();
32
+ const command = new MockCommand({});
33
+ let greedy: boolean;
37
34
 
38
35
  beforeEach(() => {
36
+ greedy = true;
39
37
  delete process.env.NODE_OPTIONS;
40
38
  (os.totalmem as jest.Mock).mockReturnValue(16384 * MB);
41
- jest.spyOn(command, 'greedy', 'get').mockReturnValue(true);
39
+ jest.spyOn(command.constructor as typeof Command, 'greedy', 'get').mockImplementation(
40
+ () => greedy
41
+ );
42
42
  });
43
43
 
44
44
  afterAll(() => (process.env.NODE_OPTIONS = originalNodeOptions));
@@ -52,7 +52,7 @@ describe(`[startup] utils:${setNodeOptions.name}`, () => {
52
52
  });
53
53
 
54
54
  describe('when the command is not greedy', () => {
55
- beforeEach(() => jest.spyOn(command, 'greedy', 'get').mockReturnValue(false));
55
+ beforeEach(() => (greedy = false));
56
56
 
57
57
  test('returns false and does not set NODE_OPTIONS', () => {
58
58
  expect(subject()).toBe(false);
@@ -52,7 +52,7 @@ export async function bundle(options: Options = {}) {
52
52
 
53
53
  log.info(`Bundling ${emitExposedDependencies ? 'exposed dependencies' : 'package'}...`);
54
54
 
55
- const mode = watch ? 'development' : 'production';
55
+ const mode = watch || useWatchConfig ? 'development' : 'production';
56
56
  const fallback = watch || useWatchConfig ? webpackDevConfigFileName : webpackProdConfigFileName;
57
57
  const customConfig = readWebpackConfig({ ...options, fallback });
58
58
  const webpackOptions = getWebpackOptions(options, customConfig);
@@ -73,3 +73,37 @@ export async function npmTagVersion({
73
73
  }add ${packageName}@${packageVersion} ${tag}`
74
74
  );
75
75
  }
76
+
77
+ export interface NPMPackageInfo {
78
+ 'name': string;
79
+ 'version': string;
80
+ 'dist-tags'?: Record<string, string>;
81
+ 'time'?: Record<string, string>;
82
+ 'versions'?: string[];
83
+ }
84
+
85
+ export function npmView({ packageName, registry }: { packageName: string; registry?: string }) {
86
+ try {
87
+ const result = runCommandOutput(
88
+ ['npm', 'view', '--json', registry ? `--registry=${registry}` : '', packageName],
89
+ { quiet: true, timeout: NPM_TIMEOUT }
90
+ );
91
+ if (result) {
92
+ return JSON.parse(result) as NPMPackageInfo;
93
+ }
94
+ } catch {
95
+ // ignore
96
+ }
97
+ }
98
+
99
+ export function npmWhoAmI({ registry }: { registry?: string } = {}) {
100
+ try {
101
+ return runCommandOutput(['npm', 'whoami', registry ? `--registry=${registry}` : ''], {
102
+ quiet: true,
103
+ stdio: ['pipe', 'pipe', 'ignore'],
104
+ timeout: NPM_TIMEOUT,
105
+ }).trim();
106
+ } catch {
107
+ // ignore
108
+ }
109
+ }
@@ -8,25 +8,19 @@ import { log } from '../../utils';
8
8
 
9
9
  type RunCommandOptions = SpawnOptionsWithoutStdio & { quiet?: boolean };
10
10
 
11
- export const runCommand = (
11
+ export async function runCommand(
12
12
  command: string | (string | false)[],
13
13
  { quiet, ...spawnOptions }: RunCommandOptions = {}
14
- ): Promise<void> => {
15
- return new Promise((resolve, reject) => {
14
+ ) {
15
+ return new Promise<void>((resolve, reject) => {
16
16
  const commandArray: string[] = Array.isArray(command)
17
- ? command
18
- .filter(c => !!c)
19
- .map(c => c.toString())
20
- .join(' ')
21
- .split(' ')
17
+ ? command.reduce((acc, el) => (el ? [...acc, ...el.toString().split(' ')] : acc), [])
22
18
  : command.split(' ');
23
19
  const fullCommand = commandArray.join(' ');
24
-
25
20
  const commandName = commandArray.shift();
26
21
 
27
22
  if (!commandName) {
28
23
  reject(new Error('invalid command'));
29
-
30
24
  return;
31
25
  }
32
26
 
@@ -57,26 +51,19 @@ export const runCommand = (
57
51
  reject(e);
58
52
  });
59
53
  });
60
- };
54
+ }
61
55
 
62
56
  type RunCommandOutputOptions = ExecSyncOptionsWithBufferEncoding & { quiet?: boolean };
63
57
 
64
- export const runCommandOutput = (
58
+ export function runCommandOutput(
65
59
  command: string | (string | false)[],
66
60
  { quiet, ...execSyncOptions }: RunCommandOutputOptions = {}
67
- ): string => {
68
- const commandArray: string[] = Array.isArray(command)
69
- ? command
70
- .filter(c => !!c)
71
- .map(c => c.toString())
72
- .join(' ')
73
- .split(' ')
74
- : command.split(' ');
75
- const fullCommand = commandArray.join(' ');
76
-
77
- const commandName = commandArray.shift();
61
+ ) {
62
+ const fullCommand = Array.isArray(command)
63
+ ? command.reduce((acc, el) => (el ? [...acc, el.toString()] : acc), []).join(' ')
64
+ : command;
78
65
 
79
- if (!commandName) {
66
+ if (!fullCommand) {
80
67
  throw new Error();
81
68
  }
82
69
 
@@ -91,4 +78,4 @@ export const runCommandOutput = (
91
78
  }
92
79
 
93
80
  return result;
94
- };
81
+ }
@@ -1,8 +1,9 @@
1
1
  import { ESLint } from 'eslint';
2
2
 
3
3
  import { getDestinationFolders, getESLintConfiguration, log } from '../../utils';
4
+ import { CommandArgs } from '../commands';
4
5
 
5
- interface Args {
6
+ interface Args extends CommandArgs {
6
7
  fix?: boolean;
7
8
  paths: string[];
8
9
  }
@@ -11,6 +11,7 @@ export * from './eslint';
11
11
  export * from './get-module-type';
12
12
  export * from './is-ci';
13
13
  export * from './is-module-installed';
14
+ export * from './is-tty';
14
15
  export * from './lerna-exec';
15
16
  export * from './maybe-create-git-folder';
16
17
  export * from './pipe-stdout';
@@ -0,0 +1,3 @@
1
+ export function isTTY() {
2
+ return process.stdin.isTTY;
3
+ }
@@ -1,21 +1,18 @@
1
1
  import fs from 'fs';
2
-
3
- import { Init } from '../commands/init';
4
2
  import { Command, Newable } from '../commands/types';
5
3
 
4
+ const EXCLUDED_COMMANDS = ['Init', 'Install'];
5
+
6
6
  /**
7
7
  * Create empty .git folder to workaround issue where Lerna does not
8
- * detect workspace packages on Windows systems. The empty .git folder
8
+ * detect workspace packages. The empty .git folder
9
9
  * causes nx to use the git-hasher when building the project graph.
10
10
  * Note this gets fixed (e.g., https://github.com/nrwl/nx/issues/8601) but
11
11
  * keeps reappearing (e.g., https://github.com/nrwl/nx/issues/9584 and
12
12
  * https://github.com/nrwl/nx/issues/18094)
13
13
  */
14
14
  export function maybeCreateGitFolder(command: Newable<Command>) {
15
- if (process.platform !== 'win32') {
16
- return;
17
- }
18
- if (command === Init) {
15
+ if (EXCLUDED_COMMANDS.includes(command.name)) {
19
16
  return;
20
17
  }
21
18
  if (!fs.existsSync('.git')) {
@@ -42,7 +42,7 @@ export class ProcessTree<T extends Record<any, any> = never> {
42
42
  const entry = this.#entries.get(item)!;
43
43
 
44
44
  const handlerResult = Promise.all(
45
- entry.dependsOn.map(item => this.#entries.get(item)!.onComplete)
45
+ entry.dependsOn.map(item => this.#entries.get(item)!.onComplete).filter(el => !!el)
46
46
  ).then(() => ({ result: entry.handler() }));
47
47
 
48
48
  entry.process = handlerResult.then(({ result }) =>
@@ -52,6 +52,8 @@ export class ProcessTree<T extends Record<any, any> = never> {
52
52
  isHandlerResultObject(result) ? (result.onComplete ?? result.process) : result
53
53
  );
54
54
  });
55
- return Promise.all([...this.#entries.values()].map(item => item.process));
55
+ return Promise.all(
56
+ [...this.#entries.values()].map(item => item.process).filter(el => !!el)
57
+ );
56
58
  }
57
59
  }
@@ -25,7 +25,8 @@ export function setNodeOptions(commandName: CommandName, command: Command) {
25
25
  }, oldNodeOptions)
26
26
  .trim();
27
27
 
28
- const newNodeOptions = ensureMaxOldSpaceSize(mergedOptions, command.greedy);
28
+ const greedy = (command.constructor as typeof Command).greedy;
29
+ const newNodeOptions = ensureMaxOldSpaceSize(mergedOptions, greedy);
29
30
  if (newNodeOptions !== oldNodeOptions) {
30
31
  process.env.NODE_OPTIONS = newNodeOptions;
31
32
  return true;
@@ -0,0 +1,61 @@
1
+ import { formatRelativeDate } from '../format-relative-date';
2
+
3
+ describe('[startup] Utils', () => {
4
+ describe(formatRelativeDate.name, () => {
5
+ beforeAll(() => {
6
+ jest.useFakeTimers();
7
+ jest.setSystemTime(new Date(2025, 0, 1));
8
+ });
9
+ afterAll(() => jest.useRealTimers());
10
+
11
+ type DateUnit = 'seconds' | 'minutes' | 'hours' | 'days' | 'months' | 'years';
12
+
13
+ function adjustDate(when: Date, amount: number, by: DateUnit) {
14
+ const result = new Date(when);
15
+ if (by === 'seconds') {
16
+ result.setSeconds(when.getSeconds() + amount);
17
+ } else if (by === 'minutes') {
18
+ result.setMinutes(when.getMinutes() + amount);
19
+ } else if (by === 'hours') {
20
+ result.setHours(when.getHours() + amount);
21
+ } else if (by === 'days') {
22
+ result.setDate(when.getDate() + amount);
23
+ } else if (by === 'months') {
24
+ result.setMonth(when.getMonth() + amount);
25
+ } else if (by === 'years') {
26
+ result.setFullYear(when.getFullYear() + amount);
27
+ }
28
+ return result;
29
+ }
30
+
31
+ test.each<{
32
+ delta: [number, DateUnit];
33
+ expected: string;
34
+ }>([
35
+ { delta: [0, 'seconds'], expected: 'in 0 seconds' },
36
+ { delta: [1, 'seconds'], expected: 'in 1 second' },
37
+ { delta: [-2, 'seconds'], expected: '2 seconds ago' },
38
+ { delta: [1, 'minutes'], expected: 'in 1 minute' },
39
+ { delta: [-2, 'minutes'], expected: '2 minutes ago' },
40
+ { delta: [1, 'hours'], expected: 'in 1 hour' },
41
+ { delta: [-2, 'hours'], expected: '2 hours ago' },
42
+ { delta: [1, 'days'], expected: 'in 1 day' },
43
+ { delta: [-2, 'days'], expected: '2 days ago' },
44
+ { delta: [1, 'months'], expected: 'in 1 month' },
45
+ { delta: [-2, 'months'], expected: '2 months ago' },
46
+ { delta: [1, 'years'], expected: 'in 1 year' },
47
+ { delta: [-2, 'years'], expected: '2 years ago' },
48
+ ])(
49
+ `with $delta.0 $delta.1 from now, returns "$expected"`,
50
+ ({ delta: [amount, unit], expected }) => {
51
+ const now = new Date();
52
+ const from = adjustDate(now, amount, unit);
53
+ expect(formatRelativeDate(from, now)).toBe(expected);
54
+ }
55
+ );
56
+
57
+ test('with no "to", returns time relative to now', () => {
58
+ expect(formatRelativeDate(Date.now() - 61 * 1000)).toEqual('1 minute ago');
59
+ });
60
+ });
61
+ });
@@ -73,6 +73,7 @@ describe('[startup] Utils', () => {
73
73
  private: false,
74
74
  location: path.resolve('./legacy/bar'),
75
75
  type: PackageType.Legacy,
76
+ cli: { legacy: true },
76
77
  },
77
78
  {
78
79
  name: 'baz',
@@ -80,6 +81,7 @@ describe('[startup] Utils', () => {
80
81
  private: false,
81
82
  location: path.resolve('./examples/baz'),
82
83
  type: PackageType.TSC,
84
+ cli: { webpack: false },
83
85
  },
84
86
  {
85
87
  name: 'qux',
@@ -87,6 +89,7 @@ describe('[startup] Utils', () => {
87
89
  private: false,
88
90
  location: path.resolve('./examples/qux'),
89
91
  type: PackageType.TSC,
92
+ cli: { webpack: false },
90
93
  },
91
94
  ]);
92
95
  });
@@ -8,6 +8,7 @@ import { log } from './log';
8
8
  export interface ProjectPackage extends Record<string, any> {
9
9
  name: string;
10
10
  location: string;
11
+ version: string;
11
12
  }
12
13
 
13
14
  export function findPackages(): ProjectPackage[] {
@@ -0,0 +1,33 @@
1
+ const SECOND = 1000;
2
+ const MINUTE = 60 * SECOND;
3
+ const HOUR = MINUTE * 60;
4
+ const DAY = HOUR * 24;
5
+ const MONTH = DAY * 30;
6
+ const YEAR = DAY * 365;
7
+
8
+ const table: { threshold: number; divisor: number; unit: Intl.RelativeTimeFormatUnit }[] = [
9
+ { threshold: MINUTE, divisor: SECOND, unit: 'seconds' },
10
+ { threshold: HOUR, divisor: MINUTE, unit: 'minutes' },
11
+ { threshold: DAY, divisor: HOUR, unit: 'hours' },
12
+ { threshold: MONTH, divisor: DAY, unit: 'days' },
13
+ { threshold: YEAR, divisor: MONTH, unit: 'months' },
14
+ ];
15
+
16
+ export function formatRelativeDate(
17
+ from: Date | string | number,
18
+ to?: Date | string | number,
19
+ locale?: string
20
+ ) {
21
+ const dateFrom = new Date(from);
22
+ const dateTo = to ? new Date(to) : new Date();
23
+ const delta = dateFrom.getTime() - dateTo.getTime();
24
+ const absoluteDelta = Math.abs(delta);
25
+ const { divisor, unit } = table.find(({ threshold }) => absoluteDelta < threshold) ?? {
26
+ divisor: YEAR,
27
+ unit: 'years',
28
+ };
29
+ return new Intl.RelativeTimeFormat(locale, {
30
+ style: 'long',
31
+ numeric: 'always',
32
+ }).format(Math.round(delta / divisor), unit);
33
+ }
@@ -71,6 +71,7 @@ export enum CommandName {
71
71
  'install' = 'install',
72
72
  'kendo-ui-license' = 'kendo-ui-license',
73
73
  'lint' = 'lint',
74
+ 'mfe-list' = 'mfe-list',
74
75
  'mfe-package-clean' = 'mfe-package-clean',
75
76
  'mfe-package-publish' = 'mfe-package-publish',
76
77
  'mfe-publish' = 'mfe-publish',
@@ -9,12 +9,9 @@ export enum PackageType {
9
9
  Legacy,
10
10
  }
11
11
 
12
- export interface Package {
13
- name: string;
14
- type: PackageType;
15
- version: string;
12
+ export interface Package extends ProjectPackage {
16
13
  private: boolean;
17
- location: string;
14
+ type: PackageType;
18
15
  }
19
16
 
20
17
  interface GetPackagesOptions {
@@ -113,12 +110,9 @@ function filterPackages(packages: ProjectPackage[], options: GetPackagesOptions)
113
110
 
114
111
  function withMetadata(packages: ProjectPackage[]): Package[] {
115
112
  return packages.map(pkg => {
116
- const { name, version, location } = pkg;
117
113
  return {
118
- name,
119
- version,
114
+ ...pkg,
120
115
  private: pkg.private ?? false,
121
- location,
122
116
  type: getPackageType(pkg),
123
117
  };
124
118
  });
@@ -2,7 +2,5 @@ import path from 'path';
2
2
  import { readJson } from './read-json';
3
3
 
4
4
  export function getStartupVersion() {
5
- return readJson(
6
- path.join(path.dirname(require.resolve('@servicetitan/startup')), '../package.json')
7
- ).version;
5
+ return readJson(path.join(__dirname, '../../package.json')).version;
8
6
  }
@@ -1,6 +1,7 @@
1
1
  export * from './find-packages';
2
2
  export * from './find-up';
3
3
  export * from './format-duration';
4
+ export * from './format-relative-date';
4
5
  export * from './get-branch-configs';
5
6
  export * from './get-configuration';
6
7
  export * from './get-destination-folders';
@@ -81,7 +81,7 @@ export const styleRules: Record<string, StyleRule> = {
81
81
  },
82
82
  };
83
83
 
84
- export const webComponentStyleRules = Object.entries(styleRules).reduce(
84
+ export const miniCssPluginStyleRules = Object.entries(styleRules).reduce(
85
85
  (result, [key, rule]) => {
86
86
  result[key] = { ...rule, use: rule.use?.map(transformStyleLoader) };
87
87
  return result;
@@ -89,7 +89,7 @@ export const webComponentStyleRules = Object.entries(styleRules).reduce(
89
89
  {} as typeof styleRules
90
90
  );
91
91
 
92
- export const productionStyleRules = Object.entries(webComponentStyleRules).reduce(
92
+ export const productionStyleRules = Object.entries(miniCssPluginStyleRules).reduce(
93
93
  (result, [key, rule]) => {
94
94
  if (key === '.css') {
95
95
  result[key] = { ...rule, exclude: /\.module.css$/ }; // production doesn't use callback?!
@@ -98,7 +98,7 @@ export const productionStyleRules = Object.entries(webComponentStyleRules).reduc
98
98
  }
99
99
  return result;
100
100
  },
101
- {} as typeof webComponentStyleRules
101
+ {} as typeof miniCssPluginStyleRules
102
102
  );
103
103
 
104
104
  /**
@@ -20,7 +20,7 @@ import {
20
20
  log,
21
21
  pick,
22
22
  } from '../../utils';
23
- import { styleRules } from '../__mocks__';
23
+ import { miniCssPluginStyleRules } from '../__mocks__';
24
24
  import { getLaunchDarklySdkVersion } from '../configs/utils/get-launchdarkly-sdk-version';
25
25
  import { getModuleEntryPath } from '../utils';
26
26
 
@@ -218,7 +218,7 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
218
218
  );
219
219
  });
220
220
 
221
- Object.entries(styleRules).forEach(([extension, rule]) => {
221
+ Object.entries(miniCssPluginStyleRules).forEach(([extension, rule]) => {
222
222
  test(`configures "${extension}" rules`, () => {
223
223
  expect(subject().module?.rules).toContainEqual(rule);
224
224
  });
@@ -226,12 +226,8 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
226
226
  });
227
227
  });
228
228
 
229
- describe('when in production', () => {
230
- beforeEach(() => (overrides.configuration = { mode: 'production' }));
231
-
232
- test('configures "output.clean" to keep shared dependencies', () => {
233
- expect(subject().output?.clean).toEqual({ keep: /shared/ });
234
- });
229
+ test('configures "output.clean" to keep shared dependencies', () => {
230
+ expect(subject().output?.clean).toEqual({ keep: /shared/ });
235
231
  });
236
232
 
237
233
  describe('with bundled exposed dependencies', () => {
@@ -408,12 +404,8 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
408
404
  expect(HtmlWebpackPlugin).not.toHaveBeenCalled();
409
405
  });
410
406
 
411
- describe('when in production', () => {
412
- beforeEach(() => (overrides.configuration = { mode: 'production' }));
413
-
414
- test('configures "output.clean" to true', () => {
415
- expect(subject().output?.clean).toBe(true);
416
- });
407
+ test('configures "output.clean" to true', () => {
408
+ expect(subject().output?.clean).toBe(true);
417
409
  });
418
410
  });
419
411
  });
@@ -15,7 +15,7 @@ import {
15
15
  isLegacyRoot,
16
16
  isWebComponent,
17
17
  } from '../../utils';
18
- import { webComponentStyleRules } from '../__mocks__';
18
+ import { miniCssPluginStyleRules } from '../__mocks__';
19
19
  import { generateMetadata } from '../configs/utils';
20
20
  import { getCallerFile, splitByEntry } from '../utils';
21
21
 
@@ -119,6 +119,20 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
119
119
  const subject = () => createWebpackConfig(overrides, options);
120
120
 
121
121
  describe('when package is a web component', () => {
122
+ const baseCacheGroups = {
123
+ styles: {
124
+ name: 'main',
125
+ type: 'css/mini-extract',
126
+ chunks: 'all',
127
+ enforce: true,
128
+ },
129
+ servicetitan: {
130
+ name: 'servicetitan',
131
+ test: /[\\/]node_modules[\\/]@servicetitan[\\/]/,
132
+ chunks: 'all',
133
+ },
134
+ };
135
+
122
136
  beforeEach(() => jest.mocked(isWebComponent).mockReturnValue(true));
123
137
 
124
138
  test('configures MiniCssExtractPlugIn plugin', () => {
@@ -127,7 +141,7 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
127
141
  );
128
142
  });
129
143
 
130
- Object.entries(webComponentStyleRules).forEach(([extension, rule]) => {
144
+ Object.entries(miniCssPluginStyleRules).forEach(([extension, rule]) => {
131
145
  test(`configures "${extension}" rules`, () => {
132
146
  expect(subject().module?.rules).toContainEqual(rule);
133
147
  });
@@ -139,13 +153,9 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
139
153
  );
140
154
  });
141
155
 
142
- test('configures "optimization.splitChunks.cacheGroups.styles', () => {
143
- expect((subject().optimization?.splitChunks as any).cacheGroups.styles).toEqual({
144
- name: 'main',
145
- type: 'css/mini-extract',
146
- chunks: 'all',
147
- enforce: true,
148
- });
156
+ test('configures "optimization.splitChunks.cacheGroups', () => {
157
+ // @ts-expect-error because splitChunks is polymorphic
158
+ expect(subject().optimization?.splitChunks.cacheGroups).toEqual(baseCacheGroups);
149
159
  });
150
160
 
151
161
  test('configures WEB_COMPONENT_NAME', () => {
@@ -183,6 +193,25 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
183
193
  });
184
194
  });
185
195
 
196
+ test('WebpackAssetsManifest plugin moves design system css to precede other css', () => {
197
+ const assets = {
198
+ entrypoints: {
199
+ foo: {
200
+ assets: {
201
+ css: ['main.css', 'servicetitan.css', 'common.css'],
202
+ },
203
+ },
204
+ },
205
+ };
206
+
207
+ subject();
208
+
209
+ const transform: any = jest.mocked(WebpackAssetsManifest).mock.calls[0][0]?.transform;
210
+ expect(transform(assets)).toEqual(
211
+ expect.objectContaining({ css: ['servicetitan.css', 'main.css', 'common.css'] })
212
+ );
213
+ });
214
+
186
215
  test('generates metadata when WebpackAssetsManifest plugin is done', () => {
187
216
  subject();
188
217
 
@@ -373,27 +402,21 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
373
402
  expect(subject().devtool).toBe('source-map');
374
403
  });
375
404
 
376
- test('configures "optimization.splitChunks.cacheGroups"', () => {
405
+ test('adds "common" and "kendo" to "optimization.splitChunks.cacheGroups"', () => {
377
406
  // @ts-expect-error because splitChunks is polymorphic
378
- expect(subject().optimization?.splitChunks.cacheGroups).toEqual(
379
- expect.objectContaining({
380
- common: {
381
- name: 'common',
382
- test: /[\\/]node_modules[\\/](axios|classnames|formstate|mobx|mobx-react|mobx-utils|react|react-dom|react-router|react-router-dom)[\\/]/,
383
- chunks: 'all',
384
- },
385
- kendo: {
386
- name: 'kendo',
387
- test: /[\\/]node_modules[\\/](@progress|@telerik)[\\/]/,
388
- chunks: 'all',
389
- },
390
- servicetitan: {
391
- name: 'servicetitan',
392
- test: /[\\/]node_modules[\\/]@servicetitan[\\/]/,
393
- chunks: 'all',
394
- },
395
- })
396
- );
407
+ expect(subject().optimization?.splitChunks.cacheGroups).toEqual({
408
+ ...baseCacheGroups,
409
+ common: {
410
+ name: 'common',
411
+ test: /[\\/]node_modules[\\/](axios|classnames|formstate|mobx|mobx-react|mobx-utils|react|react-dom|react-router|react-router-dom)[\\/]/,
412
+ chunks: 'all',
413
+ },
414
+ kendo: {
415
+ name: 'kendo',
416
+ test: /[\\/]node_modules[\\/](@progress|@telerik)[\\/]/,
417
+ chunks: 'all',
418
+ },
419
+ });
397
420
  });
398
421
 
399
422
  test('configures "output.uniqueName"', () => {
@@ -3,9 +3,12 @@ import { Context } from '../types';
3
3
  import { LoaderOptions } from './types';
4
4
 
5
5
  export function styleLoader(
6
- { isProduction, isWebComponent }: Context,
6
+ { isProduction, isWebComponent, emitExposedDependencies }: Context,
7
7
  { esModule }: LoaderOptions = {}
8
8
  ) {
9
- const loader = isProduction || isWebComponent ? MiniCssExtractPlugin.loader : 'style-loader';
9
+ const loader =
10
+ isProduction || isWebComponent || emitExposedDependencies
11
+ ? MiniCssExtractPlugin.loader
12
+ : 'style-loader';
10
13
  return esModule ? { loader, options: { esModule } } : loader;
11
14
  }