@servicetitan/startup 31.4.0 → 31.5.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 (234) hide show
  1. package/dist/cli/commands/build.d.ts +0 -7
  2. package/dist/cli/commands/build.d.ts.map +1 -1
  3. package/dist/cli/commands/build.js +28 -17
  4. package/dist/cli/commands/build.js.map +1 -1
  5. package/dist/cli/commands/bundle-package.d.ts +1 -1
  6. package/dist/cli/commands/bundle-package.d.ts.map +1 -1
  7. package/dist/cli/commands/bundle-package.js +13 -21
  8. package/dist/cli/commands/bundle-package.js.map +1 -1
  9. package/dist/cli/commands/clean.js +1 -1
  10. package/dist/cli/commands/clean.js.map +1 -1
  11. package/dist/cli/commands/eslint.d.ts +0 -1
  12. package/dist/cli/commands/eslint.d.ts.map +1 -1
  13. package/dist/cli/commands/eslint.js +0 -3
  14. package/dist/cli/commands/eslint.js.map +1 -1
  15. package/dist/cli/commands/get-command.d.ts.map +1 -1
  16. package/dist/cli/commands/get-command.js +3 -1
  17. package/dist/cli/commands/get-command.js.map +1 -1
  18. package/dist/cli/commands/get-user-commands.js +3 -2
  19. package/dist/cli/commands/get-user-commands.js.map +1 -1
  20. package/dist/cli/commands/init.js.map +1 -1
  21. package/dist/cli/commands/install.js.map +1 -1
  22. package/dist/cli/commands/lint.js.map +1 -1
  23. package/dist/cli/commands/mfe-package-clean.d.ts +3 -4
  24. package/dist/cli/commands/mfe-package-clean.d.ts.map +1 -1
  25. package/dist/cli/commands/mfe-package-clean.js +0 -3
  26. package/dist/cli/commands/mfe-package-clean.js.map +1 -1
  27. package/dist/cli/commands/mfe-package-publish.d.ts +9 -4
  28. package/dist/cli/commands/mfe-package-publish.d.ts.map +1 -1
  29. package/dist/cli/commands/mfe-package-publish.js +70 -47
  30. package/dist/cli/commands/mfe-package-publish.js.map +1 -1
  31. package/dist/cli/commands/mfe-publish.d.ts +3 -3
  32. package/dist/cli/commands/mfe-publish.d.ts.map +1 -1
  33. package/dist/cli/commands/mfe-publish.js +7 -1
  34. package/dist/cli/commands/mfe-publish.js.map +1 -1
  35. package/dist/cli/commands/prepare-package.d.ts +0 -1
  36. package/dist/cli/commands/prepare-package.d.ts.map +1 -1
  37. package/dist/cli/commands/prepare-package.js +0 -3
  38. package/dist/cli/commands/prepare-package.js.map +1 -1
  39. package/dist/cli/commands/review/review.js.map +1 -1
  40. package/dist/cli/commands/review/rules/require-one-anvil-uikit-contrib-version.js.map +1 -1
  41. package/dist/cli/commands/review/rules/require-one-collection-version.js.map +1 -1
  42. package/dist/cli/commands/review/rules/require-one-uikit-version.js.map +1 -1
  43. package/dist/cli/commands/run-task.d.ts +0 -1
  44. package/dist/cli/commands/run-task.d.ts.map +1 -1
  45. package/dist/cli/commands/run-task.js +0 -3
  46. package/dist/cli/commands/run-task.js.map +1 -1
  47. package/dist/cli/commands/start.d.ts +0 -8
  48. package/dist/cli/commands/start.d.ts.map +1 -1
  49. package/dist/cli/commands/start.js +28 -16
  50. package/dist/cli/commands/start.js.map +1 -1
  51. package/dist/cli/commands/styles-check.d.ts +0 -1
  52. package/dist/cli/commands/styles-check.d.ts.map +1 -1
  53. package/dist/cli/commands/styles-check.js +40 -99
  54. package/dist/cli/commands/styles-check.js.map +1 -1
  55. package/dist/cli/commands/tests.js.map +1 -1
  56. package/dist/cli/commands/types.d.ts +1 -1
  57. package/dist/cli/commands/types.d.ts.map +1 -1
  58. package/dist/cli/commands/upload-sourcemaps.d.ts +22 -0
  59. package/dist/cli/commands/upload-sourcemaps.d.ts.map +1 -0
  60. package/dist/cli/commands/upload-sourcemaps.js +179 -0
  61. package/dist/cli/commands/upload-sourcemaps.js.map +1 -0
  62. package/dist/cli/tasks/cli-task.js.map +1 -1
  63. package/dist/cli/tasks/swc-compile-package.js.map +1 -1
  64. package/dist/cli/tasks/task.js.map +1 -1
  65. package/dist/cli/tasks/tsc-compile-package.js.map +1 -1
  66. package/dist/cli/tasks/tsc-compile.js.map +1 -1
  67. package/dist/cli/utils/bundle.d.ts +4 -1
  68. package/dist/cli/utils/bundle.d.ts.map +1 -1
  69. package/dist/cli/utils/bundle.js +67 -74
  70. package/dist/cli/utils/bundle.js.map +1 -1
  71. package/dist/cli/utils/cli-os.js +2 -2
  72. package/dist/cli/utils/cli-os.js.map +1 -1
  73. package/dist/cli/utils/ts-config.js.map +1 -1
  74. package/dist/utils/find-packages.d.ts.map +1 -1
  75. package/dist/utils/find-packages.js +3 -4
  76. package/dist/utils/find-packages.js.map +1 -1
  77. package/dist/utils/find-up.d.ts +2 -0
  78. package/dist/utils/find-up.d.ts.map +1 -0
  79. package/dist/utils/find-up.js +28 -0
  80. package/dist/utils/find-up.js.map +1 -0
  81. package/dist/utils/get-configuration.d.ts +3 -1
  82. package/dist/utils/get-configuration.d.ts.map +1 -1
  83. package/dist/utils/get-configuration.js +1 -0
  84. package/dist/utils/get-configuration.js.map +1 -1
  85. package/dist/utils/index.d.ts +1 -0
  86. package/dist/utils/index.d.ts.map +1 -1
  87. package/dist/utils/index.js +1 -0
  88. package/dist/utils/index.js.map +1 -1
  89. package/dist/utils/log.js.map +1 -1
  90. package/dist/webpack/configs/cache-config.d.ts +6 -0
  91. package/dist/webpack/configs/cache-config.d.ts.map +1 -0
  92. package/dist/webpack/configs/cache-config.js +52 -0
  93. package/dist/webpack/configs/cache-config.js.map +1 -0
  94. package/dist/webpack/configs/dev-server-config.js +1 -1
  95. package/dist/webpack/configs/dev-server-config.js.map +1 -1
  96. package/dist/webpack/configs/entry.config.d.ts.map +1 -1
  97. package/dist/webpack/configs/entry.config.js +15 -6
  98. package/dist/webpack/configs/entry.config.js.map +1 -1
  99. package/dist/webpack/configs/externals-config.d.ts.map +1 -1
  100. package/dist/webpack/configs/externals-config.js +6 -2
  101. package/dist/webpack/configs/externals-config.js.map +1 -1
  102. package/dist/webpack/configs/index.d.ts +1 -0
  103. package/dist/webpack/configs/index.d.ts.map +1 -1
  104. package/dist/webpack/configs/index.js +1 -0
  105. package/dist/webpack/configs/index.js.map +1 -1
  106. package/dist/webpack/configs/optimization-config.d.ts.map +1 -1
  107. package/dist/webpack/configs/optimization-config.js +7 -11
  108. package/dist/webpack/configs/optimization-config.js.map +1 -1
  109. package/dist/webpack/configs/output-config.d.ts.map +1 -1
  110. package/dist/webpack/configs/output-config.js +25 -4
  111. package/dist/webpack/configs/output-config.js.map +1 -1
  112. package/dist/webpack/configs/plugins/assets-manifest-plugin.d.ts +6 -0
  113. package/dist/webpack/configs/plugins/assets-manifest-plugin.d.ts.map +1 -1
  114. package/dist/webpack/configs/plugins/assets-manifest-plugin.js +50 -8
  115. package/dist/webpack/configs/plugins/assets-manifest-plugin.js.map +1 -1
  116. package/dist/webpack/configs/plugins/bundle-analyser-plugin.d.ts.map +1 -1
  117. package/dist/webpack/configs/plugins/bundle-analyser-plugin.js +3 -7
  118. package/dist/webpack/configs/plugins/bundle-analyser-plugin.js.map +1 -1
  119. package/dist/webpack/configs/plugins/define-exposed-dependencies-plugin.d.ts.map +1 -1
  120. package/dist/webpack/configs/plugins/define-exposed-dependencies-plugin.js +3 -2
  121. package/dist/webpack/configs/plugins/define-exposed-dependencies-plugin.js.map +1 -1
  122. package/dist/webpack/configs/plugins/define-exposed-instance-dependencies-plugin.js +2 -2
  123. package/dist/webpack/configs/plugins/define-exposed-instance-dependencies-plugin.js.map +1 -1
  124. package/dist/webpack/configs/plugins/html-plugin.d.ts +1 -1
  125. package/dist/webpack/configs/plugins/html-plugin.d.ts.map +1 -1
  126. package/dist/webpack/configs/plugins/html-plugin.js +2 -3
  127. package/dist/webpack/configs/plugins/html-plugin.js.map +1 -1
  128. package/dist/webpack/configs/plugins/html-tags-plugin.d.ts +4 -0
  129. package/dist/webpack/configs/plugins/html-tags-plugin.d.ts.map +1 -0
  130. package/dist/webpack/configs/plugins/html-tags-plugin.js +49 -0
  131. package/dist/webpack/configs/plugins/html-tags-plugin.js.map +1 -0
  132. package/dist/webpack/configs/plugins/index.d.ts +2 -0
  133. package/dist/webpack/configs/plugins/index.d.ts.map +1 -1
  134. package/dist/webpack/configs/plugins/index.js +2 -0
  135. package/dist/webpack/configs/plugins/index.js.map +1 -1
  136. package/dist/webpack/configs/plugins/remove-empty-scripts-plugin.d.ts +4 -0
  137. package/dist/webpack/configs/plugins/remove-empty-scripts-plugin.d.ts.map +1 -0
  138. package/dist/webpack/configs/plugins/remove-empty-scripts-plugin.js +25 -0
  139. package/dist/webpack/configs/plugins/remove-empty-scripts-plugin.js.map +1 -0
  140. package/dist/webpack/configs/plugins/virtual-modules-plugin.d.ts +1 -0
  141. package/dist/webpack/configs/plugins/virtual-modules-plugin.d.ts.map +1 -1
  142. package/dist/webpack/configs/plugins/virtual-modules-plugin.js +23 -14
  143. package/dist/webpack/configs/plugins/virtual-modules-plugin.js.map +1 -1
  144. package/dist/webpack/configs/plugins-config.d.ts.map +1 -1
  145. package/dist/webpack/configs/plugins-config.js +2 -0
  146. package/dist/webpack/configs/plugins-config.js.map +1 -1
  147. package/dist/webpack/configs/rules/css-rules.d.ts.map +1 -1
  148. package/dist/webpack/configs/rules/css-rules.js +13 -18
  149. package/dist/webpack/configs/rules/css-rules.js.map +1 -1
  150. package/dist/webpack/configs/utils/get-bundle-type.d.ts +3 -0
  151. package/dist/webpack/configs/utils/get-bundle-type.d.ts.map +1 -0
  152. package/dist/webpack/configs/utils/get-bundle-type.js +24 -0
  153. package/dist/webpack/configs/utils/get-bundle-type.js.map +1 -0
  154. package/dist/webpack/configs/utils/index.d.ts +1 -0
  155. package/dist/webpack/configs/utils/index.d.ts.map +1 -1
  156. package/dist/webpack/configs/utils/index.js +1 -0
  157. package/dist/webpack/configs/utils/index.js.map +1 -1
  158. package/dist/webpack/create-webpack-config.d.ts.map +1 -1
  159. package/dist/webpack/create-webpack-config.js +37 -48
  160. package/dist/webpack/create-webpack-config.js.map +1 -1
  161. package/dist/webpack/types.d.ts +4 -0
  162. package/dist/webpack/types.d.ts.map +1 -1
  163. package/dist/webpack/utils/index.d.ts +1 -0
  164. package/dist/webpack/utils/index.d.ts.map +1 -1
  165. package/dist/webpack/utils/index.js +1 -0
  166. package/dist/webpack/utils/index.js.map +1 -1
  167. package/dist/webpack/utils/stringify-config.d.ts +2 -0
  168. package/dist/webpack/utils/stringify-config.d.ts.map +1 -0
  169. package/dist/webpack/utils/stringify-config.js +35 -0
  170. package/dist/webpack/utils/stringify-config.js.map +1 -0
  171. package/package.json +16 -14
  172. package/src/cli/commands/__tests__/build.test.ts +19 -2
  173. package/src/cli/commands/__tests__/bundle-package.test.ts +29 -8
  174. package/src/cli/commands/__tests__/clean.test.ts +2 -0
  175. package/src/cli/commands/__tests__/get-user-commands.test.ts +1 -1
  176. package/src/cli/commands/__tests__/mfe-package-publish.test.ts +91 -15
  177. package/src/cli/commands/__tests__/mfe-publish.test.ts +2 -0
  178. package/src/cli/commands/__tests__/start.test.ts +15 -1
  179. package/src/cli/commands/__tests__/styles-check.test.ts +27 -80
  180. package/src/cli/commands/__tests__/upload-sourcemaps.test.ts +127 -0
  181. package/src/cli/commands/build.ts +33 -17
  182. package/src/cli/commands/bundle-package.ts +10 -19
  183. package/src/cli/commands/clean.ts +1 -1
  184. package/src/cli/commands/eslint.ts +0 -4
  185. package/src/cli/commands/get-command.ts +2 -0
  186. package/src/cli/commands/get-user-commands.ts +1 -1
  187. package/src/cli/commands/mfe-package-clean.ts +2 -6
  188. package/src/cli/commands/mfe-package-publish.ts +104 -70
  189. package/src/cli/commands/mfe-publish.ts +8 -5
  190. package/src/cli/commands/prepare-package.ts +0 -4
  191. package/src/cli/commands/run-task.ts +0 -4
  192. package/src/cli/commands/start.ts +22 -5
  193. package/src/cli/commands/styles-check.ts +28 -131
  194. package/src/cli/commands/types.ts +1 -1
  195. package/src/cli/commands/upload-sourcemaps.ts +108 -0
  196. package/src/cli/utils/__tests__/bundle.test.ts +119 -9
  197. package/src/cli/utils/__tests__/cli-os.test.ts +2 -2
  198. package/src/cli/utils/__tests__/compile.test.ts +2 -0
  199. package/src/cli/utils/__tests__/type-check.test.ts +2 -0
  200. package/src/cli/utils/bundle.ts +76 -54
  201. package/src/cli/utils/cli-os.ts +2 -2
  202. package/src/utils/__tests__/get-configuration.test.ts +1 -1
  203. package/src/utils/find-packages.ts +3 -5
  204. package/src/utils/find-up.ts +12 -0
  205. package/src/utils/get-configuration.ts +2 -0
  206. package/src/utils/index.ts +1 -0
  207. package/src/webpack/__mocks__/style-rules.ts +1 -1
  208. package/src/webpack/__tests__/create-webpack-config-shared-dependencies.test.ts +274 -45
  209. package/src/webpack/__tests__/create-webpack-config-web-component.test.ts +25 -1
  210. package/src/webpack/__tests__/create-webpack-config.test.ts +9 -57
  211. package/src/webpack/configs/cache-config.ts +37 -0
  212. package/src/webpack/configs/dev-server-config.ts +1 -1
  213. package/src/webpack/configs/entry.config.ts +18 -8
  214. package/src/webpack/configs/externals-config.ts +7 -2
  215. package/src/webpack/configs/index.ts +1 -0
  216. package/src/webpack/configs/optimization-config.ts +7 -11
  217. package/src/webpack/configs/output-config.ts +23 -7
  218. package/src/webpack/configs/plugins/assets-manifest-plugin.ts +46 -10
  219. package/src/webpack/configs/plugins/bundle-analyser-plugin.ts +1 -6
  220. package/src/webpack/configs/plugins/define-exposed-dependencies-plugin.ts +3 -2
  221. package/src/webpack/configs/plugins/define-exposed-instance-dependencies-plugin.ts +2 -2
  222. package/src/webpack/configs/plugins/html-plugin.ts +2 -3
  223. package/src/webpack/configs/plugins/html-tags-plugin.ts +28 -0
  224. package/src/webpack/configs/plugins/index.ts +2 -0
  225. package/src/webpack/configs/plugins/remove-empty-scripts-plugin.ts +11 -0
  226. package/src/webpack/configs/plugins/virtual-modules-plugin.ts +27 -16
  227. package/src/webpack/configs/plugins-config.ts +4 -0
  228. package/src/webpack/configs/rules/css-rules.ts +19 -20
  229. package/src/webpack/configs/utils/get-bundle-type.ts +22 -0
  230. package/src/webpack/configs/utils/index.ts +1 -0
  231. package/src/webpack/create-webpack-config.ts +46 -52
  232. package/src/webpack/types.ts +4 -0
  233. package/src/webpack/utils/index.ts +1 -0
  234. package/src/webpack/utils/stringify-config.ts +19 -0
@@ -0,0 +1,108 @@
1
+ import path from 'path';
2
+ import { execSync } from 'child_process';
3
+ import { getTsConfig, isWebComponent, log, logErrors, readJson } from '../../utils';
4
+ import { Command } from './types';
5
+ import { TSConfig } from '../utils';
6
+
7
+ interface Args {
8
+ dry?: boolean;
9
+ releaseVersion: string;
10
+ }
11
+
12
+ interface PackageJson {
13
+ name: string;
14
+ }
15
+
16
+ export class UploadSourcemaps implements Command {
17
+ #outDir?: string;
18
+ #packageJson?: PackageJson;
19
+
20
+ constructor(private readonly args: Args) {}
21
+
22
+ @logErrors
23
+ // eslint-disable-next-line @typescript-eslint/require-await
24
+ async execute() {
25
+ this.checkLocation();
26
+ if (!this.checkArgs()) {
27
+ return;
28
+ }
29
+
30
+ const bundleDir = this.getBundleDir();
31
+ const options = this.getOptions().join(' ');
32
+ this.run(`npx --yes @datadog/datadog-ci@3 sourcemaps upload ${bundleDir} ${options}`);
33
+ }
34
+
35
+ private checkArgs() {
36
+ if (!process.env.DATADOG_API_KEY) {
37
+ const message = 'DATADOG_API_KEY environment variable is not set';
38
+ if (!process.env.CI) {
39
+ throw new Error(message);
40
+ }
41
+ log.warning(`${message}; skipping sourcemaps`);
42
+ return false;
43
+ }
44
+
45
+ if (!this.args.releaseVersion) {
46
+ throw new Error('--release-version is required');
47
+ }
48
+
49
+ return true;
50
+ }
51
+
52
+ private checkLocation() {
53
+ if (!isWebComponent()) {
54
+ throw new Error(`this command must be run inside a web-component directory`);
55
+ }
56
+ }
57
+
58
+ private getBundleDir() {
59
+ return path.relative('.', path.join(this.getOutDir(), 'bundle'));
60
+ }
61
+
62
+ private getMinifiedPrefixPath() {
63
+ const { name } = this.getPackageJson();
64
+ const baseUrl = `https://unpkg.servicetitan.com/${name}@${this.args.releaseVersion}`;
65
+ return `${baseUrl}/${this.getBundleDir().replace(/\\/g, '/')}`;
66
+ }
67
+
68
+ private getOptions() {
69
+ const { dry, releaseVersion } = this.args;
70
+ const service = this.getPackageJson().name.replace(/^[^/]+\//, '');
71
+ return [
72
+ ...[dry && `--dry-run`],
73
+ `--service=${service}`,
74
+ `--release-version=${releaseVersion}`,
75
+ `--minified-path-prefix=${this.getMinifiedPrefixPath()}`,
76
+ `--project-path=${this.getProjectPath()}`,
77
+ ].filter(item => !!item) as string[];
78
+ }
79
+
80
+ private getOutDir() {
81
+ if (!this.#outDir) {
82
+ const outDir = new TSConfig(getTsConfig()).getValue<string>('compilerOptions.outDir');
83
+ if (!outDir) {
84
+ throw new Error('compilerOptions.outDir is not configured');
85
+ }
86
+
87
+ this.#outDir = outDir;
88
+ }
89
+ return this.#outDir;
90
+ }
91
+
92
+ private getPackageJson() {
93
+ if (!this.#packageJson) {
94
+ this.#packageJson = readJson<PackageJson>('package.json');
95
+ }
96
+ return this.#packageJson;
97
+ }
98
+
99
+ private getProjectPath() {
100
+ const name = readJson(path.join(this.getOutDir(), 'metadata.json')).name;
101
+ return `${name}/`;
102
+ }
103
+
104
+ private run(command: string) {
105
+ log.info(`Running: ${command}`);
106
+ return execSync(command, { stdio: 'inherit' });
107
+ }
108
+ }
@@ -8,17 +8,13 @@ import {
8
8
  getFolders,
9
9
  getPackageData,
10
10
  hasHeadlessBundle,
11
+ isExposeSharedDependencies,
11
12
  loadSharedDependencies,
12
13
  } from '../../../utils';
13
14
  import { createWebpackConfig } from '../../../webpack';
14
15
  import { createPackage } from '../../../__mocks__';
15
16
 
16
- import {
17
- bundle,
18
- bundleWatch,
19
- webpackDevConfigFileName,
20
- webpackProdConfigFileName,
21
- } from '../bundle';
17
+ import { bundle, webpackDevConfigFileName, webpackProdConfigFileName } from '../bundle';
22
18
 
23
19
  jest.mock('fs', () => fs);
24
20
  jest.mock('portfinder');
@@ -29,8 +25,9 @@ jest.mock('../../../utils', () => ({
29
25
  getFolders: jest.fn(),
30
26
  getPackageData: jest.fn(),
31
27
  hasHeadlessBundle: jest.fn(),
28
+ isExposeSharedDependencies: jest.fn(),
32
29
  loadSharedDependencies: jest.fn(),
33
- log: { info: jest.fn() }, // suppress test output
30
+ log: { info: jest.fn(), debug: jest.fn() }, // suppress test output
34
31
  }));
35
32
  jest.mock('../../../webpack', () => ({ createWebpackConfig: jest.fn() }));
36
33
 
@@ -46,6 +43,7 @@ describe('[startup] Cli Utils', () => {
46
43
  jest.mocked(getPortPromise).mockImplementation(options =>
47
44
  Promise.resolve(options?.port ?? 0)
48
45
  );
46
+ jest.mocked(isExposeSharedDependencies).mockImplementation(() => false);
49
47
  compiler = { close: jest.fn(callback => callback(null)) };
50
48
  });
51
49
 
@@ -102,6 +100,29 @@ describe('[startup] Cli Utils', () => {
102
100
  expect(stdoutSpy).toHaveBeenCalledWith(`${stats.toString!()}\n`);
103
101
  });
104
102
 
103
+ describe('with "emitExposedDependencies"', () => {
104
+ beforeEach(() => (options = { emitExposedDependencies: true }));
105
+
106
+ test('does nothing', async () => {
107
+ await subject();
108
+
109
+ expect(createWebpackConfig).not.toHaveBeenCalled();
110
+ });
111
+
112
+ describe('when package exposes dependencies', () => {
113
+ beforeEach(() => jest.mocked(isExposeSharedDependencies).mockReturnValue(true));
114
+
115
+ test('emits exposed dependences', async () => {
116
+ await subject();
117
+
118
+ expect(createWebpackConfig).toHaveBeenCalledWith(
119
+ expect.anything(),
120
+ expect.objectContaining({ emitExposedDependencies: true })
121
+ );
122
+ });
123
+ });
124
+ });
125
+
105
126
  describe('when webpack completes with errors', () => {
106
127
  const stats = { hasErrors: () => true, toString: () => 'Oops!' };
107
128
 
@@ -144,6 +165,7 @@ describe('[startup] Cli Utils', () => {
144
165
  test(`uses ${params.name}`, async () => {
145
166
  await subject();
146
167
 
168
+ expect(createWebpackConfig).not.toHaveBeenCalled();
147
169
  expect(webpack).toHaveBeenCalledWith(params.config());
148
170
  });
149
171
  }
@@ -169,6 +191,83 @@ describe('[startup] Cli Utils', () => {
169
191
  itUsesConfig({ name: webpackProdConfigFileName, config: () => prodConfig });
170
192
  });
171
193
  });
194
+
195
+ describe('when emitting dependencies', () => {
196
+ beforeEach(() => {
197
+ options = { emitExposedDependencies: true };
198
+ jest.mocked(isExposeSharedDependencies).mockReturnValue(true);
199
+ });
200
+
201
+ function itIgnoresProdConfig() {
202
+ test(`ignores ${webpackProdConfigFileName}`, async () => {
203
+ await subject();
204
+
205
+ expect(createWebpackConfig).toHaveBeenCalled();
206
+ });
207
+ }
208
+
209
+ itIgnoresProdConfig();
210
+
211
+ describe(`when ${webpackProdConfigFileName} contains "output"`, () => {
212
+ const prodOutput = { path: './foo' };
213
+
214
+ beforeEach(() => {
215
+ jest.resetModules();
216
+ jest.doMock(
217
+ path.resolve(webpackProdConfigFileName),
218
+ () => ({ output: prodOutput }),
219
+ { virtual: true }
220
+ );
221
+ });
222
+
223
+ function itUsesProdOutputConfig() {
224
+ test(`uses ${webpackProdConfigFileName} "output" config`, async () => {
225
+ await subject();
226
+
227
+ expect(createWebpackConfig).toHaveBeenCalledWith(
228
+ expect.anything(),
229
+ expect.objectContaining({
230
+ emitExposedDependencies: { output: prodOutput },
231
+ })
232
+ );
233
+ });
234
+ }
235
+
236
+ itUsesProdOutputConfig();
237
+
238
+ describe(`when ${webpackDevConfigFileName} contains "output"`, () => {
239
+ const devOutput = { path: './bar' };
240
+
241
+ beforeEach(() => {
242
+ vol.fromJSON({ ...FS, [webpackDevConfigFileName]: '' });
243
+ jest.doMock(
244
+ path.resolve(webpackDevConfigFileName),
245
+ () => ({ output: devOutput }),
246
+ { virtual: true }
247
+ );
248
+ });
249
+
250
+ itUsesProdOutputConfig();
251
+
252
+ describe('with "useWatchConfig"', () => {
253
+ beforeEach(() => (options = { ...options, useWatchConfig: true }));
254
+
255
+ test(`uses ${webpackDevConfigFileName} "output" config`, async () => {
256
+ await subject();
257
+
258
+ expect(createWebpackConfig).toHaveBeenCalledWith(
259
+ expect.anything(),
260
+ expect.objectContaining({
261
+ emitExposedDependencies: {
262
+ output: devOutput,
263
+ },
264
+ })
265
+ );
266
+ });
267
+ });
268
+ });
269
+ });
270
+ });
172
271
  });
173
272
 
174
273
  describe('when package is a web component', () => {
@@ -271,7 +370,7 @@ describe('[startup] Cli Utils', () => {
271
370
  });
272
371
  });
273
372
 
274
- describe(`${bundleWatch.name}`, () => {
373
+ describe(`${bundle.name} (watch mode)`, () => {
275
374
  const devConfig = {
276
375
  devServer: { host: 'http://127.0.0.0', port: '9000' },
277
376
  configuration: { foo: 'bar' },
@@ -302,13 +401,14 @@ describe('[startup] Cli Utils', () => {
302
401
  stopWatching(callback);
303
402
  return { compiler, close: compiler.close };
304
403
  });
404
+ jest.resetModules();
305
405
  // Allows config files to be loaded with require(...)
306
406
  jest.doMock(path.resolve(customConfigFileName), () => customConfig, { virtual: true });
307
407
  jest.doMock(path.resolve(webpackDevConfigFileName), () => devConfig, { virtual: true });
308
408
  });
309
409
 
310
410
  const subject = async () => {
311
- await expect(bundleWatch(options)).rejects.toThrow('stopped');
411
+ await expect(bundle({ ...options, watch: true })).rejects.toThrow('stopped');
312
412
  };
313
413
 
314
414
  test('runs webpack development server', async () => {
@@ -325,6 +425,16 @@ describe('[startup] Cli Utils', () => {
325
425
  );
326
426
  });
327
427
 
428
+ describe('with "emitExposedDependencies"', () => {
429
+ beforeEach(() => (options = { emitExposedDependencies: true }));
430
+
431
+ test('throws error', async () => {
432
+ await expect(subject()).rejects.toThrow(
433
+ 'cannot bundle exposed dependencies in watch mode'
434
+ );
435
+ });
436
+ });
437
+
328
438
  describe('when webpack.devServer is set to false in package.json', () => {
329
439
  beforeEach(() => {
330
440
  vol.fromJSON(packageFS({ webpack: { devServer: false } } as any));
@@ -71,7 +71,7 @@ describe('[startup] Cli Utils (OS)', () => {
71
71
  const logInfoSpy = jest.spyOn(log, 'info');
72
72
  await subject('foo');
73
73
 
74
- expect(logInfoSpy).toHaveBeenCalledWith('run command foo');
74
+ expect(logInfoSpy).toHaveBeenCalledWith('Running: foo');
75
75
  expect(logInfoSpy).toHaveBeenCalledWith('command finished with code 0', 'foo');
76
76
  });
77
77
 
@@ -128,7 +128,7 @@ describe('[startup] Cli Utils (OS)', () => {
128
128
  const logInfoSpy = jest.spyOn(log, 'info');
129
129
  subject('foo');
130
130
 
131
- expect(logInfoSpy).toHaveBeenCalledWith('run command foo');
131
+ expect(logInfoSpy).toHaveBeenCalledWith('Running: foo');
132
132
  expect(logInfoSpy).toHaveBeenCalledWith('command finished', '');
133
133
  });
134
134
 
@@ -1,3 +1,4 @@
1
+ import { log } from '../../../utils';
1
2
  import { lernaExec } from '../lerna-exec';
2
3
  import { compile } from '../compile';
3
4
 
@@ -11,6 +12,7 @@ describe('[startup] Cli Utils', () => {
11
12
 
12
13
  beforeEach(() => {
13
14
  jest.clearAllMocks();
15
+ jest.spyOn(log, 'info').mockImplementation(jest.fn()); // suppress output
14
16
  args = { packages };
15
17
  });
16
18
 
@@ -1,4 +1,5 @@
1
1
  import execa from 'execa';
2
+ import { log } from '../../../utils';
2
3
  import { typeCheck } from '../type-check';
3
4
 
4
5
  jest.mock('execa', () => jest.fn());
@@ -10,6 +11,7 @@ describe('[startup] Cli Utils', () => {
10
11
 
11
12
  beforeEach(() => {
12
13
  jest.clearAllMocks();
14
+ jest.spyOn(log, 'info').mockImplementation(jest.fn()); // suppress output
13
15
  args = { packages };
14
16
  });
15
17
 
@@ -10,15 +10,21 @@ import {
10
10
  getPackageName,
11
11
  hasHeadlessBundle,
12
12
  isDevServerDisabled,
13
+ isExposeSharedDependencies,
13
14
  isWebComponent,
14
15
  log,
16
+ pick,
15
17
  } from '../../utils';
16
18
  import { Overrides, createWebpackConfig } from '../../webpack';
19
+ import { stringifyConfig } from '../../webpack/utils';
17
20
 
18
21
  interface Options {
19
22
  buildStat?: boolean;
20
23
  codeCoverage?: boolean;
21
24
  config?: string;
25
+ emitExposedDependencies?: boolean | Pick<Configuration, 'output'>;
26
+ useWatchConfig?: boolean;
27
+ watch?: boolean;
22
28
  }
23
29
 
24
30
  function getName() {
@@ -34,72 +40,88 @@ export const webpackDevConfigFileName = 'webpack.dev.config.js';
34
40
  export const webpackProdConfigFileName = 'webpack.prod.config.js';
35
41
 
36
42
  export async function bundle(options: Options = {}) {
37
- log.info('Bundling the package...');
43
+ const { emitExposedDependencies, useWatchConfig, watch } = options;
44
+ if (emitExposedDependencies) {
45
+ if (watch) {
46
+ throw new Error('cannot bundle exposed dependencies in watch mode');
47
+ }
48
+ if (!isExposeSharedDependencies()) {
49
+ return;
50
+ }
51
+ }
52
+
53
+ log.info(`Bundling ${emitExposedDependencies ? 'exposed dependencies' : 'package'}...`);
38
54
 
39
- const name = getName();
40
- const mode = 'production';
41
- const fallback = `./${webpackProdConfigFileName}`;
42
- const config = readWebpackConfig({ ...options, fallback });
43
- const { buildStat, codeCoverage } = options;
44
- const webpackOptions = { name, buildStat, codeCoverage };
55
+ const mode = watch ? 'development' : 'production';
56
+ const fallback = watch || useWatchConfig ? webpackDevConfigFileName : webpackProdConfigFileName;
57
+ const customConfig = readWebpackConfig({ ...options, fallback });
58
+ const webpackOptions = getWebpackOptions(options, customConfig);
59
+
60
+ log.debug('custom-webpack-config', () => stringifyConfig(customConfig));
45
61
 
46
62
  if (isWebComponent()) {
47
- const webpackConfig: Overrides = {
48
- configuration: { ...config?.configuration, mode },
49
- plugins: config?.plugins,
50
- };
51
-
52
- const bundles = [
53
- run(createWebpackConfig(webpackConfig, { embed: true, ...webpackOptions })),
54
- run(createWebpackConfig(webpackConfig, webpackOptions)),
55
- ];
56
-
57
- if (hasHeadlessBundle()) {
58
- bundles.push(
59
- run(createWebpackConfig(webpackConfig, { ...webpackOptions, headless: true }))
60
- );
61
- }
63
+ return bundleWebComponent({ customConfig, mode, watch, webpackOptions });
64
+ }
62
65
 
63
- return Promise.all(bundles);
66
+ const config =
67
+ customConfig && !emitExposedDependencies
68
+ ? customConfig
69
+ : createWebpackConfig({ configuration: { mode } }, webpackOptions);
70
+
71
+ if (watch) {
72
+ return isDevServerDisabled() ? runWatch(config) : runServe(config);
64
73
  }
65
74
 
66
- return run(config ?? createWebpackConfig({ configuration: { mode } }, webpackOptions));
75
+ return run(config);
67
76
  }
68
77
 
69
- export async function bundleWatch(options: Options = {}) {
70
- log.info('Bundling the package...');
71
-
72
- const name = getName();
73
- const mode = 'development';
74
- const config = readWebpackConfig({ ...options, fallback: `./${webpackDevConfigFileName}` });
75
- const configOverrides = { codeCoverage: options.codeCoverage, name };
78
+ function bundleWebComponent({
79
+ customConfig,
80
+ mode,
81
+ watch,
82
+ webpackOptions,
83
+ }: {
84
+ customConfig: ReturnType<typeof readWebpackConfig>;
85
+ mode: 'development' | 'production';
86
+ watch?: boolean;
87
+ webpackOptions: ReturnType<typeof getWebpackOptions>;
88
+ }) {
89
+ const overrides: Overrides = {
90
+ configuration: { ...customConfig?.configuration, mode },
91
+ plugins: customConfig?.plugins,
92
+ };
93
+
94
+ const fullConfig = createWebpackConfig(overrides, webpackOptions);
95
+ const lightConfig = createWebpackConfig(overrides, { ...webpackOptions, embed: true });
96
+ const headlessConfig = hasHeadlessBundle()
97
+ ? createWebpackConfig(overrides, {
98
+ ...webpackOptions,
99
+ headless: true,
100
+ })
101
+ : undefined;
102
+
103
+ const promises = watch
104
+ ? [
105
+ runWatch(lightConfig),
106
+ isDevServerDisabled() ? runWatch(fullConfig) : runServe(fullConfig),
107
+ headlessConfig && runWatch(headlessConfig),
108
+ ]
109
+ : [run(lightConfig), run(fullConfig), headlessConfig && run(headlessConfig)];
110
+
111
+ return Promise.all(promises.filter(promise => !!promise));
112
+ }
76
113
 
77
- if (isWebComponent()) {
78
- const webpackConfig: Overrides = {
79
- configuration: { ...config?.configuration, mode },
80
- plugins: config?.plugins,
81
- };
82
-
83
- const bundles = [
84
- runWatch(createWebpackConfig(webpackConfig, { embed: true, ...configOverrides })),
85
- isDevServerDisabled()
86
- ? runWatch(createWebpackConfig(webpackConfig, configOverrides))
87
- : runServe(createWebpackConfig(webpackConfig, configOverrides)),
88
- ];
89
-
90
- if (hasHeadlessBundle()) {
91
- bundles.push(
92
- runWatch(createWebpackConfig(webpackConfig, { ...configOverrides, headless: true }))
93
- );
94
- }
114
+ function getWebpackOptions(options: Options, customConfig?: Record<string, any>) {
115
+ const result = {
116
+ name: getName(),
117
+ ...pick(options, ['buildStat', 'codeCoverage', 'emitExposedDependencies']),
118
+ };
95
119
 
96
- return Promise.all(bundles);
120
+ if (result.emitExposedDependencies && customConfig) {
121
+ result.emitExposedDependencies = { output: customConfig.output };
97
122
  }
98
123
 
99
- const webpackConfig =
100
- config ?? createWebpackConfig({ configuration: { mode } }, configOverrides);
101
-
102
- return isDevServerDisabled() ? runWatch(webpackConfig) : runServe(webpackConfig);
124
+ return result;
103
125
  }
104
126
 
105
127
  function readWebpackConfig({ config, fallback }: Options & { fallback: string }) {
@@ -31,7 +31,7 @@ export const runCommand = (
31
31
  }
32
32
 
33
33
  if (!quiet) {
34
- log.info(`run command ${fullCommand}`);
34
+ log.info(`Running: ${fullCommand}`);
35
35
  }
36
36
 
37
37
  const proc = spawn(commandName, commandArray, {
@@ -78,7 +78,7 @@ export const runCommandOutput = (
78
78
  }
79
79
 
80
80
  if (!quiet) {
81
- log.info(`run command ${fullCommand}`);
81
+ log.info(`Running: ${fullCommand}`);
82
82
  }
83
83
 
84
84
  const result = execSync(fullCommand, execSyncOptions).toString();
@@ -277,7 +277,7 @@ describe('[startup] Utils', () => {
277
277
  beforeEach(() => fs.rmSync(configPath));
278
278
 
279
279
  test('logs warning and returns undefined', () => {
280
- const logSpy = jest.spyOn(log, 'warning');
280
+ const logSpy = jest.spyOn(log, 'warning').mockImplementation(jest.fn());
281
281
 
282
282
  expect(subject()).toBeUndefined();
283
283
 
@@ -1,6 +1,7 @@
1
1
  import { globSync } from 'glob';
2
2
  import multimatch from 'multimatch';
3
3
  import path from 'path';
4
+ import { findUp } from './find-up';
4
5
  import { readJsonSafe } from './read-json';
5
6
  import { log } from './log';
6
7
 
@@ -36,8 +37,7 @@ export function findPackages(): ProjectPackage[] {
36
37
  }
37
38
 
38
39
  function findWorkspaces() {
39
- let directory = path.resolve('./');
40
- do {
40
+ return findUp(directory => {
41
41
  const packageJson = path.resolve(path.join(directory, 'package.json'));
42
42
 
43
43
  log.debug('find-packages', `reading: ${packageJson}`);
@@ -61,7 +61,5 @@ function findWorkspaces() {
61
61
  log.debug('find-packages', () => `found workspaces: ${JSON.stringify(workspaces)}`);
62
62
  return workspaces;
63
63
  }
64
-
65
- directory = path.resolve(path.join(directory, '../'));
66
- } while (path.parse(directory).name);
64
+ });
67
65
  }
@@ -0,0 +1,12 @@
1
+ import path from 'path';
2
+
3
+ export function findUp<T>(callback: (directory: string) => T | undefined) {
4
+ let directory = path.resolve('./');
5
+ do {
6
+ const result = callback(directory);
7
+ if (result) {
8
+ return result;
9
+ }
10
+ directory = path.resolve(path.join(directory, '../'));
11
+ } while (path.parse(directory).name);
12
+ }
@@ -77,11 +77,13 @@ export enum CommandName {
77
77
  'styles-check' = 'styles-check',
78
78
  'test' = 'test',
79
79
  'task' = 'task',
80
+ 'upload-sourcemaps' = 'upload-sourcemaps',
80
81
  }
81
82
  /* eslint-enable @typescript-eslint/naming-convention */
82
83
 
83
84
  export interface WebComponentBranchConfigs {
84
85
  publishTag?: string;
86
+ uploadSourcemaps?: boolean;
85
87
  }
86
88
 
87
89
  interface WebComponentOptions {
@@ -1,4 +1,5 @@
1
1
  export * from './find-packages';
2
+ export * from './find-up';
2
3
  export * from './format-duration';
3
4
  export * from './get-configuration';
4
5
  export * from './get-destination-folders';
@@ -6,7 +6,7 @@ export type StyleRule = RuleSetRule & { use: (string | object)[] };
6
6
  export const styleRules: Record<string, StyleRule> = {
7
7
  '.css': {
8
8
  test: /(\.css)$/,
9
- exclude: expect.any(Function),
9
+ exclude: /\.module.css$/,
10
10
  use: ['style-loader', 'css-loader'],
11
11
  },
12
12
  '.scss': {