@servicetitan/startup 32.1.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 (253) 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/runners/vitest.js +2 -1
  81. package/dist/cli/commands/test/runners/vitest.js.map +1 -1
  82. package/dist/cli/commands/test/tests.d.ts +14 -5
  83. package/dist/cli/commands/test/tests.d.ts.map +1 -1
  84. package/dist/cli/commands/test/tests.js +26 -13
  85. package/dist/cli/commands/test/tests.js.map +1 -1
  86. package/dist/cli/commands/types.d.ts +13 -4
  87. package/dist/cli/commands/types.d.ts.map +1 -1
  88. package/dist/cli/commands/types.js +28 -0
  89. package/dist/cli/commands/types.js.map +1 -1
  90. package/dist/cli/commands/upload-sourcemaps.d.ts +3 -5
  91. package/dist/cli/commands/upload-sourcemaps.d.ts.map +1 -1
  92. package/dist/cli/commands/upload-sourcemaps.js +5 -20
  93. package/dist/cli/commands/upload-sourcemaps.js.map +1 -1
  94. package/dist/cli/index.js +48 -39
  95. package/dist/cli/index.js.map +1 -1
  96. package/dist/cli/tasks/swc-compile-package.d.ts +2 -2
  97. package/dist/cli/tasks/swc-compile-package.d.ts.map +1 -1
  98. package/dist/cli/tasks/swc-compile-package.js.map +1 -1
  99. package/dist/cli/tasks/tsc-compile-package.d.ts +2 -2
  100. package/dist/cli/tasks/tsc-compile-package.d.ts.map +1 -1
  101. package/dist/cli/tasks/tsc-compile-package.js +1 -1
  102. package/dist/cli/tasks/tsc-compile-package.js.map +1 -1
  103. package/dist/cli/tasks/tsc-compile.d.ts +2 -2
  104. package/dist/cli/tasks/tsc-compile.d.ts.map +1 -1
  105. package/dist/cli/tasks/tsc-compile.js.map +1 -1
  106. package/dist/cli/utils/bundle.js +2 -2
  107. package/dist/cli/utils/bundle.js.map +1 -1
  108. package/dist/cli/utils/cli-npm.d.ts +14 -0
  109. package/dist/cli/utils/cli-npm.d.ts.map +1 -1
  110. package/dist/cli/utils/cli-npm.js +44 -0
  111. package/dist/cli/utils/cli-npm.js.map +1 -1
  112. package/dist/cli/utils/cli-os.d.ts +2 -2
  113. package/dist/cli/utils/cli-os.d.ts.map +1 -1
  114. package/dist/cli/utils/cli-os.js +13 -9
  115. package/dist/cli/utils/cli-os.js.map +1 -1
  116. package/dist/cli/utils/eslint.d.ts +2 -1
  117. package/dist/cli/utils/eslint.d.ts.map +1 -1
  118. package/dist/cli/utils/eslint.js.map +1 -1
  119. package/dist/cli/utils/index.d.ts +1 -0
  120. package/dist/cli/utils/index.d.ts.map +1 -1
  121. package/dist/cli/utils/index.js +1 -0
  122. package/dist/cli/utils/index.js.map +1 -1
  123. package/dist/cli/utils/is-tty.d.ts +2 -0
  124. package/dist/cli/utils/is-tty.d.ts.map +1 -0
  125. package/dist/cli/utils/is-tty.js +15 -0
  126. package/dist/cli/utils/is-tty.js.map +1 -0
  127. package/dist/cli/utils/maybe-create-git-folder.d.ts +1 -1
  128. package/dist/cli/utils/maybe-create-git-folder.d.ts.map +1 -1
  129. package/dist/cli/utils/maybe-create-git-folder.js +12 -6
  130. package/dist/cli/utils/maybe-create-git-folder.js.map +1 -1
  131. package/dist/cli/utils/process-tree.d.ts.map +1 -1
  132. package/dist/cli/utils/process-tree.js +2 -2
  133. package/dist/cli/utils/process-tree.js.map +1 -1
  134. package/dist/cli/utils/set-node-options.d.ts.map +1 -1
  135. package/dist/cli/utils/set-node-options.js +2 -1
  136. package/dist/cli/utils/set-node-options.js.map +1 -1
  137. package/dist/utils/find-packages.d.ts +1 -0
  138. package/dist/utils/find-packages.d.ts.map +1 -1
  139. package/dist/utils/find-packages.js.map +1 -1
  140. package/dist/utils/format-relative-date.d.ts +2 -0
  141. package/dist/utils/format-relative-date.d.ts.map +1 -0
  142. package/dist/utils/format-relative-date.js +60 -0
  143. package/dist/utils/format-relative-date.js.map +1 -0
  144. package/dist/utils/get-configuration.d.ts +10 -3
  145. package/dist/utils/get-configuration.d.ts.map +1 -1
  146. package/dist/utils/get-configuration.js +1 -0
  147. package/dist/utils/get-configuration.js.map +1 -1
  148. package/dist/utils/get-jest-config.d.ts.map +1 -1
  149. package/dist/utils/get-jest-config.js +20 -9
  150. package/dist/utils/get-jest-config.js.map +1 -1
  151. package/dist/utils/get-packages.d.ts +3 -5
  152. package/dist/utils/get-packages.d.ts.map +1 -1
  153. package/dist/utils/get-packages.js +1 -4
  154. package/dist/utils/get-packages.js.map +1 -1
  155. package/dist/utils/get-startup-version.d.ts.map +1 -1
  156. package/dist/utils/get-startup-version.js +1 -1
  157. package/dist/utils/get-startup-version.js.map +1 -1
  158. package/dist/utils/index.d.ts +2 -0
  159. package/dist/utils/index.d.ts.map +1 -1
  160. package/dist/utils/index.js +2 -0
  161. package/dist/utils/index.js.map +1 -1
  162. package/dist/utils/omit.d.ts +2 -0
  163. package/dist/utils/omit.d.ts.map +1 -0
  164. package/dist/utils/omit.js +28 -0
  165. package/dist/utils/omit.js.map +1 -0
  166. package/dist/webpack/configs/loaders/style-loader.d.ts +1 -1
  167. package/dist/webpack/configs/loaders/style-loader.d.ts.map +1 -1
  168. package/dist/webpack/configs/loaders/style-loader.js +2 -2
  169. package/dist/webpack/configs/loaders/style-loader.js.map +1 -1
  170. package/dist/webpack/configs/optimization-config.js +5 -5
  171. package/dist/webpack/configs/optimization-config.js.map +1 -1
  172. package/dist/webpack/configs/output-config.d.ts.map +1 -1
  173. package/dist/webpack/configs/output-config.js +14 -7
  174. package/dist/webpack/configs/output-config.js.map +1 -1
  175. package/dist/webpack/configs/plugins/assets-manifest-plugin.d.ts.map +1 -1
  176. package/dist/webpack/configs/plugins/assets-manifest-plugin.js +10 -3
  177. package/dist/webpack/configs/plugins/assets-manifest-plugin.js.map +1 -1
  178. package/package.json +26 -20
  179. package/src/cli/commands/__tests__/build.test.ts +1 -1
  180. package/src/cli/commands/__tests__/bundle-package.test.ts +22 -2
  181. package/src/cli/commands/__tests__/install.test.ts +42 -4
  182. package/src/cli/commands/__tests__/lint.test.ts +1 -1
  183. package/src/cli/commands/__tests__/mfe-list.test.ts +394 -0
  184. package/src/cli/commands/__tests__/mfe-publish.test.ts +25 -0
  185. package/src/cli/commands/__tests__/start.test.ts +1 -1
  186. package/src/cli/commands/build.ts +14 -10
  187. package/src/cli/commands/bundle-package.ts +19 -13
  188. package/src/cli/commands/clean.ts +2 -4
  189. package/src/cli/commands/convert-eslint-config.ts +3 -5
  190. package/src/cli/commands/eslint.ts +3 -5
  191. package/src/cli/commands/get-command.ts +2 -0
  192. package/src/cli/commands/index.ts +0 -1
  193. package/src/cli/commands/init.ts +7 -8
  194. package/src/cli/commands/install.ts +24 -11
  195. package/src/cli/commands/kendo-ui-license.ts +4 -6
  196. package/src/cli/commands/lint.ts +19 -19
  197. package/src/cli/commands/mfe-list.ts +173 -0
  198. package/src/cli/commands/mfe-package-clean.ts +25 -4
  199. package/src/cli/commands/mfe-package-publish.ts +33 -4
  200. package/src/cli/commands/mfe-publish.ts +37 -6
  201. package/src/cli/commands/prepare-package.ts +3 -5
  202. package/src/cli/commands/review/review.ts +9 -9
  203. package/src/cli/commands/run-task.ts +15 -11
  204. package/src/cli/commands/start.ts +12 -10
  205. package/src/cli/commands/styles-check.ts +2 -2
  206. package/src/cli/commands/test/__tests__/tests.test.ts +1 -1
  207. package/src/cli/commands/test/runners/__tests__/vitest.test.ts +82 -13
  208. package/src/cli/commands/test/runners/vitest.ts +4 -2
  209. package/src/cli/commands/test/tests.ts +20 -10
  210. package/src/cli/commands/types.ts +14 -4
  211. package/src/cli/commands/upload-sourcemaps.ts +3 -5
  212. package/src/cli/index.ts +59 -36
  213. package/src/cli/tasks/swc-compile-package.ts +2 -2
  214. package/src/cli/tasks/tsc-compile-package.ts +4 -3
  215. package/src/cli/tasks/tsc-compile.ts +2 -2
  216. package/src/cli/utils/__tests__/bundle.test.ts +13 -0
  217. package/src/cli/utils/__tests__/cli-npm.test.ts +89 -0
  218. package/src/cli/utils/__tests__/is-tty.test.ts +17 -0
  219. package/src/cli/utils/__tests__/maybe-create-git-folder.test.ts +10 -17
  220. package/src/cli/utils/__tests__/set-node-options.test.ts +10 -10
  221. package/src/cli/utils/bundle.ts +2 -2
  222. package/src/cli/utils/cli-npm.ts +34 -0
  223. package/src/cli/utils/cli-os.ts +12 -25
  224. package/src/cli/utils/eslint.ts +2 -1
  225. package/src/cli/utils/index.ts +1 -0
  226. package/src/cli/utils/is-tty.ts +3 -0
  227. package/src/cli/utils/maybe-create-git-folder.ts +10 -8
  228. package/src/cli/utils/process-tree.ts +4 -2
  229. package/src/cli/utils/set-node-options.ts +2 -1
  230. package/src/utils/__tests__/format-relative-date.test.ts +61 -0
  231. package/src/utils/__tests__/get-jest-config.test.ts +44 -0
  232. package/src/utils/__tests__/get-packages.test.ts +3 -0
  233. package/src/utils/find-packages.ts +1 -0
  234. package/src/utils/format-relative-date.ts +33 -0
  235. package/src/utils/get-configuration.ts +7 -2
  236. package/src/utils/get-jest-config.ts +36 -18
  237. package/src/utils/get-packages.ts +3 -9
  238. package/src/utils/get-startup-version.ts +1 -3
  239. package/src/utils/index.ts +2 -0
  240. package/src/utils/omit.ts +12 -0
  241. package/src/webpack/__mocks__/style-rules.ts +3 -3
  242. package/src/webpack/__tests__/create-webpack-config-shared-dependencies.test.ts +6 -14
  243. package/src/webpack/__tests__/create-webpack-config-web-component.test.ts +52 -29
  244. package/src/webpack/configs/loaders/style-loader.ts +5 -2
  245. package/src/webpack/configs/optimization-config.ts +5 -5
  246. package/src/webpack/configs/output-config.ts +10 -5
  247. package/src/webpack/configs/plugins/assets-manifest-plugin.ts +11 -4
  248. package/dist/cli/commands/get-user-commands.d.ts +0 -7
  249. package/dist/cli/commands/get-user-commands.d.ts.map +0 -1
  250. package/dist/cli/commands/get-user-commands.js +0 -27
  251. package/dist/cli/commands/get-user-commands.js.map +0 -1
  252. package/src/cli/commands/__tests__/get-user-commands.test.ts +0 -27
  253. package/src/cli/commands/get-user-commands.ts +0 -19
@@ -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,24 +1,26 @@
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')) {
22
- fs.mkdirSync('.git');
19
+ /*
20
+ * Using {recursive: true} to ignore if directory exists. This happens
21
+ * when parallel process creates the directory after we've checked
22
+ * whether it exists.
23
+ */
24
+ fs.mkdirSync('.git', { recursive: true });
23
25
  }
24
26
  }
@@ -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
+ });
@@ -2,6 +2,7 @@ import { Config } from '@jest/types';
2
2
  import path from 'path';
3
3
  import { getJestConfiguration } from '../get-configuration';
4
4
  import { getDestinationFolders } from '../get-destination-folders';
5
+ import { pick } from '../pick';
5
6
 
6
7
  import { getJestConfigCLI } from '../get-jest-config';
7
8
 
@@ -76,5 +77,48 @@ describe('[startup] Utils', () => {
76
77
  expect.objectContaining({ transform: JSON.stringify(transform) })
77
78
  );
78
79
  });
80
+
81
+ describe('with "omitDefault"', () => {
82
+ beforeEach(() => {
83
+ jest.mocked(getJestConfiguration).mockReturnValue({
84
+ omitDefault: Object.keys(defaultConfig),
85
+ });
86
+ });
87
+
88
+ test('omits specified defaults', () => {
89
+ expect(pick(subject(), getJestConfiguration().omitDefault!)).toEqual({});
90
+ });
91
+ });
92
+
93
+ describe.each(['coveragePathIgnorePatterns', 'setupFiles', 'testPathIgnorePatterns'])(
94
+ 'with custom "%s"',
95
+ key => {
96
+ let customConfig: Record<string, string[]>;
97
+
98
+ beforeEach(() => {
99
+ customConfig = { [key]: ['foo'] };
100
+ jest.mocked(getJestConfiguration).mockReturnValue(customConfig);
101
+ });
102
+
103
+ test('appends custom value to default', () => {
104
+ expect(subject()).toEqual(
105
+ expect.objectContaining({
106
+ [key]: [
107
+ ...defaultConfig[key],
108
+ ...(getJestConfiguration()[key] as string[]),
109
+ ],
110
+ })
111
+ );
112
+ });
113
+
114
+ describe('when default is omitted', () => {
115
+ beforeEach(() => (customConfig.omitDefault = [key]));
116
+
117
+ test('returns only custom value', () => {
118
+ expect(subject()[key]).toEqual(customConfig[key]);
119
+ });
120
+ });
121
+ }
122
+ );
79
123
  });
80
124
  });
@@ -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
+ }
@@ -51,7 +51,9 @@ export interface StylelintConfiguration extends Partial<LinterOptions> {
51
51
  disabled?: boolean;
52
52
  }
53
53
 
54
- export type JestConfiguration = Omit<Config.Argv, '_' | '$0'>;
54
+ export interface JestConfiguration extends Omit<Config.Argv, '_' | '$0'> {
55
+ omitDefault?: string[];
56
+ }
55
57
 
56
58
  export interface NodeConfiguration {
57
59
  // eslint-disable-next-line @typescript-eslint/naming-convention
@@ -69,6 +71,7 @@ export enum CommandName {
69
71
  'install' = 'install',
70
72
  'kendo-ui-license' = 'kendo-ui-license',
71
73
  'lint' = 'lint',
74
+ 'mfe-list' = 'mfe-list',
72
75
  'mfe-package-clean' = 'mfe-package-clean',
73
76
  'mfe-package-publish' = 'mfe-package-publish',
74
77
  'mfe-publish' = 'mfe-publish',
@@ -82,7 +85,9 @@ export enum CommandName {
82
85
  }
83
86
  /* eslint-enable @typescript-eslint/naming-convention */
84
87
 
85
- export type VitestConfiguration = ViteUserConfig['test'];
88
+ export type VitestConfiguration = ViteUserConfig['test'] & {
89
+ omitDefault?: string[];
90
+ };
86
91
 
87
92
  export interface WebComponentBranchConfigs {
88
93
  publishTag?: string;
@@ -3,16 +3,9 @@ import path from 'path';
3
3
  import { getJestConfiguration } from './get-configuration';
4
4
  import { getDestinationFolders } from './get-destination-folders';
5
5
  import { toArray } from './to-array';
6
+ import { omit } from './omit';
6
7
 
7
- function getDefaultJestConfiguration({
8
- coveragePathIgnorePatterns = [],
9
- setupFiles = [],
10
- testPathIgnorePatterns = [],
11
- }: {
12
- coveragePathIgnorePatterns?: string[];
13
- setupFiles?: string[];
14
- testPathIgnorePatterns?: string[];
15
- }) {
8
+ function getDefaultJestConfiguration() {
16
9
  const moduleNameMapper = {
17
10
  '\\.(css|scss|less|png|svg|svg\\?\\w+|jpg|jpeg|gif|woff|woff2|eot|ttf|otf)$':
18
11
  'identity-obj-proxy',
@@ -20,21 +13,21 @@ function getDefaultJestConfiguration({
20
13
 
21
14
  return {
22
15
  collectCoverageFrom: ['**/*.{ts,tsx}'],
23
- coveragePathIgnorePatterns: ['^.+\\.d\\.ts$', ...coveragePathIgnorePatterns],
16
+ coveragePathIgnorePatterns: ['^.+\\.d\\.ts$'],
24
17
  coverageReporters: ['html-spa', 'text', 'json', 'cobertura', 'lcov'],
25
18
  moduleNameMapper,
26
19
  modulePathIgnorePatterns: ['<rootDir>/.*/__mocks__'],
27
20
  preset: path.join(__dirname, '../../jest'),
28
- setupFiles: [path.join(__dirname, '../../jest/setup.js'), ...toArray(setupFiles)],
21
+ setupFiles: [path.join(__dirname, '../../jest/setup.js')],
29
22
  testEnvironment: 'jsdom',
30
- testPathIgnorePatterns: [
31
- '\\.yalc',
32
- ...getDestinationFolders(),
33
- ...toArray(testPathIgnorePatterns),
34
- ],
23
+ testPathIgnorePatterns: ['\\.yalc', ...getDestinationFolders()],
35
24
  testRunner: 'jest-circus/runner',
36
25
  transformIgnorePatterns: ['node_modules/(?!(@servicetitan|@react-hook|nanoid|axios)/)'],
37
26
  verbose: true,
27
+ } as Omit<Config.Argv, 'collectCoverageFrom' | 'moduleNameMapper' | 'setupFiles'> & {
28
+ collectCoverageFrom: string[];
29
+ moduleNameMapper: Record<string, string>;
30
+ setupFiles: string[];
38
31
  };
39
32
  }
40
33
 
@@ -42,13 +35,21 @@ function getDefaultJestConfiguration({
42
35
  * Get Jest config for running it using jest CLI (see jest runCLI function)
43
36
  */
44
37
  export function getJestConfigCLI(args: Config.Argv): Config.Argv {
45
- const { coveragePathIgnorePatterns, setupFiles, testPathIgnorePatterns, ...config } = {
38
+ const {
39
+ coveragePathIgnorePatterns,
40
+ omitDefault = [],
41
+ setupFiles,
42
+ testPathIgnorePatterns,
43
+ ...config
44
+ } = {
46
45
  ...getJestConfiguration(),
47
46
  ...args,
48
47
  };
49
48
 
49
+ const defaultConfig = omit(getDefaultJestConfiguration(), omitDefault);
50
+
50
51
  return stringifyForCLI({
51
- ...getDefaultJestConfiguration({
52
+ ...mergeArrayValues(defaultConfig, {
52
53
  coveragePathIgnorePatterns,
53
54
  setupFiles,
54
55
  testPathIgnorePatterns,
@@ -57,6 +58,23 @@ export function getJestConfigCLI(args: Config.Argv): Config.Argv {
57
58
  });
58
59
  }
59
60
 
61
+ function mergeArrayValues(
62
+ config: any,
63
+ arrayValues: {
64
+ coveragePathIgnorePatterns?: string | string[];
65
+ setupFiles?: string | string[];
66
+ testPathIgnorePatterns?: string | string[];
67
+ }
68
+ ) {
69
+ return Object.keys(arrayValues).reduce((result, key: keyof typeof arrayValues) => {
70
+ const newValue = arrayValues[key];
71
+ if (newValue) {
72
+ result[key] = [...toArray(result[key]), ...toArray(newValue)];
73
+ }
74
+ return result;
75
+ }, config);
76
+ }
77
+
60
78
  function stringifyForCLI(config: any): Config.Argv {
61
79
  return ['collectCoverageFrom', 'globals', 'moduleNameMapper', 'transform'].reduce(
62
80
  (result, key) => {
@@ -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';
@@ -14,6 +15,7 @@ export * from './get-tsconfig';
14
15
  export * from './load-shared-dependencies';
15
16
  export * from './log';
16
17
  export * from './log-errors';
18
+ export * from './omit';
17
19
  export * from './pick';
18
20
  export * from './read-json';
19
21
  export * from './to-array';
@@ -0,0 +1,12 @@
1
+ export function omit<T extends Record<string, any>>(obj: T, keys: string[]): T {
2
+ return keys.reduce((result, key) => omitInternal({ ...result }, key.split('.')), obj);
3
+ }
4
+
5
+ function omitInternal<T extends Record<string, any>>(obj: T, [key, ...rest]: string[]): T {
6
+ if (!rest.length) {
7
+ delete obj[key];
8
+ } else if (typeof obj[key] === 'object') {
9
+ return { ...obj, [key]: omitInternal(obj[key], rest) };
10
+ }
11
+ return obj;
12
+ }
@@ -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
  });