@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
@@ -3,12 +3,12 @@ import fs from 'fs';
3
3
  import path from 'path';
4
4
  import os from 'os';
5
5
  import { log, logErrors, getStartupVersion, readJsonSafe } from '../../utils';
6
- import { Command } from './types';
7
- import { gitCloneRepo, isCI } from '../utils';
6
+ import { Command, CommandArgs } from './types';
7
+ import { gitCloneRepo, isCI, npmWhoAmI } from '../utils';
8
8
 
9
- interface Args {
10
- quiet?: boolean;
9
+ interface Args extends CommandArgs {
11
10
  fix?: boolean;
11
+ quiet?: boolean;
12
12
  token?: boolean;
13
13
  }
14
14
 
@@ -16,12 +16,13 @@ const REPO_NAME = 'frontend-dev-config';
16
16
  const AUTH_TOKEN_KEY = '//registry.npmjs.org/:_authToken';
17
17
  const AUTH_TOKEN_REGEX = /^\/\/registry\.npmjs\.org\/:_authToken=\s*\${([^}]+)}/m;
18
18
 
19
- export class Install implements Command {
20
- constructor(private readonly args?: Args) {}
21
-
22
- description() {
23
- return 'install project dependencies';
24
- }
19
+ export class Install extends Command<Args> {
20
+ static readonly description = 'Install project dependencies';
21
+ static readonly options = {
22
+ fix: { boolean: true, describe: 'Update and dedupe package-lock.json', hidden: true },
23
+ quite: { boolean: true, describe: 'Suppress output', hidden: true },
24
+ token: { boolean: true, describe: 'Configure npm token' },
25
+ };
25
26
 
26
27
  @logErrors
27
28
  async execute() {
@@ -30,7 +31,10 @@ export class Install implements Command {
30
31
  }
31
32
 
32
33
  const env = await this.configureNpmToken();
33
- this.installPackages(env);
34
+
35
+ if (this.args?.token !== true) {
36
+ this.installPackages(env);
37
+ }
34
38
 
35
39
  return Promise.resolve(); // stops "async method has no 'await' expression" lint error
36
40
  }
@@ -44,6 +48,15 @@ export class Install implements Command {
44
48
  log.info('Configuring NPM token ...');
45
49
  }
46
50
 
51
+ if (this.args?.token !== true) {
52
+ const npmUser = npmWhoAmI();
53
+ /* istanbul ignore next: debug only */
54
+ log.debug('install:npm-user', () => JSON.stringify({ npmUser }));
55
+ if (npmUser === 'st-team') {
56
+ return;
57
+ }
58
+ }
59
+
47
60
  const token = await this.fetchNpmToken();
48
61
  if (!token) {
49
62
  return;
@@ -2,7 +2,7 @@ import execa from 'execa';
2
2
 
3
3
  import { log, logErrors } from '../../utils';
4
4
  import { isModuleInstalled } from '../utils';
5
- import { Command } from '.';
5
+ import { Command } from './types';
6
6
 
7
7
  const ENCODED_LICENSE = `
8
8
  ZXlKaGJHY2lPaUpTVXpJMU5pSXNJblI1Y0NJNklreEpReUo5LmV5SndjbTlrZFdOMGN5STZXM3Np
@@ -29,10 +29,8 @@ const ENVIRONMENT_VARIABLE = 'KENDO_UI_LICENSE';
29
29
  const LICENSE = Buffer.from(ENCODED_LICENSE, 'base64').toString('ascii');
30
30
  const LICENSING_PACKAGE = '@progress/kendo-licensing';
31
31
 
32
- export class KendoUILicense implements Command {
33
- description() {
34
- return 'install KendoReact license key';
35
- }
32
+ export class KendoUILicense extends Command {
33
+ static readonly description = 'Install KendoReact license key';
36
34
 
37
35
  async execute() {
38
36
  if (!isModuleInstalled(LICENSING_PACKAGE)) {
@@ -66,5 +64,5 @@ export class KendoUILicense implements Command {
66
64
  }
67
65
 
68
66
  export async function kendoUILicense() {
69
- return new KendoUILicense().execute();
67
+ return new KendoUILicense({}).execute();
70
68
  }
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/naming-convention */
1
2
  import path from 'path';
2
3
 
3
4
  import stylelint from 'stylelint';
@@ -9,34 +10,28 @@ import {
9
10
  log,
10
11
  logErrors,
11
12
  } from '../../utils';
12
- import { Command } from '.';
13
+ import { Command, CommandArgs } from './types';
13
14
  import { eslint, lernaExec } from '../utils';
14
15
 
15
- interface Args {
16
- // eslint-disable-next-line @typescript-eslint/naming-convention
16
+ interface Args extends CommandArgs {
17
17
  _: string[];
18
- /** Apply fixes for issues? */
19
18
  fix?: boolean;
20
- /** Packages to lint */
21
19
  scope?: string | string[];
22
- /** Packages to skip */
23
20
  ignore?: string | string[];
24
- /** Run eslint separately for each package? */
25
21
  parallel?: boolean;
22
+ paths?: string[];
26
23
  }
27
24
 
28
- export class Lint implements Command {
29
- readonly greedy = true;
30
-
31
- private readonly paths: string[];
32
-
33
- constructor(private readonly args: Args) {
34
- this.paths = [...args._];
35
- }
36
-
37
- description() {
38
- return 'run eslint and stylelint';
39
- }
25
+ export class Lint extends Command<Args> {
26
+ static readonly description = 'Run eslint and stylelint';
27
+ static readonly greedy = true;
28
+ static readonly options = {
29
+ _: { description: '[paths...]' },
30
+ fix: { boolean: true, description: 'Apply fixes for issues?' },
31
+ scope: { array: true, hidden: true, description: 'Packages to lint' },
32
+ ignore: { array: true, hidden: true, description: 'Packages to skip' },
33
+ parallel: { boolean: true, hidden: true, description: 'Lint each package separately' },
34
+ };
40
35
 
41
36
  async execute() {
42
37
  await this.checkStyles();
@@ -127,6 +122,11 @@ export class Lint implements Command {
127
122
  // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
128
123
  return !this.paths.length && (parallel || scope?.length || ignore?.length);
129
124
  }
125
+
126
+ private get paths() {
127
+ const { _, paths = [] } = this.args;
128
+ return [..._, ...paths];
129
+ }
130
130
  }
131
131
 
132
132
  function pathUniJoin(...chunks: string[]) {
@@ -0,0 +1,173 @@
1
+ /* eslint-disable @typescript-eslint/naming-convention */
2
+ import chalk from 'chalk';
3
+ import Table from 'cli-table3';
4
+ import readline from 'readline/promises';
5
+ import {
6
+ formatRelativeDate,
7
+ getPackages,
8
+ isWebComponent,
9
+ log,
10
+ logErrors,
11
+ PackageType,
12
+ } from '../../utils';
13
+ import { Command, CommandArgs } from './types';
14
+ import { isTTY, NPMPackageInfo, npmView, npmWhoAmI, runCommand } from '../utils';
15
+
16
+ interface Args extends CommandArgs {
17
+ _: string[];
18
+ all?: boolean;
19
+ ignore?: string | string[];
20
+ limit?: number;
21
+ packageNames?: string[];
22
+ registry?: string;
23
+ tagged?: boolean;
24
+ }
25
+
26
+ const collator = new Intl.Collator();
27
+
28
+ const VERDACCIO = 'https://verdaccio.servicetitan.com';
29
+
30
+ export class MFEList extends Command<Args> {
31
+ static readonly description = 'List published MFE packages';
32
+ static readonly options = {
33
+ _: { description: '[packageNames...]' },
34
+ all: { boolean: true, description: 'List all published versions ' },
35
+ ignore: {
36
+ array: true,
37
+ description: 'Exclude MFEs with names matching specified glob pattern ',
38
+ },
39
+ limit: {
40
+ number: true,
41
+ description: 'List only the specified number of published versions',
42
+ },
43
+ tagged: { boolean: true, description: 'List only tagged versions' },
44
+ };
45
+
46
+ @logErrors
47
+ async execute() {
48
+ await this.login();
49
+
50
+ this.packageNames.forEach((name, index) => {
51
+ const info = npmView({ packageName: name, registry: this.registry });
52
+ if (info) {
53
+ if (index > 0) {
54
+ process.stdout.write('\n');
55
+ }
56
+
57
+ process.stdout.write(this.getCaption(info) + '\n');
58
+ const table = this.getTable(info);
59
+ if (table) {
60
+ process.stdout.write(table + '\n');
61
+ }
62
+ }
63
+ });
64
+ }
65
+
66
+ private getCaption(info: NPMPackageInfo) {
67
+ return [
68
+ chalk.bold.cyan(info.name),
69
+ info.version && `version: ${info.version}`,
70
+ `versions: ${Object.keys(this.getTime(info)).length}`,
71
+ ]
72
+ .filter(el => !!el)
73
+ .join(' | ');
74
+ }
75
+
76
+ private getTable(info: NPMPackageInfo) {
77
+ const times = Object.entries(this.getTime(info)).sort(
78
+ ([, a], [, b]) => -1 * collator.compare(a, b)
79
+ );
80
+ const versionTags = this.getVersionTags(info);
81
+ const versions = this.args.tagged
82
+ ? times.filter(([version]) => !!versionTags[version])
83
+ : times.slice(0, this.limit);
84
+
85
+ /* istanbul ignore next: debug only */
86
+ log.debug('mfe-list', () =>
87
+ JSON.stringify({ name: info.name, versionTags, versions }, null, 2)
88
+ );
89
+
90
+ if (versions.length === 0) {
91
+ return '';
92
+ }
93
+
94
+ const table = new Table({
95
+ head: ['Version', 'Tag', 'When'].map(title => chalk.bold.cyan(title)),
96
+ style: { head: [] },
97
+ });
98
+
99
+ versions.forEach(([version, timestamp]) => {
100
+ const when = formatRelativeDate(new Date(timestamp));
101
+ const tag = (versionTags[version] ?? []).join(', ');
102
+ table.push([version, chalk.bold.cyan(tag), when]);
103
+ });
104
+
105
+ return table.toString();
106
+ }
107
+
108
+ private getTime(info: NPMPackageInfo) {
109
+ const { time: { created, modified, ...time } = {} } = info;
110
+ return time;
111
+ }
112
+
113
+ private getVersionTags({ 'dist-tags': distTags = {} }: NPMPackageInfo) {
114
+ return Object.entries(distTags).reduce<Record<string, string[]>>(
115
+ (result, [name, version]) => {
116
+ result[version] ??= [];
117
+ result[version].push(name);
118
+ return result;
119
+ },
120
+ {}
121
+ );
122
+ }
123
+
124
+ private async ask(question: string) {
125
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
126
+ const answer = await rl.question(question);
127
+ rl.close();
128
+ return answer.trim().toLowerCase();
129
+ }
130
+
131
+ private async login() {
132
+ if (this.registry !== VERDACCIO || npmWhoAmI({ registry: this.registry }) !== undefined) {
133
+ return;
134
+ }
135
+
136
+ const message = `This machine is not authorized to access ${this.registry}.`;
137
+ if (!isTTY()) {
138
+ throw new Error(message);
139
+ }
140
+
141
+ const answer = await this.ask(chalk.bold.cyan(`${message} Authorize? [Y/n] `));
142
+ if (answer && answer !== 'y') {
143
+ throw new Error('Not authorized');
144
+ }
145
+
146
+ await runCommand(`npx --yes verdaccio-okta-oauth@latest --registry=${this.registry}`, {
147
+ quiet: true,
148
+ });
149
+ }
150
+
151
+ private get limit() {
152
+ if (this.args.all) {
153
+ return Number.MAX_SAFE_INTEGER;
154
+ }
155
+ return this.args.limit && this.args.limit > 0 ? this.args.limit : 20;
156
+ }
157
+
158
+ private get packageNames() {
159
+ const { _, packageNames = [] } = this.args;
160
+ if (_.length || packageNames.length) {
161
+ return [..._, ...packageNames];
162
+ }
163
+
164
+ return getPackages({ ignore: this.args.ignore, type: PackageType.Webpack })
165
+ .filter(isWebComponent)
166
+ .map(({ name }) => name)
167
+ .sort((a, b) => collator.compare(a, b));
168
+ }
169
+
170
+ private get registry() {
171
+ return this.args.registry ?? VERDACCIO;
172
+ }
173
+ }
@@ -1,8 +1,8 @@
1
1
  import { getBranchesConfigs, isWebComponent, log, logErrors, readJson } from '../../utils';
2
2
  import { gitGetBranch, npmGetPackageVersionsDetails, npmUnpublish, Version } from '../utils';
3
- import { Command } from './types';
3
+ import { Command, CommandArgs } from './types';
4
4
 
5
- export interface Args {
5
+ export interface Args extends CommandArgs {
6
6
  all?: true;
7
7
  branch?: string;
8
8
  count?: number;
@@ -10,8 +10,29 @@ export interface Args {
10
10
  registry?: string;
11
11
  }
12
12
 
13
- export class MFEPackageClean implements Command {
14
- constructor(private readonly args: Args) {}
13
+ export class MFEPackageClean extends Command<Args> {
14
+ static readonly options = {
15
+ all: {
16
+ boolean: true,
17
+ description: 'Unpublish old versions from all branches',
18
+ defaultDescription: 'false',
19
+ },
20
+ branch: {
21
+ string: true,
22
+ description: 'Branch name of versions to unpublish',
23
+ defaultDescription: 'current git branch',
24
+ },
25
+ count: {
26
+ number: true,
27
+ description: 'Keep the specified number of old versions',
28
+ defaultDescription: '5',
29
+ },
30
+ dry: {
31
+ boolean: true,
32
+ description: 'Take no action and only log what would be unpublished',
33
+ },
34
+ registry: { string: true, hidden: true, description: 'Registry url' },
35
+ };
15
36
 
16
37
  @logErrors
17
38
  async execute() {
@@ -19,9 +19,9 @@ import {
19
19
  npmTagVersion,
20
20
  runCommand,
21
21
  } from '../utils';
22
- import { Command } from './types';
22
+ import { Command, CommandArgs } from './types';
23
23
 
24
- export interface Args {
24
+ export interface Args extends CommandArgs {
25
25
  branch?: string;
26
26
  build?: string;
27
27
  dry?: boolean;
@@ -49,8 +49,37 @@ interface PackageJson {
49
49
  files?: string[];
50
50
  }
51
51
 
52
- export class MFEPackagePublish implements Command {
53
- constructor(private readonly args: Args) {}
52
+ export class MFEPackagePublish extends Command<Args> {
53
+ static readonly options = {
54
+ 'branch': {
55
+ string: true,
56
+ description: 'Branch name to associate with published version',
57
+ defaultDescription: 'current git branch',
58
+ },
59
+ 'build': {
60
+ string: true,
61
+ description: 'Package version',
62
+ defaultDescription: '<branch_name>.<commit_hash>',
63
+ },
64
+ 'dry': {
65
+ boolean: true,
66
+ description: 'Take no action and only log what would be published',
67
+ },
68
+ 'force': {
69
+ boolean: true,
70
+ description: 'Force publishing from an unrecognized branch',
71
+ },
72
+ 'registry': { string: true, hidden: true, description: 'Registry url' },
73
+ 'tag': {
74
+ string: true,
75
+ description: 'Tag to assign to published version',
76
+ },
77
+ 'upload-source-maps': {
78
+ boolean: true,
79
+ description: 'Upload source maps to Datadog?',
80
+ defaultDescription: 'true',
81
+ },
82
+ };
54
83
 
55
84
  @logErrors
56
85
  async execute() {
@@ -1,6 +1,6 @@
1
1
  import { getPackages, isWebComponent, logErrors, PackageType } from '../../utils';
2
- import { Args as CleanArgs } from './mfe-package-clean';
3
- import { Args as PublishArgs } from './mfe-package-publish';
2
+ import { Args as CleanArgs, MFEPackageClean } from './mfe-package-clean';
3
+ import { Args as PublishArgs, MFEPackagePublish } from './mfe-package-publish';
4
4
  import { Command } from './types';
5
5
  import { lernaExec } from '../utils';
6
6
 
@@ -10,11 +10,42 @@ interface Args extends PublishArgs, CleanArgs {
10
10
  scope?: string | string[];
11
11
  }
12
12
 
13
- export class MFEPublish implements Command {
14
- constructor(private readonly args: Args) {}
13
+ export class MFEPublish extends Command<Args> {
14
+ static readonly description = 'Publish or unpublish MFE packages';
15
+ static get options() {
16
+ const publishOptions = Object.entries(MFEPackagePublish.options).reduce(
17
+ (result, [key, value]) => {
18
+ result[key] = { group: 'Publish Options:', ...value };
19
+ return result;
20
+ },
21
+ {} as NonNullable<typeof Command.options>
22
+ );
23
+
24
+ const cleanOptions = Object.entries(MFEPackageClean.options).reduce(
25
+ (result, [key, value]) => {
26
+ result[Object.hasOwn(publishOptions, key) ? `${key}\u00A0` : key] = {
27
+ group: 'Clean Options:',
28
+ ...value,
29
+ };
30
+ return result;
31
+ },
32
+ {} as NonNullable<typeof Command.options>
33
+ );
15
34
 
16
- description() {
17
- return 'publish or unpublish MFE packages';
35
+ return {
36
+ clean: { boolean: true, description: 'Unpublish old versions' },
37
+ concurrency: {
38
+ number: true,
39
+ description: 'Publish/unpublish the specified number of packages concurrently',
40
+ defaultDescription: '1',
41
+ },
42
+ scope: {
43
+ array: true,
44
+ description: 'Publish/unpublish only the specified packages',
45
+ },
46
+ ...publishOptions,
47
+ ...cleanOptions,
48
+ };
18
49
  }
19
50
 
20
51
  @logErrors
@@ -1,14 +1,12 @@
1
1
  import { logErrors } from '../../utils';
2
2
  import { copyFiles } from '../utils';
3
- import { Command } from './types';
3
+ import { Command, CommandArgs } from './types';
4
4
 
5
- interface Args {
5
+ interface Args extends CommandArgs {
6
6
  watch?: boolean;
7
7
  }
8
8
 
9
- export class PreparePackage implements Command {
10
- constructor(private readonly args: Args) {}
11
-
9
+ export class PreparePackage extends Command<Args> {
12
10
  @logErrors
13
11
  execute() {
14
12
  return copyFiles({ watch: this.args.watch });
@@ -9,7 +9,7 @@ import {
9
9
  readJsonSafe,
10
10
  toArray,
11
11
  } from '../../../utils';
12
- import { Command } from '../types';
12
+ import { Command, CommandArgs } from '../types';
13
13
 
14
14
  import {
15
15
  ErrorSeverity,
@@ -33,12 +33,18 @@ import { rules } from './rules';
33
33
 
34
34
  const collator = new Intl.Collator();
35
35
 
36
- interface Args {
36
+ interface Args extends CommandArgs {
37
37
  fix?: boolean;
38
38
  rule?: string | string[];
39
39
  }
40
40
 
41
- export class Review implements Command {
41
+ export class Review extends Command<Args> {
42
+ static readonly description = 'Check project for configuration errors';
43
+ static readonly options = {
44
+ fix: { boolean: true, description: 'Fix detected problems' },
45
+ rule: { array: true, description: 'Limit checks to specified rule(s)' },
46
+ };
47
+
42
48
  private readonly severityToLabel: Record<ErrorSeverity, string> = {
43
49
  [ErrorSeverity.warning]: chalk.yellow('warning'),
44
50
  [ErrorSeverity.error]: chalk.red('error'),
@@ -49,12 +55,6 @@ export class Review implements Command {
49
55
  error: ErrorSeverity.error,
50
56
  };
51
57
 
52
- constructor(private readonly args: Args) {}
53
-
54
- description() {
55
- return 'check project for configuration errors';
56
- }
57
-
58
58
  @logErrors
59
59
  async execute() {
60
60
  const errors = this.args.fix ? this.fixErrors() : this.findErrors();
@@ -1,33 +1,37 @@
1
+ /* eslint-disable @typescript-eslint/naming-convention */
1
2
  import { log, logErrors } from '../../utils';
2
- import { Command } from './types';
3
3
  import { SwcCompilePackage } from '../tasks/swc-compile-package';
4
4
  import { TscCompilePackage } from '../tasks/tsc-compile-package';
5
5
  import { TscCompile } from '../tasks/tsc-compile';
6
6
  import { Task } from '../tasks/task';
7
+ import { Command, CommandArgs } from './types';
7
8
 
8
- interface Args {
9
- [key: string]: unknown;
10
- // eslint-disable-next-line @typescript-eslint/naming-convention
9
+ interface Args extends CommandArgs {
11
10
  _: string[];
11
+ taskName?: string;
12
+ taskArgs?: string[];
12
13
  }
13
14
 
14
- const tasks: Record<string, new (args: Args) => Task> = {
15
+ const tasks: Record<string, new (args: { [key: string]: unknown }) => Task> = {
15
16
  'tsc-compile-package': TscCompilePackage,
16
17
  'swc-compile-package': SwcCompilePackage,
17
18
  'tsc-compile': TscCompile,
18
19
  };
19
20
 
20
- export class RunTask implements Command {
21
- constructor(private readonly args: Args) {}
21
+ export class RunTask extends Command<Args> {
22
+ static readonly options = {
23
+ _: { description: '<taskName> [taskArgs...]' },
24
+ };
22
25
 
23
26
  @logErrors
24
27
  async execute() {
25
- const taskName = this.args._[0];
28
+ const { _, taskName = this.args._[0], taskArgs = [], ...restOptions } = this.args;
26
29
 
27
30
  if (taskName in tasks) {
28
- // eslint-disable-next-line @typescript-eslint/naming-convention
29
- const trimArgs = { ...this.args, _: this.args._.slice(1) };
30
- await new tasks[taskName](trimArgs).execute();
31
+ await new tasks[taskName]({
32
+ _: [..._, ...taskArgs],
33
+ ...restOptions,
34
+ }).execute();
31
35
  return;
32
36
  }
33
37
 
@@ -8,9 +8,9 @@ import {
8
8
  watchStdout,
9
9
  ProcessTree,
10
10
  } from '../utils';
11
- import { Command } from './types';
11
+ import { Command, CommandArgs } from './types';
12
12
 
13
- interface Args {
13
+ interface Args extends CommandArgs {
14
14
  'config'?: string;
15
15
  'code-coverage'?: boolean;
16
16
  'ignore'?: string | string[];
@@ -28,14 +28,16 @@ enum StartProcesses {
28
28
  BundlePackage,
29
29
  }
30
30
 
31
- export class Start implements Command {
32
- readonly greedy = true;
33
-
34
- constructor(private readonly args: Args) {}
35
-
36
- description() {
37
- return 'run project in development mode';
38
- }
31
+ export class Start extends Command<Args> {
32
+ static readonly description = 'Run project in development mode';
33
+ static readonly greedy = true;
34
+ static readonly options = {
35
+ 'config': { string: true, hidden: true, description: 'Use specified configuration' },
36
+ 'code-coverage': { boolean: true, description: 'Instrument code for coverage analysis?' },
37
+ 'ignore': { array: true, description: 'Packages to skip' },
38
+ 'scope': { array: true, description: 'Packages to run and watch' },
39
+ 'use-tsc': { boolean: true, description: 'Use tsc to compile packages?' },
40
+ };
39
41
 
40
42
  @logErrors
41
43
  async execute() {
@@ -2,7 +2,7 @@ import fs from 'fs';
2
2
  import { glob } from 'glob';
3
3
  import path from 'path';
4
4
  import { getFolders, isBundle, isLegacy, isStyleCheckDisabled, log, logErrors } from '../../utils';
5
- import { Command } from './index';
5
+ import { Command } from './types';
6
6
 
7
7
  const patterns = [
8
8
  "@import '~@servicetitan/tokens/core/tokens.css';",
@@ -10,7 +10,7 @@ const patterns = [
10
10
  "@import '~@servicetitan/design-system/dist/system.min.css';",
11
11
  ];
12
12
 
13
- export class StylesCheck implements Command {
13
+ export class StylesCheck extends Command {
14
14
  @logErrors
15
15
  async execute() {
16
16
  if (isLegacy() || !isBundle()) {
@@ -23,7 +23,7 @@ describe(`[startup] ${Tests.name}`, () => {
23
23
  const subject = async () => new Tests(args).execute();
24
24
 
25
25
  test('command is greedy', () => {
26
- expect(new Tests(args).greedy).toBe(true);
26
+ expect(Tests.greedy).toBe(true);
27
27
  });
28
28
 
29
29
  function itRunsJest() {