@servicetitan/startup 32.2.0 → 32.3.1

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 (244) 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 +47 -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/lerna-exec.d.ts.map +1 -1
  126. package/dist/cli/utils/lerna-exec.js +2 -0
  127. package/dist/cli/utils/lerna-exec.js.map +1 -1
  128. package/dist/cli/utils/maybe-create-git-folder.d.ts +2 -3
  129. package/dist/cli/utils/maybe-create-git-folder.d.ts.map +1 -1
  130. package/dist/cli/utils/maybe-create-git-folder.js +4 -9
  131. package/dist/cli/utils/maybe-create-git-folder.js.map +1 -1
  132. package/dist/cli/utils/process-tree.d.ts.map +1 -1
  133. package/dist/cli/utils/process-tree.js +2 -2
  134. package/dist/cli/utils/process-tree.js.map +1 -1
  135. package/dist/cli/utils/set-node-options.d.ts.map +1 -1
  136. package/dist/cli/utils/set-node-options.js +2 -1
  137. package/dist/cli/utils/set-node-options.js.map +1 -1
  138. package/dist/utils/find-packages.d.ts +1 -0
  139. package/dist/utils/find-packages.d.ts.map +1 -1
  140. package/dist/utils/find-packages.js.map +1 -1
  141. package/dist/utils/format-relative-date.d.ts +2 -0
  142. package/dist/utils/format-relative-date.d.ts.map +1 -0
  143. package/dist/utils/format-relative-date.js +60 -0
  144. package/dist/utils/format-relative-date.js.map +1 -0
  145. package/dist/utils/get-configuration.d.ts +1 -0
  146. package/dist/utils/get-configuration.d.ts.map +1 -1
  147. package/dist/utils/get-configuration.js +1 -0
  148. package/dist/utils/get-configuration.js.map +1 -1
  149. package/dist/utils/get-packages.d.ts +3 -5
  150. package/dist/utils/get-packages.d.ts.map +1 -1
  151. package/dist/utils/get-packages.js +1 -4
  152. package/dist/utils/get-packages.js.map +1 -1
  153. package/dist/utils/get-startup-version.d.ts.map +1 -1
  154. package/dist/utils/get-startup-version.js +1 -1
  155. package/dist/utils/get-startup-version.js.map +1 -1
  156. package/dist/utils/index.d.ts +1 -0
  157. package/dist/utils/index.d.ts.map +1 -1
  158. package/dist/utils/index.js +1 -0
  159. package/dist/utils/index.js.map +1 -1
  160. package/dist/webpack/configs/loaders/style-loader.d.ts +1 -1
  161. package/dist/webpack/configs/loaders/style-loader.d.ts.map +1 -1
  162. package/dist/webpack/configs/loaders/style-loader.js +2 -2
  163. package/dist/webpack/configs/loaders/style-loader.js.map +1 -1
  164. package/dist/webpack/configs/optimization-config.js +5 -5
  165. package/dist/webpack/configs/optimization-config.js.map +1 -1
  166. package/dist/webpack/configs/output-config.d.ts.map +1 -1
  167. package/dist/webpack/configs/output-config.js +14 -7
  168. package/dist/webpack/configs/output-config.js.map +1 -1
  169. package/dist/webpack/configs/plugins/assets-manifest-plugin.d.ts.map +1 -1
  170. package/dist/webpack/configs/plugins/assets-manifest-plugin.js +10 -3
  171. package/dist/webpack/configs/plugins/assets-manifest-plugin.js.map +1 -1
  172. package/package.json +9 -8
  173. package/src/cli/commands/__tests__/build.test.ts +1 -1
  174. package/src/cli/commands/__tests__/bundle-package.test.ts +22 -2
  175. package/src/cli/commands/__tests__/install.test.ts +42 -4
  176. package/src/cli/commands/__tests__/lint.test.ts +1 -1
  177. package/src/cli/commands/__tests__/mfe-list.test.ts +394 -0
  178. package/src/cli/commands/__tests__/mfe-publish.test.ts +25 -0
  179. package/src/cli/commands/__tests__/start.test.ts +1 -1
  180. package/src/cli/commands/build.ts +14 -10
  181. package/src/cli/commands/bundle-package.ts +19 -13
  182. package/src/cli/commands/clean.ts +2 -4
  183. package/src/cli/commands/convert-eslint-config.ts +3 -5
  184. package/src/cli/commands/eslint.ts +3 -5
  185. package/src/cli/commands/get-command.ts +2 -0
  186. package/src/cli/commands/index.ts +0 -1
  187. package/src/cli/commands/init.ts +7 -8
  188. package/src/cli/commands/install.ts +24 -11
  189. package/src/cli/commands/kendo-ui-license.ts +4 -6
  190. package/src/cli/commands/lint.ts +19 -19
  191. package/src/cli/commands/mfe-list.ts +173 -0
  192. package/src/cli/commands/mfe-package-clean.ts +25 -4
  193. package/src/cli/commands/mfe-package-publish.ts +33 -4
  194. package/src/cli/commands/mfe-publish.ts +37 -6
  195. package/src/cli/commands/prepare-package.ts +3 -5
  196. package/src/cli/commands/review/review.ts +9 -9
  197. package/src/cli/commands/run-task.ts +15 -11
  198. package/src/cli/commands/start.ts +12 -10
  199. package/src/cli/commands/styles-check.ts +2 -2
  200. package/src/cli/commands/test/__tests__/tests.test.ts +1 -1
  201. package/src/cli/commands/test/tests.ts +20 -10
  202. package/src/cli/commands/types.ts +14 -4
  203. package/src/cli/commands/upload-sourcemaps.ts +3 -5
  204. package/src/cli/index.ts +59 -37
  205. package/src/cli/tasks/swc-compile-package.ts +2 -2
  206. package/src/cli/tasks/tsc-compile-package.ts +4 -3
  207. package/src/cli/tasks/tsc-compile.ts +2 -2
  208. package/src/cli/utils/__tests__/bundle.test.ts +13 -0
  209. package/src/cli/utils/__tests__/cli-npm.test.ts +89 -0
  210. package/src/cli/utils/__tests__/is-tty.test.ts +17 -0
  211. package/src/cli/utils/__tests__/lerna-exec.test.ts +7 -0
  212. package/src/cli/utils/__tests__/maybe-create-git-folder.test.ts +11 -32
  213. package/src/cli/utils/__tests__/set-node-options.test.ts +10 -10
  214. package/src/cli/utils/bundle.ts +1 -1
  215. package/src/cli/utils/cli-npm.ts +34 -0
  216. package/src/cli/utils/cli-os.ts +12 -25
  217. package/src/cli/utils/eslint.ts +2 -1
  218. package/src/cli/utils/index.ts +1 -0
  219. package/src/cli/utils/is-tty.ts +3 -0
  220. package/src/cli/utils/lerna-exec.ts +3 -0
  221. package/src/cli/utils/maybe-create-git-folder.ts +5 -12
  222. package/src/cli/utils/process-tree.ts +4 -2
  223. package/src/cli/utils/set-node-options.ts +2 -1
  224. package/src/utils/__tests__/format-relative-date.test.ts +61 -0
  225. package/src/utils/__tests__/get-packages.test.ts +3 -0
  226. package/src/utils/find-packages.ts +1 -0
  227. package/src/utils/format-relative-date.ts +33 -0
  228. package/src/utils/get-configuration.ts +1 -0
  229. package/src/utils/get-packages.ts +3 -9
  230. package/src/utils/get-startup-version.ts +1 -3
  231. package/src/utils/index.ts +1 -0
  232. package/src/webpack/__mocks__/style-rules.ts +3 -3
  233. package/src/webpack/__tests__/create-webpack-config-shared-dependencies.test.ts +6 -14
  234. package/src/webpack/__tests__/create-webpack-config-web-component.test.ts +52 -29
  235. package/src/webpack/configs/loaders/style-loader.ts +5 -2
  236. package/src/webpack/configs/optimization-config.ts +5 -5
  237. package/src/webpack/configs/output-config.ts +10 -5
  238. package/src/webpack/configs/plugins/assets-manifest-plugin.ts +11 -4
  239. package/dist/cli/commands/get-user-commands.d.ts +0 -7
  240. package/dist/cli/commands/get-user-commands.d.ts.map +0 -1
  241. package/dist/cli/commands/get-user-commands.js +0 -27
  242. package/dist/cli/commands/get-user-commands.js.map +0 -1
  243. package/src/cli/commands/__tests__/get-user-commands.test.ts +0 -27
  244. package/src/cli/commands/get-user-commands.ts +0 -19
@@ -3,6 +3,8 @@ import { lernaExec } from '../../utils';
3
3
  import { Package, PackageType, getPackages } from '../../../utils';
4
4
  import { createPackage } from '../../../__mocks__';
5
5
 
6
+ import { MFEPackageClean } from '../mfe-package-clean';
7
+ import { MFEPackagePublish } from '../mfe-package-publish';
6
8
  import { MFEPublish } from '../mfe-publish';
7
9
 
8
10
  jest.mock('fs', () => fs);
@@ -209,4 +211,27 @@ describe(`[startup] ${MFEPublish.name}`, () => {
209
211
  });
210
212
  });
211
213
  });
214
+
215
+ describe('options', () => {
216
+ const subject = () => MFEPublish.options;
217
+
218
+ test('groups publish and clean options', () => {
219
+ expect(subject()).toEqual(
220
+ expect.objectContaining({
221
+ ...Object.fromEntries(
222
+ Object.entries(MFEPackagePublish.options).map(([key, value]) => [
223
+ key,
224
+ { group: 'Publish Options:', ...value },
225
+ ])
226
+ ),
227
+ ...Object.fromEntries(
228
+ Object.entries(MFEPackageClean.options).map(([key, value]) => [
229
+ Object.hasOwn(MFEPackagePublish.options, key) ? `${key}\u00A0` : key,
230
+ { group: 'Clean Options:', ...value },
231
+ ])
232
+ ),
233
+ })
234
+ );
235
+ });
236
+ });
212
237
  });
@@ -83,7 +83,7 @@ describe(`[startup] ${Start.name}`, () => {
83
83
  }
84
84
 
85
85
  test('command is greedy', () => {
86
- expect(new Start(args).greedy).toBe(true);
86
+ expect(Start.greedy).toBe(true);
87
87
  });
88
88
 
89
89
  describe('with TSC package', () => {
@@ -1,9 +1,9 @@
1
1
  import { getPackages, logErrors, PackageType } from '../../utils';
2
2
  import { checkArgs, compile, lernaExec, typeCheck, ProcessTree } from '../utils';
3
3
  import { kendoUILicense } from './kendo-ui-license';
4
- import { Command } from './types';
4
+ import { Command, CommandArgs } from './types';
5
5
 
6
- interface Args {
6
+ interface Args extends CommandArgs {
7
7
  'cdn-path'?: string;
8
8
  'code-coverage'?: boolean;
9
9
  'config'?: string;
@@ -22,14 +22,18 @@ enum BuildProcesses {
22
22
  BundlePackage,
23
23
  }
24
24
 
25
- export class Build implements Command {
26
- readonly greedy = true;
27
-
28
- constructor(private readonly args: Args) {}
29
-
30
- description() {
31
- return 'build project for production';
32
- }
25
+ export class Build extends Command<Args> {
26
+ static readonly description = 'Build project for production';
27
+ static readonly greedy = true;
28
+ static readonly options = {
29
+ 'cdn-path': { string: true, description: 'Base url for application assets' },
30
+ 'code-coverage': { boolean: true, description: 'Instrument code for coverage analysis?' },
31
+ 'config': { string: true, hidden: true, description: 'Use specified configuration' },
32
+ 'ignore': { array: true, description: 'Packages to skip' },
33
+ 'scope': { array: true, description: 'Packages to build' },
34
+ 'stat': { boolean: true, description: 'Generate bundle report?' },
35
+ 'use-tsc': { boolean: true, description: 'Use tsc to compile packages?' },
36
+ };
33
37
 
34
38
  @logErrors
35
39
  async execute() {
@@ -1,21 +1,27 @@
1
1
  import { getTsConfig, log, logErrors } from '../../utils';
2
2
  import { bundle, getModuleType } from '../utils';
3
- import { Command } from '.';
3
+ import { Command, CommandArgs } from './types';
4
4
 
5
- interface Args {
6
- 'config'?: string;
7
- 'code-coverage'?: boolean;
8
- 'exposed-dependencies'?: boolean;
9
- 'stat'?: boolean;
10
- 'watch'?: boolean;
5
+ interface Args extends CommandArgs {
6
+ codeCoverage?: boolean;
7
+ config?: string;
8
+ exposedDependencies?: boolean;
9
+ stat?: boolean;
10
+ useWatchConfig?: boolean;
11
+ watch?: boolean;
11
12
  }
12
13
 
13
- export class BundlePackage implements Command {
14
- constructor(private readonly args: Args) {}
15
-
14
+ export class BundlePackage extends Command<Args> {
16
15
  @logErrors
17
16
  async execute() {
18
- const { config, stat = false, watch } = this.args;
17
+ const {
18
+ config,
19
+ codeCoverage,
20
+ exposedDependencies: emitExposedDependencies,
21
+ stat = false,
22
+ useWatchConfig,
23
+ watch,
24
+ } = this.args;
19
25
 
20
26
  if (getModuleType(getTsConfig()) !== 'esnext') {
21
27
  log.warning(
@@ -23,11 +29,11 @@ export class BundlePackage implements Command {
23
29
  );
24
30
  }
25
31
 
26
- const emitExposedDependencies = this.args['exposed-dependencies'];
27
32
  const options: Parameters<typeof bundle>[0] = {
28
33
  ...(emitExposedDependencies ? {} : { config }),
29
- codeCoverage: this.args['code-coverage'],
34
+ codeCoverage,
30
35
  emitExposedDependencies,
36
+ useWatchConfig,
31
37
  };
32
38
 
33
39
  await bundle({ buildStat: stat, ...options, watch });
@@ -2,10 +2,8 @@ import { exec, execSync } from 'child_process';
2
2
  import { log, logErrors } from '../../utils';
3
3
  import { Command } from './types';
4
4
 
5
- export class Clean implements Command {
6
- description() {
7
- return 'reset project to fresh state';
8
- }
5
+ export class Clean extends Command {
6
+ static readonly description = 'Reset project to fresh state';
9
7
 
10
8
  @logErrors
11
9
  async execute() {
@@ -40,7 +40,9 @@ interface Recipe {
40
40
  import: { as: string; from?: string };
41
41
  }
42
42
 
43
- export class ConvertEslintConfig implements Command {
43
+ export class ConvertEslintConfig extends Command {
44
+ static readonly description = 'Convert v8.x eslintrc.json to v9.x flat config';
45
+
44
46
  private static readonly recipes: Record<string, Recipe | null> = {
45
47
  '@servicetitan/eslint-config/mono': {
46
48
  import: { as: 'mono' },
@@ -74,10 +76,6 @@ export class ConvertEslintConfig implements Command {
74
76
  'prettier': null,
75
77
  };
76
78
 
77
- description() {
78
- return 'convert v8.x eslintrc.json to v9.x flat config';
79
- }
80
-
81
79
  @logErrors
82
80
  async execute() {
83
81
  if (!fs.existsSync(oldConfigFile)) {
@@ -1,16 +1,14 @@
1
- import { Command } from '.';
2
1
  import { logErrors } from '../../utils';
3
2
  import { eslint } from '../utils';
3
+ import { Command, CommandArgs } from './types';
4
4
 
5
- interface Args {
5
+ interface Args extends CommandArgs {
6
6
  // eslint-disable-next-line @typescript-eslint/naming-convention
7
7
  _: string[];
8
8
  fix?: boolean;
9
9
  }
10
10
 
11
- export class ESLintCommand implements Command {
12
- constructor(private readonly args: Args) {}
13
-
11
+ export class ESLintCommand extends Command<Args> {
14
12
  @logErrors
15
13
  async execute() {
16
14
  const { _: paths, fix } = this.args;
@@ -9,6 +9,7 @@ import { Init } from './init';
9
9
  import { Install } from './install';
10
10
  import { KendoUILicense } from './kendo-ui-license';
11
11
  import { Lint } from './lint';
12
+ import { MFEList } from './mfe-list';
12
13
  import { MFEPackageClean } from './mfe-package-clean';
13
14
  import { MFEPackagePublish } from './mfe-package-publish';
14
15
  import { MFEPublish } from './mfe-publish';
@@ -31,6 +32,7 @@ const commands: Record<CommandName, Newable<Command>> = {
31
32
  [CommandName.install]: Install,
32
33
  [CommandName['kendo-ui-license']]: KendoUILicense,
33
34
  [CommandName.lint]: Lint,
35
+ [CommandName['mfe-list']]: MFEList,
34
36
  [CommandName['mfe-package-clean']]: MFEPackageClean,
35
37
  [CommandName['mfe-package-publish']]: MFEPackagePublish,
36
38
  [CommandName['mfe-publish']]: MFEPublish,
@@ -2,7 +2,6 @@ export * from './build';
2
2
  export * from './bundle-package';
3
3
  export * from './eslint';
4
4
  export * from './get-command';
5
- export * from './get-user-commands';
6
5
  export * from './init';
7
6
  export * from './install';
8
7
  export * from './kendo-ui-license';
@@ -3,20 +3,19 @@ import path from 'path';
3
3
 
4
4
  import { log, logErrors } from '../../utils';
5
5
  import { gitCloneRepo, gitIsReachable } from '../utils';
6
- import { Command } from './types';
6
+ import { Command, CommandArgs } from './types';
7
7
 
8
- interface Args {
8
+ interface Args extends CommandArgs {
9
9
  output?: string;
10
10
  }
11
11
 
12
12
  const REPO_NAME = 'frontend-example';
13
13
 
14
- export class Init implements Command {
15
- constructor(private readonly args: Args) {}
16
-
17
- description() {
18
- return 'create example project';
19
- }
14
+ export class Init extends Command<Args> {
15
+ static readonly description = 'Create example project';
16
+ static readonly options = {
17
+ output: { string: true, description: 'Output path' },
18
+ };
20
19
 
21
20
  @logErrors
22
21
  async execute() {
@@ -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() {