@servicetitan/startup 32.5.0 → 32.7.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 (47) hide show
  1. package/dist/cli/commands/test/runners/vitest.d.ts.map +1 -1
  2. package/dist/cli/commands/test/runners/vitest.js +13 -1
  3. package/dist/cli/commands/test/runners/vitest.js.map +1 -1
  4. package/dist/jest/resolver.d.ts +4 -0
  5. package/dist/jest/resolver.d.ts.map +1 -0
  6. package/dist/jest/resolver.js +11 -0
  7. package/dist/jest/resolver.js.map +1 -0
  8. package/dist/jest/svg-transformer.d.ts +4 -0
  9. package/dist/jest/svg-transformer.d.ts.map +1 -0
  10. package/dist/jest/svg-transformer.js +26 -0
  11. package/dist/jest/svg-transformer.js.map +1 -0
  12. package/dist/utils/get-jest-config.d.ts.map +1 -1
  13. package/dist/utils/get-jest-config.js +13 -2
  14. package/dist/utils/get-jest-config.js.map +1 -1
  15. package/dist/utils/transform-svg.d.ts +7 -0
  16. package/dist/utils/transform-svg.d.ts.map +1 -0
  17. package/dist/utils/transform-svg.js +62 -0
  18. package/dist/utils/transform-svg.js.map +1 -0
  19. package/dist/vitest/svg-transformer.d.ts +4 -0
  20. package/dist/vitest/svg-transformer.d.ts.map +1 -0
  21. package/dist/vitest/svg-transformer.js +31 -0
  22. package/dist/vitest/svg-transformer.js.map +1 -0
  23. package/dist/webpack/configs/plugins/html-plugin.d.ts.map +1 -1
  24. package/dist/webpack/configs/plugins/html-plugin.js +4 -1
  25. package/dist/webpack/configs/plugins/html-plugin.js.map +1 -1
  26. package/dist/webpack/configs/plugins/mini-css-extract-plugin.d.ts.map +1 -1
  27. package/dist/webpack/configs/plugins/mini-css-extract-plugin.js +4 -10
  28. package/dist/webpack/configs/plugins/mini-css-extract-plugin.js.map +1 -1
  29. package/jest/jest-preset.js +1 -0
  30. package/package.json +21 -6
  31. package/src/cli/commands/test/runners/__tests__/vitest.test.ts +26 -7
  32. package/src/cli/commands/test/runners/vitest.ts +6 -1
  33. package/src/cli/utils/__tests__/copy-files.test.ts +1 -1
  34. package/src/jest/__tests__/resolver.test.ts +41 -0
  35. package/src/jest/__tests__/svg-transformer.test.ts +31 -0
  36. package/src/jest/resolver.ts +9 -0
  37. package/src/jest/svg-transformer.ts +17 -0
  38. package/src/utils/__tests__/get-jest-config.test.ts +36 -3
  39. package/src/utils/__tests__/transform-svg.test.ts +110 -0
  40. package/src/utils/get-jest-config.ts +12 -2
  41. package/src/utils/transform-svg.ts +52 -0
  42. package/src/vitest/__tests__/svg-transformer.test.ts +59 -0
  43. package/src/vitest/svg-transformer.ts +17 -0
  44. package/src/webpack/__tests__/create-webpack-config-shared-dependencies.test.ts +7 -2
  45. package/src/webpack/__tests__/create-webpack-config-web-component.test.ts +14 -2
  46. package/src/webpack/configs/plugins/html-plugin.ts +4 -1
  47. package/src/webpack/configs/plugins/mini-css-extract-plugin.ts +5 -9
@@ -1 +1 @@
1
- {"version":3,"file":"vitest.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/test/runners/vitest.ts"],"names":[],"mappings":"AAMA,qBAAa,MAAM;IACT,GAAG;CAQZ"}
1
+ {"version":3,"file":"vitest.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/test/runners/vitest.ts"],"names":[],"mappings":"AAOA,qBAAa,MAAM;IACT,GAAG;CAQZ"}
@@ -11,6 +11,12 @@ Object.defineProperty(exports, "Vitest", {
11
11
  const _config = require("vitest/config");
12
12
  const _node = require("vitest/node");
13
13
  const _utils = require("../../../../utils");
14
+ const _svgtransformer = /*#__PURE__*/ _interop_require_default(require("../../../../vitest/svg-transformer"));
15
+ function _interop_require_default(obj) {
16
+ return obj && obj.__esModule ? obj : {
17
+ default: obj
18
+ };
19
+ }
14
20
  class Vitest {
15
21
  async run() {
16
22
  const cliOptions = getCliOptions();
@@ -79,8 +85,14 @@ async function getUserConfig() {
79
85
  var _viteConfig_test;
80
86
  const result = (0, _config.mergeConfig)((0, _config.mergeConfig)((0, _utils.omit)(getDefaultConfig(), omitDefault), config), (_viteConfig_test = viteConfig.test) !== null && _viteConfig_test !== void 0 ? _viteConfig_test : {});
81
87
  /* istanbul ignore next: debug only */ _utils.log.debug('vitest:userConfig', ()=>JSON.stringify(result, null, 2));
88
+ const plugins = [
89
+ (0, _svgtransformer.default)()
90
+ ].filter(({ name })=>!omitDefault.includes(`plugins.${name}`));
82
91
  return {
83
- test: result
92
+ test: result,
93
+ ...plugins.length ? {
94
+ plugins
95
+ } : {}
84
96
  };
85
97
  }
86
98
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/cli/commands/test/runners/vitest.ts"],"sourcesContent":["import { configDefaults, coverageConfigDefaults, mergeConfig, ViteUserConfig } from 'vitest/config';\nimport { startVitest, parseCLI, resolveConfig } from 'vitest/node';\nimport { getVitestConfiguration, log, omit } from '../../../../utils';\n\ntype VitestConfig = NonNullable<ViteUserConfig['test']>;\n\nexport class Vitest {\n async run() {\n const cliOptions = getCliOptions();\n const userConfig = await getUserConfig();\n\n // startVitest sets process.exitCode to 1 when tests fail\n const vitest = await startVitest('test', cliOptions.filter, cliOptions.options, userConfig);\n await vitest.close();\n }\n}\n\nconst RUNNER_OPTION = '--runner';\n\nfunction excludeRunnerOption(args: string[]) {\n return args.reduce<string[]>((result, item, index) => {\n if (!item.startsWith(RUNNER_OPTION) && (index === 0 || args[index - 1] !== RUNNER_OPTION)) {\n result.push(item);\n }\n return result;\n }, []);\n}\n\nfunction getCliOptions() {\n // parseCLI requires the first element to be \"vitest\"\n const result = parseCLI(['vitest', ...excludeRunnerOption(process.argv.slice(3))]);\n\n /* istanbul ignore next: debug only */\n log.debug('vitest:cliOptions', () => JSON.stringify(result, null, 2));\n\n return result;\n}\n\nfunction getDefaultConfig(): VitestConfig {\n return {\n coverage: {\n exclude: [\n ...coverageConfigDefaults.exclude,\n '**/__mocks__/**',\n '**/*.stories.*',\n '\\\\.yalc',\n ],\n include: ['**/*.{ts,tsx}'],\n reporter: ['html-spa', 'text', 'json', 'cobertura', 'lcov'],\n },\n environment: 'jsdom',\n exclude: [...configDefaults.exclude, '\\\\.yalc'],\n restoreMocks: true,\n server: { deps: { inline: ['@servicetitan/anvil2'] } }, // fixes css parser errors\n };\n}\n\nasync function getUserConfig(): Promise<ViteUserConfig> {\n const { viteConfig } = await resolveConfig();\n\n const { omitDefault = [], ...config } = getVitestConfiguration();\n\n const result = mergeConfig(\n mergeConfig(omit(getDefaultConfig(), omitDefault), config),\n viteConfig.test ?? {}\n );\n\n /* istanbul ignore next: debug only */\n log.debug('vitest:userConfig', () => JSON.stringify(result, null, 2));\n\n return { test: result };\n}\n"],"names":["Vitest","run","cliOptions","getCliOptions","userConfig","getUserConfig","vitest","startVitest","filter","options","close","RUNNER_OPTION","excludeRunnerOption","args","reduce","result","item","index","startsWith","push","parseCLI","process","argv","slice","log","debug","JSON","stringify","getDefaultConfig","coverage","exclude","coverageConfigDefaults","include","reporter","environment","configDefaults","restoreMocks","server","deps","inline","viteConfig","resolveConfig","omitDefault","config","getVitestConfiguration","mergeConfig","omit","test"],"mappings":";;;;+BAMaA;;;eAAAA;;;wBANuE;sBAC/B;uBACH;AAI3C,MAAMA;IACT,MAAMC,MAAM;QACR,MAAMC,aAAaC;QACnB,MAAMC,aAAa,MAAMC;QAEzB,yDAAyD;QACzD,MAAMC,SAAS,MAAMC,IAAAA,iBAAW,EAAC,QAAQL,WAAWM,MAAM,EAAEN,WAAWO,OAAO,EAAEL;QAChF,MAAME,OAAOI,KAAK;IACtB;AACJ;AAEA,MAAMC,gBAAgB;AAEtB,SAASC,oBAAoBC,IAAc;IACvC,OAAOA,KAAKC,MAAM,CAAW,CAACC,QAAQC,MAAMC;QACxC,IAAI,CAACD,KAAKE,UAAU,CAACP,kBAAmBM,CAAAA,UAAU,KAAKJ,IAAI,CAACI,QAAQ,EAAE,KAAKN,aAAY,GAAI;YACvFI,OAAOI,IAAI,CAACH;QAChB;QACA,OAAOD;IACX,GAAG,EAAE;AACT;AAEA,SAASZ;IACL,qDAAqD;IACrD,MAAMY,SAASK,IAAAA,cAAQ,EAAC;QAAC;WAAaR,oBAAoBS,QAAQC,IAAI,CAACC,KAAK,CAAC;KAAI;IAEjF,oCAAoC,GACpCC,UAAG,CAACC,KAAK,CAAC,qBAAqB,IAAMC,KAAKC,SAAS,CAACZ,QAAQ,MAAM;IAElE,OAAOA;AACX;AAEA,SAASa;IACL,OAAO;QACHC,UAAU;YACNC,SAAS;mBACFC,8BAAsB,CAACD,OAAO;gBACjC;gBACA;gBACA;aACH;YACDE,SAAS;gBAAC;aAAgB;YAC1BC,UAAU;gBAAC;gBAAY;gBAAQ;gBAAQ;gBAAa;aAAO;QAC/D;QACAC,aAAa;QACbJ,SAAS;eAAIK,sBAAc,CAACL,OAAO;YAAE;SAAU;QAC/CM,cAAc;QACdC,QAAQ;YAAEC,MAAM;gBAAEC,QAAQ;oBAAC;iBAAuB;YAAC;QAAE;IACzD;AACJ;AAEA,eAAelC;IACX,MAAM,EAAEmC,UAAU,EAAE,GAAG,MAAMC,IAAAA,mBAAa;IAE1C,MAAM,EAAEC,cAAc,EAAE,EAAE,GAAGC,QAAQ,GAAGC,IAAAA,6BAAsB;QAI1DJ;IAFJ,MAAMzB,SAAS8B,IAAAA,mBAAW,EACtBA,IAAAA,mBAAW,EAACC,IAAAA,WAAI,EAAClB,oBAAoBc,cAAcC,SACnDH,CAAAA,mBAAAA,WAAWO,IAAI,cAAfP,8BAAAA,mBAAmB,CAAC;IAGxB,oCAAoC,GACpChB,UAAG,CAACC,KAAK,CAAC,qBAAqB,IAAMC,KAAKC,SAAS,CAACZ,QAAQ,MAAM;IAElE,OAAO;QAAEgC,MAAMhC;IAAO;AAC1B"}
1
+ {"version":3,"sources":["../../../../../src/cli/commands/test/runners/vitest.ts"],"sourcesContent":["import { configDefaults, coverageConfigDefaults, mergeConfig, ViteUserConfig } from 'vitest/config';\nimport { startVitest, parseCLI, resolveConfig } from 'vitest/node';\nimport { getVitestConfiguration, log, omit } from '../../../../utils';\nimport svgTransformer from '../../../../vitest/svg-transformer';\n\ntype VitestConfig = NonNullable<ViteUserConfig['test']>;\n\nexport class Vitest {\n async run() {\n const cliOptions = getCliOptions();\n const userConfig = await getUserConfig();\n\n // startVitest sets process.exitCode to 1 when tests fail\n const vitest = await startVitest('test', cliOptions.filter, cliOptions.options, userConfig);\n await vitest.close();\n }\n}\n\nconst RUNNER_OPTION = '--runner';\n\nfunction excludeRunnerOption(args: string[]) {\n return args.reduce<string[]>((result, item, index) => {\n if (!item.startsWith(RUNNER_OPTION) && (index === 0 || args[index - 1] !== RUNNER_OPTION)) {\n result.push(item);\n }\n return result;\n }, []);\n}\n\nfunction getCliOptions() {\n // parseCLI requires the first element to be \"vitest\"\n const result = parseCLI(['vitest', ...excludeRunnerOption(process.argv.slice(3))]);\n\n /* istanbul ignore next: debug only */\n log.debug('vitest:cliOptions', () => JSON.stringify(result, null, 2));\n\n return result;\n}\n\nfunction getDefaultConfig(): VitestConfig {\n return {\n coverage: {\n exclude: [\n ...coverageConfigDefaults.exclude,\n '**/__mocks__/**',\n '**/*.stories.*',\n '\\\\.yalc',\n ],\n include: ['**/*.{ts,tsx}'],\n reporter: ['html-spa', 'text', 'json', 'cobertura', 'lcov'],\n },\n environment: 'jsdom',\n exclude: [...configDefaults.exclude, '\\\\.yalc'],\n restoreMocks: true,\n server: { deps: { inline: ['@servicetitan/anvil2'] } }, // fixes css parser errors\n };\n}\n\nasync function getUserConfig(): Promise<ViteUserConfig> {\n const { viteConfig } = await resolveConfig();\n\n const { omitDefault = [], ...config } = getVitestConfiguration();\n\n const result = mergeConfig(\n mergeConfig(omit(getDefaultConfig(), omitDefault), config),\n viteConfig.test ?? {}\n );\n\n /* istanbul ignore next: debug only */\n log.debug('vitest:userConfig', () => JSON.stringify(result, null, 2));\n\n const plugins: NonNullable<ViteUserConfig['plugins']> = [svgTransformer()].filter(\n ({ name }) => !omitDefault.includes(`plugins.${name}`)\n );\n\n return { test: result, ...(plugins.length ? { plugins } : {}) };\n}\n"],"names":["Vitest","run","cliOptions","getCliOptions","userConfig","getUserConfig","vitest","startVitest","filter","options","close","RUNNER_OPTION","excludeRunnerOption","args","reduce","result","item","index","startsWith","push","parseCLI","process","argv","slice","log","debug","JSON","stringify","getDefaultConfig","coverage","exclude","coverageConfigDefaults","include","reporter","environment","configDefaults","restoreMocks","server","deps","inline","viteConfig","resolveConfig","omitDefault","config","getVitestConfiguration","mergeConfig","omit","test","plugins","svgTransformer","name","includes","length"],"mappings":";;;;+BAOaA;;;eAAAA;;;wBAPuE;sBAC/B;uBACH;uEACvB;;;;;;AAIpB,MAAMA;IACT,MAAMC,MAAM;QACR,MAAMC,aAAaC;QACnB,MAAMC,aAAa,MAAMC;QAEzB,yDAAyD;QACzD,MAAMC,SAAS,MAAMC,IAAAA,iBAAW,EAAC,QAAQL,WAAWM,MAAM,EAAEN,WAAWO,OAAO,EAAEL;QAChF,MAAME,OAAOI,KAAK;IACtB;AACJ;AAEA,MAAMC,gBAAgB;AAEtB,SAASC,oBAAoBC,IAAc;IACvC,OAAOA,KAAKC,MAAM,CAAW,CAACC,QAAQC,MAAMC;QACxC,IAAI,CAACD,KAAKE,UAAU,CAACP,kBAAmBM,CAAAA,UAAU,KAAKJ,IAAI,CAACI,QAAQ,EAAE,KAAKN,aAAY,GAAI;YACvFI,OAAOI,IAAI,CAACH;QAChB;QACA,OAAOD;IACX,GAAG,EAAE;AACT;AAEA,SAASZ;IACL,qDAAqD;IACrD,MAAMY,SAASK,IAAAA,cAAQ,EAAC;QAAC;WAAaR,oBAAoBS,QAAQC,IAAI,CAACC,KAAK,CAAC;KAAI;IAEjF,oCAAoC,GACpCC,UAAG,CAACC,KAAK,CAAC,qBAAqB,IAAMC,KAAKC,SAAS,CAACZ,QAAQ,MAAM;IAElE,OAAOA;AACX;AAEA,SAASa;IACL,OAAO;QACHC,UAAU;YACNC,SAAS;mBACFC,8BAAsB,CAACD,OAAO;gBACjC;gBACA;gBACA;aACH;YACDE,SAAS;gBAAC;aAAgB;YAC1BC,UAAU;gBAAC;gBAAY;gBAAQ;gBAAQ;gBAAa;aAAO;QAC/D;QACAC,aAAa;QACbJ,SAAS;eAAIK,sBAAc,CAACL,OAAO;YAAE;SAAU;QAC/CM,cAAc;QACdC,QAAQ;YAAEC,MAAM;gBAAEC,QAAQ;oBAAC;iBAAuB;YAAC;QAAE;IACzD;AACJ;AAEA,eAAelC;IACX,MAAM,EAAEmC,UAAU,EAAE,GAAG,MAAMC,IAAAA,mBAAa;IAE1C,MAAM,EAAEC,cAAc,EAAE,EAAE,GAAGC,QAAQ,GAAGC,IAAAA,6BAAsB;QAI1DJ;IAFJ,MAAMzB,SAAS8B,IAAAA,mBAAW,EACtBA,IAAAA,mBAAW,EAACC,IAAAA,WAAI,EAAClB,oBAAoBc,cAAcC,SACnDH,CAAAA,mBAAAA,WAAWO,IAAI,cAAfP,8BAAAA,mBAAmB,CAAC;IAGxB,oCAAoC,GACpChB,UAAG,CAACC,KAAK,CAAC,qBAAqB,IAAMC,KAAKC,SAAS,CAACZ,QAAQ,MAAM;IAElE,MAAMiC,UAAkD;QAACC,IAAAA,uBAAc;KAAG,CAACzC,MAAM,CAC7E,CAAC,EAAE0C,IAAI,EAAE,GAAK,CAACR,YAAYS,QAAQ,CAAC,CAAC,QAAQ,EAAED,MAAM;IAGzD,OAAO;QAAEH,MAAMhC;QAAQ,GAAIiC,QAAQI,MAAM,GAAG;YAAEJ;QAAQ,IAAI,CAAC,CAAC;IAAE;AAClE"}
@@ -0,0 +1,4 @@
1
+ import type { SyncResolver } from 'jest-resolve';
2
+ declare const resolver: SyncResolver;
3
+ export = resolver;
4
+ //# sourceMappingURL=resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/jest/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAGjD,QAAA,MAAM,QAAQ,EAAE,YAGf,CAAC;AAEF,SAAS,QAAQ,CAAC"}
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ const _transformsvg = require("../utils/transform-svg");
3
+ const resolver = (path, options)=>{
4
+ var _SVG_PATH_REGEX_exec;
5
+ var _SVG_PATH_REGEX_exec_groups;
6
+ const { type, path: pathSansType } = (_SVG_PATH_REGEX_exec_groups = (_SVG_PATH_REGEX_exec = _transformsvg.SVG_PATH_REGEX.exec(path)) === null || _SVG_PATH_REGEX_exec === void 0 ? void 0 : _SVG_PATH_REGEX_exec.groups) !== null && _SVG_PATH_REGEX_exec_groups !== void 0 ? _SVG_PATH_REGEX_exec_groups : {};
7
+ return options.defaultResolver(type ? pathSansType : path, options);
8
+ };
9
+ module.exports = resolver;
10
+
11
+ //# sourceMappingURL=resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/jest/resolver.ts"],"sourcesContent":["import type { SyncResolver } from 'jest-resolve';\nimport { SVG_PATH_REGEX } from '../utils/transform-svg';\n\nconst resolver: SyncResolver = (path, options) => {\n const { type, path: pathSansType } = SVG_PATH_REGEX.exec(path)?.groups ?? {};\n return options.defaultResolver(type ? pathSansType : path, options);\n};\n\nexport = resolver;\n"],"names":["resolver","path","options","SVG_PATH_REGEX","type","pathSansType","exec","groups","defaultResolver"],"mappings":";8BAC+B;AAE/B,MAAMA,WAAyB,CAACC,MAAMC;QACGC;QAAAA;IAArC,MAAM,EAAEC,IAAI,EAAEH,MAAMI,YAAY,EAAE,GAAGF,CAAAA,+BAAAA,uBAAAA,4BAAc,CAACG,IAAI,CAACL,mBAApBE,2CAAAA,qBAA2BI,MAAM,cAAjCJ,yCAAAA,8BAAqC,CAAC;IAC3E,OAAOD,QAAQM,eAAe,CAACJ,OAAOC,eAAeJ,MAAMC;AAC/D;iBAESF"}
@@ -0,0 +1,4 @@
1
+ import type { Transformer } from '@jest/transform';
2
+ declare const svgTransformer: Transformer;
3
+ export default svgTransformer;
4
+ //# sourceMappingURL=svg-transformer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"svg-transformer.d.ts","sourceRoot":"","sources":["../../src/jest/svg-transformer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAInD,QAAA,MAAM,cAAc,EAAE,WASrB,CAAC;AAGF,eAAe,cAAc,CAAC"}
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, // eslint-disable-next-line import/no-default-export
6
+ "default", {
7
+ enumerable: true,
8
+ get: function() {
9
+ return _default;
10
+ }
11
+ });
12
+ const _transformsvg = require("../utils/transform-svg");
13
+ const svgTransformer = {
14
+ process (_sourceText, sourcePath) {
15
+ /*
16
+ * Because Jest discards the query param and caches only one transformation,
17
+ * we can't detect or rely on how the SVG was requested. So, render all SVGs
18
+ * as component and rely on its toString() to render the "asset" version.
19
+ */ return {
20
+ code: (0, _transformsvg.transformSVG)(`${sourcePath}?component`)
21
+ };
22
+ }
23
+ };
24
+ const _default = svgTransformer;
25
+
26
+ //# sourceMappingURL=svg-transformer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/jest/svg-transformer.ts"],"sourcesContent":["import type { Transformer } from '@jest/transform';\n\nimport { transformSVG } from '../utils/transform-svg';\n\nconst svgTransformer: Transformer = {\n process(_sourceText, sourcePath) {\n /*\n * Because Jest discards the query param and caches only one transformation,\n * we can't detect or rely on how the SVG was requested. So, render all SVGs\n * as component and rely on its toString() to render the \"asset\" version.\n */\n return { code: transformSVG(`${sourcePath}?component`) };\n },\n};\n\n// eslint-disable-next-line import/no-default-export\nexport default svgTransformer;\n"],"names":["svgTransformer","process","_sourceText","sourcePath","code","transformSVG"],"mappings":";;;;+BAeA,oDAAoD;AACpD;;;eAAA;;;8BAd6B;AAE7B,MAAMA,iBAA8B;IAChCC,SAAQC,WAAW,EAAEC,UAAU;QAC3B;;;;SAIC,GACD,OAAO;YAAEC,MAAMC,IAAAA,0BAAY,EAAC,GAAGF,WAAW,UAAU,CAAC;QAAE;IAC3D;AACJ;MAGA,WAAeH"}
@@ -1 +1 @@
1
- {"version":3,"file":"get-jest-config.d.ts","sourceRoot":"","sources":["../../src/utils/get-jest-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAiCrC;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAsB/D"}
1
+ {"version":3,"file":"get-jest-config.d.ts","sourceRoot":"","sources":["../../src/utils/get-jest-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAiCrC;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAgC/D"}
@@ -20,7 +20,7 @@ function _interop_require_default(obj) {
20
20
  }
21
21
  function getDefaultJestConfiguration() {
22
22
  const moduleNameMapper = {
23
- '\\.(css|scss|less|png|svg|svg\\?\\w+|jpg|jpeg|gif|woff|woff2|eot|ttf|otf)$': 'identity-obj-proxy'
23
+ '\\.(css|scss|less|png|jpg|jpeg|gif|woff|woff2|eot|ttf|otf)$': 'identity-obj-proxy'
24
24
  };
25
25
  return {
26
26
  collectCoverageFrom: [
@@ -41,6 +41,7 @@ function getDefaultJestConfiguration() {
41
41
  '<rootDir>/.*/__mocks__'
42
42
  ],
43
43
  preset: _path.default.join(__dirname, '../../jest'),
44
+ resolver: '@servicetitan/startup/jest-resolver',
44
45
  setupFiles: [
45
46
  _path.default.join(__dirname, '../../jest/setup.js')
46
47
  ],
@@ -62,13 +63,23 @@ function getJestConfigCLI(args) {
62
63
  ...args
63
64
  };
64
65
  const defaultConfig = (0, _omit.omit)(getDefaultJestConfiguration(), omitDefault);
66
+ let moduleNameMapper = typeof config.moduleNameMapper === 'string' ? JSON.parse(config.moduleNameMapper) : config.moduleNameMapper;
67
+ if (defaultConfig.moduleNameMapper) {
68
+ moduleNameMapper = {
69
+ ...moduleNameMapper,
70
+ ...defaultConfig.moduleNameMapper
71
+ };
72
+ }
65
73
  return stringifyForCLI({
66
74
  ...mergeArrayValues(defaultConfig, {
67
75
  coveragePathIgnorePatterns,
68
76
  setupFiles,
69
77
  testPathIgnorePatterns
70
78
  }),
71
- ...config
79
+ ...config,
80
+ ...moduleNameMapper ? {
81
+ moduleNameMapper
82
+ } : {}
72
83
  });
73
84
  }
74
85
  function mergeArrayValues(config, arrayValues) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/get-jest-config.ts"],"sourcesContent":["import { Config } from '@jest/types';\nimport path from 'path';\nimport { getJestConfiguration } from './get-configuration';\nimport { getDestinationFolders } from './get-destination-folders';\nimport { toArray } from './to-array';\nimport { omit } from './omit';\n\nfunction getDefaultJestConfiguration() {\n const moduleNameMapper = {\n '\\\\.(css|scss|less|png|svg|svg\\\\?\\\\w+|jpg|jpeg|gif|woff|woff2|eot|ttf|otf)$':\n 'identity-obj-proxy',\n };\n\n return {\n collectCoverageFrom: ['**/*.{ts,tsx}'],\n coveragePathIgnorePatterns: ['^.+\\\\.d\\\\.ts$'],\n coverageReporters: ['html-spa', 'text', 'json', 'cobertura', 'lcov'],\n moduleNameMapper,\n modulePathIgnorePatterns: ['<rootDir>/.*/__mocks__'],\n preset: path.join(__dirname, '../../jest'),\n setupFiles: [path.join(__dirname, '../../jest/setup.js')],\n testEnvironment: 'jsdom',\n testPathIgnorePatterns: ['\\\\.yalc', ...getDestinationFolders()],\n testRunner: 'jest-circus/runner',\n transformIgnorePatterns: ['node_modules/(?!(@servicetitan|@react-hook|nanoid|axios)/)'],\n verbose: true,\n } as Omit<Config.Argv, 'collectCoverageFrom' | 'moduleNameMapper' | 'setupFiles'> & {\n collectCoverageFrom: string[];\n moduleNameMapper: Record<string, string>;\n setupFiles: string[];\n };\n}\n\n/**\n * Get Jest config for running it using jest CLI (see jest runCLI function)\n */\nexport function getJestConfigCLI(args: Config.Argv): Config.Argv {\n const {\n coveragePathIgnorePatterns,\n omitDefault = [],\n setupFiles,\n testPathIgnorePatterns,\n ...config\n } = {\n ...getJestConfiguration(),\n ...args,\n };\n\n const defaultConfig = omit(getDefaultJestConfiguration(), omitDefault);\n\n return stringifyForCLI({\n ...mergeArrayValues(defaultConfig, {\n coveragePathIgnorePatterns,\n setupFiles,\n testPathIgnorePatterns,\n }),\n ...config,\n });\n}\n\nfunction mergeArrayValues(\n config: any,\n arrayValues: {\n coveragePathIgnorePatterns?: string | string[];\n setupFiles?: string | string[];\n testPathIgnorePatterns?: string | string[];\n }\n) {\n return Object.keys(arrayValues).reduce((result, key: keyof typeof arrayValues) => {\n const newValue = arrayValues[key];\n if (newValue) {\n result[key] = [...toArray(result[key]), ...toArray(newValue)];\n }\n return result;\n }, config);\n}\n\nfunction stringifyForCLI(config: any): Config.Argv {\n return ['collectCoverageFrom', 'globals', 'moduleNameMapper', 'transform'].reduce(\n (result, key) => {\n const value = result[key];\n if (value && typeof value !== 'string') {\n result[key] = JSON.stringify(result[key]);\n }\n return result;\n },\n config\n );\n}\n"],"names":["getJestConfigCLI","getDefaultJestConfiguration","moduleNameMapper","collectCoverageFrom","coveragePathIgnorePatterns","coverageReporters","modulePathIgnorePatterns","preset","path","join","__dirname","setupFiles","testEnvironment","testPathIgnorePatterns","getDestinationFolders","testRunner","transformIgnorePatterns","verbose","args","omitDefault","config","getJestConfiguration","defaultConfig","omit","stringifyForCLI","mergeArrayValues","arrayValues","Object","keys","reduce","result","key","newValue","toArray","value","JSON","stringify"],"mappings":";;;;+BAoCgBA;;;eAAAA;;;6DAnCC;kCACoB;uCACC;yBACd;sBACH;;;;;;AAErB,SAASC;IACL,MAAMC,mBAAmB;QACrB,8EACI;IACR;IAEA,OAAO;QACHC,qBAAqB;YAAC;SAAgB;QACtCC,4BAA4B;YAAC;SAAgB;QAC7CC,mBAAmB;YAAC;YAAY;YAAQ;YAAQ;YAAa;SAAO;QACpEH;QACAI,0BAA0B;YAAC;SAAyB;QACpDC,QAAQC,aAAI,CAACC,IAAI,CAACC,WAAW;QAC7BC,YAAY;YAACH,aAAI,CAACC,IAAI,CAACC,WAAW;SAAuB;QACzDE,iBAAiB;QACjBC,wBAAwB;YAAC;eAAcC,IAAAA,4CAAqB;SAAG;QAC/DC,YAAY;QACZC,yBAAyB;YAAC;SAA6D;QACvFC,SAAS;IACb;AAKJ;AAKO,SAASjB,iBAAiBkB,IAAiB;IAC9C,MAAM,EACFd,0BAA0B,EAC1Be,cAAc,EAAE,EAChBR,UAAU,EACVE,sBAAsB,EACtB,GAAGO,QACN,GAAG;QACA,GAAGC,IAAAA,sCAAoB,GAAE;QACzB,GAAGH,IAAI;IACX;IAEA,MAAMI,gBAAgBC,IAAAA,UAAI,EAACtB,+BAA+BkB;IAE1D,OAAOK,gBAAgB;QACnB,GAAGC,iBAAiBH,eAAe;YAC/BlB;YACAO;YACAE;QACJ,EAAE;QACF,GAAGO,MAAM;IACb;AACJ;AAEA,SAASK,iBACLL,MAAW,EACXM,WAIC;IAED,OAAOC,OAAOC,IAAI,CAACF,aAAaG,MAAM,CAAC,CAACC,QAAQC;QAC5C,MAAMC,WAAWN,WAAW,CAACK,IAAI;QACjC,IAAIC,UAAU;YACVF,MAAM,CAACC,IAAI,GAAG;mBAAIE,IAAAA,gBAAO,EAACH,MAAM,CAACC,IAAI;mBAAME,IAAAA,gBAAO,EAACD;aAAU;QACjE;QACA,OAAOF;IACX,GAAGV;AACP;AAEA,SAASI,gBAAgBJ,MAAW;IAChC,OAAO;QAAC;QAAuB;QAAW;QAAoB;KAAY,CAACS,MAAM,CAC7E,CAACC,QAAQC;QACL,MAAMG,QAAQJ,MAAM,CAACC,IAAI;QACzB,IAAIG,SAAS,OAAOA,UAAU,UAAU;YACpCJ,MAAM,CAACC,IAAI,GAAGI,KAAKC,SAAS,CAACN,MAAM,CAACC,IAAI;QAC5C;QACA,OAAOD;IACX,GACAV;AAER"}
1
+ {"version":3,"sources":["../../src/utils/get-jest-config.ts"],"sourcesContent":["import { Config } from '@jest/types';\nimport path from 'path';\nimport { getJestConfiguration } from './get-configuration';\nimport { getDestinationFolders } from './get-destination-folders';\nimport { toArray } from './to-array';\nimport { omit } from './omit';\n\nfunction getDefaultJestConfiguration() {\n const moduleNameMapper = {\n '\\\\.(css|scss|less|png|jpg|jpeg|gif|woff|woff2|eot|ttf|otf)$': 'identity-obj-proxy',\n };\n\n return {\n collectCoverageFrom: ['**/*.{ts,tsx}'],\n coveragePathIgnorePatterns: ['^.+\\\\.d\\\\.ts$'],\n coverageReporters: ['html-spa', 'text', 'json', 'cobertura', 'lcov'],\n moduleNameMapper,\n modulePathIgnorePatterns: ['<rootDir>/.*/__mocks__'],\n preset: path.join(__dirname, '../../jest'),\n resolver: '@servicetitan/startup/jest-resolver',\n setupFiles: [path.join(__dirname, '../../jest/setup.js')],\n testEnvironment: 'jsdom',\n testPathIgnorePatterns: ['\\\\.yalc', ...getDestinationFolders()],\n testRunner: 'jest-circus/runner',\n transformIgnorePatterns: ['node_modules/(?!(@servicetitan|@react-hook|nanoid|axios)/)'],\n verbose: true,\n } as Omit<Config.Argv, 'collectCoverageFrom' | 'moduleNameMapper' | 'setupFiles'> & {\n collectCoverageFrom: string[];\n moduleNameMapper: Record<string, string>;\n setupFiles: string[];\n };\n}\n\n/**\n * Get Jest config for running it using jest CLI (see jest runCLI function)\n */\nexport function getJestConfigCLI(args: Config.Argv): Config.Argv {\n const {\n coveragePathIgnorePatterns,\n omitDefault = [],\n setupFiles,\n testPathIgnorePatterns,\n ...config\n } = {\n ...getJestConfiguration(),\n ...args,\n };\n\n const defaultConfig = omit(getDefaultJestConfiguration(), omitDefault);\n\n let moduleNameMapper: Record<string, string> | undefined =\n typeof config.moduleNameMapper === 'string'\n ? JSON.parse(config.moduleNameMapper)\n : config.moduleNameMapper;\n\n if (defaultConfig.moduleNameMapper) {\n moduleNameMapper = { ...moduleNameMapper, ...defaultConfig.moduleNameMapper };\n }\n\n return stringifyForCLI({\n ...mergeArrayValues(defaultConfig, {\n coveragePathIgnorePatterns,\n setupFiles,\n testPathIgnorePatterns,\n }),\n ...config,\n ...(moduleNameMapper ? { moduleNameMapper } : {}),\n });\n}\n\nfunction mergeArrayValues(\n config: any,\n arrayValues: {\n coveragePathIgnorePatterns?: string | string[];\n setupFiles?: string | string[];\n testPathIgnorePatterns?: string | string[];\n }\n) {\n return Object.keys(arrayValues).reduce((result, key: keyof typeof arrayValues) => {\n const newValue = arrayValues[key];\n if (newValue) {\n result[key] = [...toArray(result[key]), ...toArray(newValue)];\n }\n return result;\n }, config);\n}\n\nfunction stringifyForCLI(config: any): Config.Argv {\n return ['collectCoverageFrom', 'globals', 'moduleNameMapper', 'transform'].reduce(\n (result, key) => {\n const value = result[key];\n if (value && typeof value !== 'string') {\n result[key] = JSON.stringify(result[key]);\n }\n return result;\n },\n config\n );\n}\n"],"names":["getJestConfigCLI","getDefaultJestConfiguration","moduleNameMapper","collectCoverageFrom","coveragePathIgnorePatterns","coverageReporters","modulePathIgnorePatterns","preset","path","join","__dirname","resolver","setupFiles","testEnvironment","testPathIgnorePatterns","getDestinationFolders","testRunner","transformIgnorePatterns","verbose","args","omitDefault","config","getJestConfiguration","defaultConfig","omit","JSON","parse","stringifyForCLI","mergeArrayValues","arrayValues","Object","keys","reduce","result","key","newValue","toArray","value","stringify"],"mappings":";;;;+BAoCgBA;;;eAAAA;;;6DAnCC;kCACoB;uCACC;yBACd;sBACH;;;;;;AAErB,SAASC;IACL,MAAMC,mBAAmB;QACrB,+DAA+D;IACnE;IAEA,OAAO;QACHC,qBAAqB;YAAC;SAAgB;QACtCC,4BAA4B;YAAC;SAAgB;QAC7CC,mBAAmB;YAAC;YAAY;YAAQ;YAAQ;YAAa;SAAO;QACpEH;QACAI,0BAA0B;YAAC;SAAyB;QACpDC,QAAQC,aAAI,CAACC,IAAI,CAACC,WAAW;QAC7BC,UAAU;QACVC,YAAY;YAACJ,aAAI,CAACC,IAAI,CAACC,WAAW;SAAuB;QACzDG,iBAAiB;QACjBC,wBAAwB;YAAC;eAAcC,IAAAA,4CAAqB;SAAG;QAC/DC,YAAY;QACZC,yBAAyB;YAAC;SAA6D;QACvFC,SAAS;IACb;AAKJ;AAKO,SAASlB,iBAAiBmB,IAAiB;IAC9C,MAAM,EACFf,0BAA0B,EAC1BgB,cAAc,EAAE,EAChBR,UAAU,EACVE,sBAAsB,EACtB,GAAGO,QACN,GAAG;QACA,GAAGC,IAAAA,sCAAoB,GAAE;QACzB,GAAGH,IAAI;IACX;IAEA,MAAMI,gBAAgBC,IAAAA,UAAI,EAACvB,+BAA+BmB;IAE1D,IAAIlB,mBACA,OAAOmB,OAAOnB,gBAAgB,KAAK,WAC7BuB,KAAKC,KAAK,CAACL,OAAOnB,gBAAgB,IAClCmB,OAAOnB,gBAAgB;IAEjC,IAAIqB,cAAcrB,gBAAgB,EAAE;QAChCA,mBAAmB;YAAE,GAAGA,gBAAgB;YAAE,GAAGqB,cAAcrB,gBAAgB;QAAC;IAChF;IAEA,OAAOyB,gBAAgB;QACnB,GAAGC,iBAAiBL,eAAe;YAC/BnB;YACAQ;YACAE;QACJ,EAAE;QACF,GAAGO,MAAM;QACT,GAAInB,mBAAmB;YAAEA;QAAiB,IAAI,CAAC,CAAC;IACpD;AACJ;AAEA,SAAS0B,iBACLP,MAAW,EACXQ,WAIC;IAED,OAAOC,OAAOC,IAAI,CAACF,aAAaG,MAAM,CAAC,CAACC,QAAQC;QAC5C,MAAMC,WAAWN,WAAW,CAACK,IAAI;QACjC,IAAIC,UAAU;YACVF,MAAM,CAACC,IAAI,GAAG;mBAAIE,IAAAA,gBAAO,EAACH,MAAM,CAACC,IAAI;mBAAME,IAAAA,gBAAO,EAACD;aAAU;QACjE;QACA,OAAOF;IACX,GAAGZ;AACP;AAEA,SAASM,gBAAgBN,MAAW;IAChC,OAAO;QAAC;QAAuB;QAAW;QAAoB;KAAY,CAACW,MAAM,CAC7E,CAACC,QAAQC;QACL,MAAMG,QAAQJ,MAAM,CAACC,IAAI;QACzB,IAAIG,SAAS,OAAOA,UAAU,UAAU;YACpCJ,MAAM,CAACC,IAAI,GAAGT,KAAKa,SAAS,CAACL,MAAM,CAACC,IAAI;QAC5C;QACA,OAAOD;IACX,GACAZ;AAER"}
@@ -0,0 +1,7 @@
1
+ export declare const SVG_PATH_REGEX: RegExp;
2
+ interface TransformOptions {
3
+ esm?: boolean;
4
+ }
5
+ export declare function transformSVG(sourcePath: string, options?: TransformOptions): string;
6
+ export {};
7
+ //# sourceMappingURL=transform-svg.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transform-svg.d.ts","sourceRoot":"","sources":["../../src/utils/transform-svg.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,cAAc,QAAgD,CAAC;AAE5E,UAAU,gBAAgB;IACtB,GAAG,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,UAO9E"}
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: Object.getOwnPropertyDescriptor(all, name).get
9
+ });
10
+ }
11
+ _export(exports, {
12
+ get SVG_PATH_REGEX () {
13
+ return SVG_PATH_REGEX;
14
+ },
15
+ get transformSVG () {
16
+ return transformSVG;
17
+ }
18
+ });
19
+ const _path = /*#__PURE__*/ _interop_require_default(require("path"));
20
+ function _interop_require_default(obj) {
21
+ return obj && obj.__esModule ? obj : {
22
+ default: obj
23
+ };
24
+ }
25
+ const SVG_PATH_REGEX = RegExp(/^(?<path>.+\.svg)(\?(?<type>\w+))?$/);
26
+ function transformSVG(sourcePath, options = {}) {
27
+ var _SVG_PATH_REGEX_exec;
28
+ var _SVG_PATH_REGEX_exec_groups;
29
+ const { type = getType(sourcePath), path } = (_SVG_PATH_REGEX_exec_groups = (_SVG_PATH_REGEX_exec = SVG_PATH_REGEX.exec(sourcePath)) === null || _SVG_PATH_REGEX_exec === void 0 ? void 0 : _SVG_PATH_REGEX_exec.groups) !== null && _SVG_PATH_REGEX_exec_groups !== void 0 ? _SVG_PATH_REGEX_exec_groups : {};
30
+ if (!path) {
31
+ throw new Error(`${sourcePath} is not an SVG file`);
32
+ }
33
+ return type === 'component' ? renderComponent(path, options) : renderAsset(path, options);
34
+ }
35
+ function renderAsset(sourcePath, { esm }) {
36
+ const modulePath = getModulePath(sourcePath);
37
+ return esm ? `export default '${modulePath}';` : `module.exports = { __esModule: true, default: '${modulePath}' };`;
38
+ }
39
+ function renderComponent(sourcePath, { esm }) {
40
+ const modulePath = getModulePath(sourcePath);
41
+ return `
42
+ const _jsx = require('react/jsx-runtime').jsx;
43
+ const SVG = props => {
44
+ return _jsx('svg', {
45
+ href: '${modulePath}',
46
+ id: '${_path.default.basename(sourcePath)}',
47
+ ...props
48
+ });
49
+ }
50
+ SVG.toString = () => '${modulePath}';
51
+ ${esm ? 'export default SVG;' : 'module.exports = { __esModule: true, default: SVG };'}
52
+ `;
53
+ }
54
+ function getModulePath(sourcePath) {
55
+ return _path.default.relative(process.cwd(), sourcePath).replace(/node_modules[\\/]/, '').replace(/\\/g, '/');
56
+ }
57
+ const ANVIL2_REGEX = new RegExp(/node_modules[\\/]@servicetitan[\\/]anvil2/);
58
+ function getType(sourcePath) {
59
+ return ANVIL2_REGEX.test(sourcePath) ? 'component' : 'asset';
60
+ }
61
+
62
+ //# sourceMappingURL=transform-svg.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/transform-svg.ts"],"sourcesContent":["import path from 'path';\n\nexport const SVG_PATH_REGEX = RegExp(/^(?<path>.+\\.svg)(\\?(?<type>\\w+))?$/);\n\ninterface TransformOptions {\n esm?: boolean;\n}\n\nexport function transformSVG(sourcePath: string, options: TransformOptions = {}) {\n const { type = getType(sourcePath), path } = SVG_PATH_REGEX.exec(sourcePath)?.groups ?? {};\n if (!path) {\n throw new Error(`${sourcePath} is not an SVG file`);\n }\n\n return type === 'component' ? renderComponent(path, options) : renderAsset(path, options);\n}\n\nfunction renderAsset(sourcePath: string, { esm }: TransformOptions) {\n const modulePath = getModulePath(sourcePath);\n return esm\n ? `export default '${modulePath}';`\n : `module.exports = { __esModule: true, default: '${modulePath}' };`;\n}\n\nfunction renderComponent(sourcePath: string, { esm }: TransformOptions) {\n const modulePath = getModulePath(sourcePath);\n return `\n const _jsx = require('react/jsx-runtime').jsx;\n const SVG = props => {\n return _jsx('svg', {\n href: '${modulePath}',\n id: '${path.basename(sourcePath)}', \n ...props\n });\n }\n SVG.toString = () => '${modulePath}';\n ${esm ? 'export default SVG;' : 'module.exports = { __esModule: true, default: SVG };'}\n `;\n}\n\nfunction getModulePath(sourcePath: string) {\n return path\n .relative(process.cwd(), sourcePath)\n .replace(/node_modules[\\\\/]/, '')\n .replace(/\\\\/g, '/');\n}\n\nconst ANVIL2_REGEX = new RegExp(/node_modules[\\\\/]@servicetitan[\\\\/]anvil2/);\n\nfunction getType(sourcePath: string) {\n return ANVIL2_REGEX.test(sourcePath) ? 'component' : 'asset';\n}\n"],"names":["SVG_PATH_REGEX","transformSVG","RegExp","sourcePath","options","type","getType","path","exec","groups","Error","renderComponent","renderAsset","esm","modulePath","getModulePath","basename","relative","process","cwd","replace","ANVIL2_REGEX","test"],"mappings":";;;;;;;;;;;QAEaA;eAAAA;;QAMGC;eAAAA;;;6DARC;;;;;;AAEV,MAAMD,iBAAiBE,OAAO;AAM9B,SAASD,aAAaE,UAAkB,EAAEC,UAA4B,CAAC,CAAC;QAC9BJ;QAAAA;IAA7C,MAAM,EAAEK,OAAOC,QAAQH,WAAW,EAAEI,IAAI,EAAE,GAAGP,CAAAA,+BAAAA,uBAAAA,eAAeQ,IAAI,CAACL,yBAApBH,2CAAAA,qBAAiCS,MAAM,cAAvCT,yCAAAA,8BAA2C,CAAC;IACzF,IAAI,CAACO,MAAM;QACP,MAAM,IAAIG,MAAM,GAAGP,WAAW,mBAAmB,CAAC;IACtD;IAEA,OAAOE,SAAS,cAAcM,gBAAgBJ,MAAMH,WAAWQ,YAAYL,MAAMH;AACrF;AAEA,SAASQ,YAAYT,UAAkB,EAAE,EAAEU,GAAG,EAAoB;IAC9D,MAAMC,aAAaC,cAAcZ;IACjC,OAAOU,MACD,CAAC,gBAAgB,EAAEC,WAAW,EAAE,CAAC,GACjC,CAAC,+CAA+C,EAAEA,WAAW,IAAI,CAAC;AAC5E;AAEA,SAASH,gBAAgBR,UAAkB,EAAE,EAAEU,GAAG,EAAoB;IAClE,MAAMC,aAAaC,cAAcZ;IACjC,OAAO,CAAC;;;;uBAIW,EAAEW,WAAW;qBACf,EAAEP,aAAI,CAACS,QAAQ,CAACb,YAAY;;;;8BAInB,EAAEW,WAAW;QACnC,EAAED,MAAM,wBAAwB,uDAAuD;IAC3F,CAAC;AACL;AAEA,SAASE,cAAcZ,UAAkB;IACrC,OAAOI,aAAI,CACNU,QAAQ,CAACC,QAAQC,GAAG,IAAIhB,YACxBiB,OAAO,CAAC,qBAAqB,IAC7BA,OAAO,CAAC,OAAO;AACxB;AAEA,MAAMC,eAAe,IAAInB,OAAO;AAEhC,SAASI,QAAQH,UAAkB;IAC/B,OAAOkB,aAAaC,IAAI,CAACnB,cAAc,cAAc;AACzD"}
@@ -0,0 +1,4 @@
1
+ import type { Plugin } from 'vitest/config';
2
+ declare function svgTransformer(): Plugin;
3
+ export default svgTransformer;
4
+ //# sourceMappingURL=svg-transformer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"svg-transformer.d.ts","sourceRoot":"","sources":["../../src/vitest/svg-transformer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAG5C,iBAAS,cAAc,IAAI,MAAM,CAUhC;AAGD,eAAe,cAAc,CAAC"}
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, // eslint-disable-next-line import/no-default-export
6
+ "default", {
7
+ enumerable: true,
8
+ get: function() {
9
+ return _default;
10
+ }
11
+ });
12
+ const _transformsvg = require("../utils/transform-svg");
13
+ function svgTransformer() {
14
+ return {
15
+ name: 'vitest-svg-transformer',
16
+ transform (_src, path) {
17
+ if (_transformsvg.SVG_PATH_REGEX.test(path)) {
18
+ const code = (0, _transformsvg.transformSVG)(path, {
19
+ esm: true
20
+ });
21
+ return {
22
+ code,
23
+ map: null
24
+ };
25
+ }
26
+ }
27
+ };
28
+ }
29
+ const _default = svgTransformer;
30
+
31
+ //# sourceMappingURL=svg-transformer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/vitest/svg-transformer.ts"],"sourcesContent":["import type { Plugin } from 'vitest/config';\nimport { SVG_PATH_REGEX, transformSVG } from '../utils/transform-svg';\n\nfunction svgTransformer(): Plugin {\n return {\n name: 'vitest-svg-transformer',\n transform(_src, path) {\n if (SVG_PATH_REGEX.test(path)) {\n const code = transformSVG(path, { esm: true });\n return { code, map: null };\n }\n },\n };\n}\n\n// eslint-disable-next-line import/no-default-export\nexport default svgTransformer;\n"],"names":["svgTransformer","name","transform","_src","path","SVG_PATH_REGEX","test","code","transformSVG","esm","map"],"mappings":";;;;+BAeA,oDAAoD;AACpD;;;eAAA;;;8BAf6C;AAE7C,SAASA;IACL,OAAO;QACHC,MAAM;QACNC,WAAUC,IAAI,EAAEC,IAAI;YAChB,IAAIC,4BAAc,CAACC,IAAI,CAACF,OAAO;gBAC3B,MAAMG,OAAOC,IAAAA,0BAAY,EAACJ,MAAM;oBAAEK,KAAK;gBAAK;gBAC5C,OAAO;oBAAEF;oBAAMG,KAAK;gBAAK;YAC7B;QACJ;IACJ;AACJ;MAGA,WAAeV"}
@@ -1 +1 @@
1
- {"version":3,"file":"html-plugin.d.ts","sourceRoot":"","sources":["../../../../src/webpack/configs/plugins/html-plugin.ts"],"names":[],"mappings":"AACA,OAAO,iBAA0D,MAAM,qBAAqB,CAAC;AAE7F,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,UAAU,CACtB,EAAE,KAAK,EAAE,uBAAuB,EAAE,QAAQ,EAAE,cAAc,EAAE,IAAI,EAAE,EAAE,OAAO,EAC3E,EAAE,OAAO,EAAE,EAAE,SAAS,iCA+CzB"}
1
+ {"version":3,"file":"html-plugin.d.ts","sourceRoot":"","sources":["../../../../src/webpack/configs/plugins/html-plugin.ts"],"names":[],"mappings":"AACA,OAAO,iBAA0D,MAAM,qBAAqB,CAAC;AAE7F,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,UAAU,CACtB,EAAE,KAAK,EAAE,uBAAuB,EAAE,QAAQ,EAAE,cAAc,EAAE,IAAI,EAAE,EAAE,OAAO,EAC3E,EAAE,OAAO,EAAE,EAAE,SAAS,iCAkDzB"}
@@ -34,10 +34,13 @@ function htmlPlugin({ embed, emitExposedDependencies, headless, isWebComponent,
34
34
  <head>
35
35
  <meta name="viewport" content="width=device-width,initial-scale=1">
36
36
  ${headTags}
37
+ <script type="text/javascript">
38
+ /* Simulate host initialization */
39
+ window.onload = () => document.querySelector("${name}")?.provide({ onReady() {}});
40
+ </script>
37
41
  </head>
38
42
  <body>
39
43
  <${name} style-urls="${styleUrls}" />
40
-
41
44
  ${bodyTags}
42
45
  </body>
43
46
  </html>
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/webpack/configs/plugins/html-plugin.ts"],"sourcesContent":["import deepmerge from 'deepmerge';\nimport HtmlWebpackPlugin, { Options as HtmlWebpackPluginOptions } from 'html-webpack-plugin';\nimport { splitByEntry } from '../../utils';\nimport { Context, Overrides } from '../types';\n\nexport function htmlPlugin(\n { embed, emitExposedDependencies, headless, isWebComponent, name }: Context,\n { plugins }: Overrides\n) {\n const { HtmlWebpackPlugin: htmlWebpackPluginOptions = {} } = plugins ?? {};\n\n if (embed || headless || emitExposedDependencies) {\n return;\n }\n\n return new HtmlWebpackPlugin(\n deepmerge<HtmlWebpackPluginOptions>(\n {\n title: 'ServiceTitan',\n ...(isWebComponent\n ? {\n inject: false,\n publicPath: '/',\n templateContent: ({\n htmlWebpackPlugin: {\n tags: { headTags, bodyTags },\n files,\n },\n }) => {\n const styleUrls = encodeURIComponent(JSON.stringify(files.css));\n return `\n <!DOCTYPE html>\n <html>\n <head>\n <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n ${headTags}\n </head>\n <body>\n <${name} style-urls=\"${styleUrls}\" />\n\n ${bodyTags}\n </body>\n </html>\n `;\n },\n }\n : {}),\n templateParameters: {\n splitByEntry,\n },\n },\n htmlWebpackPluginOptions\n )\n );\n}\n"],"names":["htmlPlugin","embed","emitExposedDependencies","headless","isWebComponent","name","plugins","HtmlWebpackPlugin","htmlWebpackPluginOptions","deepmerge","title","inject","publicPath","templateContent","htmlWebpackPlugin","tags","headTags","bodyTags","files","styleUrls","encodeURIComponent","JSON","stringify","css","templateParameters","splitByEntry"],"mappings":";;;;+BAKgBA;;;eAAAA;;;kEALM;0EACiD;uBAC1C;;;;;;AAGtB,SAASA,WACZ,EAAEC,KAAK,EAAEC,uBAAuB,EAAEC,QAAQ,EAAEC,cAAc,EAAEC,IAAI,EAAW,EAC3E,EAAEC,OAAO,EAAa;IAEtB,MAAM,EAAEC,mBAAmBC,2BAA2B,CAAC,CAAC,EAAE,GAAGF,oBAAAA,qBAAAA,UAAW,CAAC;IAEzE,IAAIL,SAASE,YAAYD,yBAAyB;QAC9C;IACJ;IAEA,OAAO,IAAIK,0BAAiB,CACxBE,IAAAA,kBAAS,EACL;QACIC,OAAO;QACP,GAAIN,iBACE;YACIO,QAAQ;YACRC,YAAY;YACZC,iBAAiB,CAAC,EACdC,mBAAmB,EACfC,MAAM,EAAEC,QAAQ,EAAEC,QAAQ,EAAE,EAC5BC,KAAK,EACR,EACJ;gBACG,MAAMC,YAAYC,mBAAmBC,KAAKC,SAAS,CAACJ,MAAMK,GAAG;gBAC7D,OAAO,CAAC;;;;;wCAKE,EAAEP,SAAS;;;yCAGV,EAAEX,KAAK,aAAa,EAAEc,UAAU;;wCAEjC,EAAEF,SAAS;;;4BAGvB,CAAC;YACH;QACJ,IACA,CAAC,CAAC;QACRO,oBAAoB;YAChBC,cAAAA,mBAAY;QAChB;IACJ,GACAjB;AAGZ"}
1
+ {"version":3,"sources":["../../../../src/webpack/configs/plugins/html-plugin.ts"],"sourcesContent":["import deepmerge from 'deepmerge';\nimport HtmlWebpackPlugin, { Options as HtmlWebpackPluginOptions } from 'html-webpack-plugin';\nimport { splitByEntry } from '../../utils';\nimport { Context, Overrides } from '../types';\n\nexport function htmlPlugin(\n { embed, emitExposedDependencies, headless, isWebComponent, name }: Context,\n { plugins }: Overrides\n) {\n const { HtmlWebpackPlugin: htmlWebpackPluginOptions = {} } = plugins ?? {};\n\n if (embed || headless || emitExposedDependencies) {\n return;\n }\n\n return new HtmlWebpackPlugin(\n deepmerge<HtmlWebpackPluginOptions>(\n {\n title: 'ServiceTitan',\n ...(isWebComponent\n ? {\n inject: false,\n publicPath: '/',\n templateContent: ({\n htmlWebpackPlugin: {\n tags: { headTags, bodyTags },\n files,\n },\n }) => {\n const styleUrls = encodeURIComponent(JSON.stringify(files.css));\n return `\n <!DOCTYPE html>\n <html>\n <head>\n <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n ${headTags}\n <script type=\"text/javascript\">\n /* Simulate host initialization */\n window.onload = () => document.querySelector(\"${name}\")?.provide({ onReady() {}});\n </script>\n </head>\n <body>\n <${name} style-urls=\"${styleUrls}\" />\n ${bodyTags}\n </body>\n </html>\n `;\n },\n }\n : {}),\n templateParameters: {\n splitByEntry,\n },\n },\n htmlWebpackPluginOptions\n )\n );\n}\n"],"names":["htmlPlugin","embed","emitExposedDependencies","headless","isWebComponent","name","plugins","HtmlWebpackPlugin","htmlWebpackPluginOptions","deepmerge","title","inject","publicPath","templateContent","htmlWebpackPlugin","tags","headTags","bodyTags","files","styleUrls","encodeURIComponent","JSON","stringify","css","templateParameters","splitByEntry"],"mappings":";;;;+BAKgBA;;;eAAAA;;;kEALM;0EACiD;uBAC1C;;;;;;AAGtB,SAASA,WACZ,EAAEC,KAAK,EAAEC,uBAAuB,EAAEC,QAAQ,EAAEC,cAAc,EAAEC,IAAI,EAAW,EAC3E,EAAEC,OAAO,EAAa;IAEtB,MAAM,EAAEC,mBAAmBC,2BAA2B,CAAC,CAAC,EAAE,GAAGF,oBAAAA,qBAAAA,UAAW,CAAC;IAEzE,IAAIL,SAASE,YAAYD,yBAAyB;QAC9C;IACJ;IAEA,OAAO,IAAIK,0BAAiB,CACxBE,IAAAA,kBAAS,EACL;QACIC,OAAO;QACP,GAAIN,iBACE;YACIO,QAAQ;YACRC,YAAY;YACZC,iBAAiB,CAAC,EACdC,mBAAmB,EACfC,MAAM,EAAEC,QAAQ,EAAEC,QAAQ,EAAE,EAC5BC,KAAK,EACR,EACJ;gBACG,MAAMC,YAAYC,mBAAmBC,KAAKC,SAAS,CAACJ,MAAMK,GAAG;gBAC7D,OAAO,CAAC;;;;;wCAKE,EAAEP,SAAS;;;0FAGuC,EAAEX,KAAK;;;;yCAIxD,EAAEA,KAAK,aAAa,EAAEc,UAAU;wCACjC,EAAEF,SAAS;;;4BAGvB,CAAC;YACH;QACJ,IACA,CAAC,CAAC;QACRO,oBAAoB;YAChBC,cAAAA,mBAAY;QAChB;IACJ,GACAjB;AAGZ"}
@@ -1 +1 @@
1
- {"version":3,"file":"mini-css-extract-plugin.d.ts","sourceRoot":"","sources":["../../../../src/webpack/configs/plugins/mini-css-extract-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,oBAAoB,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oCAc1E"}
1
+ {"version":3,"file":"mini-css-extract-plugin.d.ts","sourceRoot":"","sources":["../../../../src/webpack/configs/plugins/mini-css-extract-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,oBAAoB,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oCAU1E"}
@@ -16,17 +16,11 @@ function _interop_require_default(obj) {
16
16
  }
17
17
  function miniCssExtractPlugin(context, overrides) {
18
18
  const { isCustomStyleRules, isExposeSharedDependencies, isProduction, isWebComponent } = context;
19
- if (isProduction) {
20
- if (!isCustomStyleRules) {
21
- var _overrides_plugins;
22
- return new _minicssextractplugin.default({
23
- filename: '[name].[contenthash].bundle.css',
24
- ...(_overrides_plugins = overrides.plugins) === null || _overrides_plugins === void 0 ? void 0 : _overrides_plugins.MiniCssExtractPlugin
25
- });
26
- }
27
- } else if (isWebComponent || isExposeSharedDependencies && !isCustomStyleRules) {
19
+ if (!isCustomStyleRules && (isProduction || isWebComponent || isExposeSharedDependencies)) {
20
+ var _overrides_plugins;
28
21
  return new _minicssextractplugin.default({
29
- filename: '[name].bundle.css'
22
+ filename: isProduction ? '[name].[contenthash].bundle.css' : '[name].bundle.css',
23
+ ...(_overrides_plugins = overrides.plugins) === null || _overrides_plugins === void 0 ? void 0 : _overrides_plugins.MiniCssExtractPlugin
30
24
  });
31
25
  }
32
26
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/webpack/configs/plugins/mini-css-extract-plugin.ts"],"sourcesContent":["import MiniCssExtractPlugin from 'mini-css-extract-plugin';\nimport { Context, Overrides } from '../types';\n\nexport function miniCssExtractPlugin(context: Context, overrides: Overrides) {\n const { isCustomStyleRules, isExposeSharedDependencies, isProduction, isWebComponent } =\n context;\n\n if (isProduction) {\n if (!isCustomStyleRules) {\n return new MiniCssExtractPlugin({\n filename: '[name].[contenthash].bundle.css',\n ...(overrides.plugins as any)?.MiniCssExtractPlugin,\n });\n }\n } else if (isWebComponent || (isExposeSharedDependencies && !isCustomStyleRules)) {\n return new MiniCssExtractPlugin({ filename: '[name].bundle.css' });\n }\n}\n"],"names":["miniCssExtractPlugin","context","overrides","isCustomStyleRules","isExposeSharedDependencies","isProduction","isWebComponent","MiniCssExtractPlugin","filename","plugins"],"mappings":";;;;+BAGgBA;;;eAAAA;;;6EAHiB;;;;;;AAG1B,SAASA,qBAAqBC,OAAgB,EAAEC,SAAoB;IACvE,MAAM,EAAEC,kBAAkB,EAAEC,0BAA0B,EAAEC,YAAY,EAAEC,cAAc,EAAE,GAClFL;IAEJ,IAAII,cAAc;QACd,IAAI,CAACF,oBAAoB;gBAGbD;YAFR,OAAO,IAAIK,6BAAoB,CAAC;gBAC5BC,UAAU;oBACNN,qBAAAA,UAAUO,OAAO,cAAjBP,yCAAD,AAACA,mBAA2BK,oBAAoB,AAAnD;YACJ;QACJ;IACJ,OAAO,IAAID,kBAAmBF,8BAA8B,CAACD,oBAAqB;QAC9E,OAAO,IAAII,6BAAoB,CAAC;YAAEC,UAAU;QAAoB;IACpE;AACJ"}
1
+ {"version":3,"sources":["../../../../src/webpack/configs/plugins/mini-css-extract-plugin.ts"],"sourcesContent":["import MiniCssExtractPlugin from 'mini-css-extract-plugin';\nimport { Context, Overrides } from '../types';\n\nexport function miniCssExtractPlugin(context: Context, overrides: Overrides) {\n const { isCustomStyleRules, isExposeSharedDependencies, isProduction, isWebComponent } =\n context;\n\n if (!isCustomStyleRules && (isProduction || isWebComponent || isExposeSharedDependencies)) {\n return new MiniCssExtractPlugin({\n filename: isProduction ? '[name].[contenthash].bundle.css' : '[name].bundle.css',\n ...overrides.plugins?.MiniCssExtractPlugin,\n });\n }\n}\n"],"names":["miniCssExtractPlugin","context","overrides","isCustomStyleRules","isExposeSharedDependencies","isProduction","isWebComponent","MiniCssExtractPlugin","filename","plugins"],"mappings":";;;;+BAGgBA;;;eAAAA;;;6EAHiB;;;;;;AAG1B,SAASA,qBAAqBC,OAAgB,EAAEC,SAAoB;IACvE,MAAM,EAAEC,kBAAkB,EAAEC,0BAA0B,EAAEC,YAAY,EAAEC,cAAc,EAAE,GAClFL;IAEJ,IAAI,CAACE,sBAAuBE,CAAAA,gBAAgBC,kBAAkBF,0BAAyB,GAAI;YAGhFF;QAFP,OAAO,IAAIK,6BAAoB,CAAC;YAC5BC,UAAUH,eAAe,oCAAoC;gBAC1DH,qBAAAA,UAAUO,OAAO,cAAjBP,yCAAAA,mBAAmBK,oBAAoB,AAA1C;QACJ;IACJ;AACJ"}
@@ -1,5 +1,6 @@
1
1
  module.exports = {
2
2
  transform: {
3
+ '^.+\\.svg$': '@servicetitan/startup/jest-svg-transformer',
3
4
  '^.+\\.jsx?$': [
4
5
  'babel-jest',
5
6
  { presets: [['@babel/preset-env', { targets: { node: 'current' } }]] },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@servicetitan/startup",
3
- "version": "32.5.0",
3
+ "version": "32.7.0",
4
4
  "description": "",
5
5
  "homepage": "https://docs.st.dev/docs/frontend/startup",
6
6
  "repository": {
@@ -15,6 +15,17 @@
15
15
  "sideEffects": false,
16
16
  "main": "./dist/index.js",
17
17
  "typings": "./dist/index.d.ts",
18
+ "exports": {
19
+ ".": {
20
+ "default": "./dist/index.js",
21
+ "types": "./dist/index.d.ts"
22
+ },
23
+ "./jest-preset": "./jest/jest-preset.js",
24
+ "./jest-resolver": "./dist/jest/resolver.js",
25
+ "./jest-svg-transformer": "./dist/jest/svg-transformer.js",
26
+ "./tsconfig/*": "./tsconfig/*.json",
27
+ "./vitest-svg-transformer": "./dist/vitest/svg-transformer.js"
28
+ },
18
29
  "files": [
19
30
  "bin",
20
31
  "dist",
@@ -38,9 +49,9 @@
38
49
  "@jest/core": "~29.7.0",
39
50
  "@jest/types": "~29.6.3",
40
51
  "@jsdevtools/coverage-istanbul-loader": "^3.0.5",
41
- "@servicetitan/eslint-config": "32.5.0",
42
- "@servicetitan/install": "32.5.0",
43
- "@servicetitan/stylelint-config": "32.5.0",
52
+ "@servicetitan/eslint-config": "32.7.0",
53
+ "@servicetitan/install": "32.7.0",
54
+ "@servicetitan/stylelint-config": "32.7.0",
44
55
  "@svgr/webpack": "^8.1.0",
45
56
  "@swc/cli": "^0.5.0",
46
57
  "@swc/core": "1.13.5",
@@ -56,7 +67,7 @@
56
67
  "deepmerge": "~4.3.1",
57
68
  "eslint": "~9.39.1",
58
69
  "execa": "~5.1.1",
59
- "glob": "~11.0.3",
70
+ "glob": "~11.1.0",
60
71
  "html-webpack-plugin": "~5.6.4",
61
72
  "html-webpack-tags-plugin": "^3.0.2",
62
73
  "identity-obj-proxy": "~3.0.0",
@@ -66,6 +77,7 @@
66
77
  "jest-fetch-mock": "~3.0.3",
67
78
  "json5": "^2.2.3",
68
79
  "jwa": "^1.4.2",
80
+ "keyv": "5.5.1",
69
81
  "lerna": "~9.0.0",
70
82
  "less": "~4.4.2",
71
83
  "less-loader": "~12.3.0",
@@ -119,6 +131,9 @@
119
131
  "jwa": [
120
132
  "@progress/kendo-licensing@1.3.5 -> jsonwebtoken@9.0.2 -> jws@3.2.2 -> jwa@1.4.1",
121
133
  "Forcing ^1.4.2 to fix Node v25 incompatibility in 1.4.1 (see https://github.com/auth0/node-jsonwebtoken/issues/992)"
134
+ ],
135
+ "keyv": [
136
+ "Update/remove when https://github.com/stylelint/stylelint/issues/8837 is resolved"
122
137
  ]
123
138
  },
124
139
  "publishConfig": {
@@ -127,5 +142,5 @@
127
142
  "cli": {
128
143
  "webpack": false
129
144
  },
130
- "gitHead": "9ba97491f520e7b5914179aa061d1c3c3285079d"
145
+ "gitHead": "673fb6b56865da309c09f91b4ebf30aaf815a562"
131
146
  }
@@ -53,10 +53,26 @@ describe(`[startup] Test ${Vitest.name}`, () => {
53
53
 
54
54
  const subject = async () => new Vitest().run();
55
55
 
56
+ function expectCallsVitestWithConfig(
57
+ config: Record<string, any>,
58
+ overrides: Record<string, any> = {}
59
+ ) {
60
+ expect(startVitest).toHaveBeenCalledWith(
61
+ 'test',
62
+ [],
63
+ {},
64
+ {
65
+ test: config,
66
+ plugins: [expect.objectContaining({ name: 'vitest-svg-transformer' })],
67
+ ...overrides,
68
+ }
69
+ );
70
+ }
71
+
56
72
  test('runs startVitest with default config', async () => {
57
73
  await subject();
58
74
 
59
- expect(startVitest).toHaveBeenCalledWith('test', [], {}, { test: defaultConfig });
75
+ expectCallsVitestWithConfig(defaultConfig);
60
76
  });
61
77
 
62
78
  test('closes vitest', async () => {
@@ -66,10 +82,6 @@ describe(`[startup] Test ${Vitest.name}`, () => {
66
82
  expect(vitest.close).toHaveBeenCalled();
67
83
  });
68
84
 
69
- function expectCallsVitestWithConfig(config: Record<string, any>) {
70
- expect(startVitest).toHaveBeenCalledWith('test', [], {}, { test: config });
71
- }
72
-
73
85
  describe('with package.json config', () => {
74
86
  const packageJSONConfig: ViteUserConfig['test'] = { bail: 1, globals: false };
75
87
 
@@ -92,7 +104,11 @@ describe(`[startup] Test ${Vitest.name}`, () => {
92
104
  cli: {
93
105
  vitest: {
94
106
  ...packageJSONConfig,
95
- omitDefault: ['coverage.include', 'environment'],
107
+ omitDefault: [
108
+ 'coverage.include',
109
+ 'environment',
110
+ 'plugins.vitest-svg-transformer',
111
+ ],
96
112
  },
97
113
  },
98
114
  }),
@@ -106,7 +122,10 @@ describe(`[startup] Test ${Vitest.name}`, () => {
106
122
  const { include, ...restCoverage } = coverage as any;
107
123
  const defaultSansOmitted = { coverage: restCoverage, ...restDefault };
108
124
 
109
- expectCallsVitestWithConfig({ ...defaultSansOmitted, ...packageJSONConfig });
125
+ expectCallsVitestWithConfig(
126
+ { ...defaultSansOmitted, ...packageJSONConfig },
127
+ { plugins: undefined }
128
+ );
110
129
  });
111
130
  });
112
131
  });
@@ -1,6 +1,7 @@
1
1
  import { configDefaults, coverageConfigDefaults, mergeConfig, ViteUserConfig } from 'vitest/config';
2
2
  import { startVitest, parseCLI, resolveConfig } from 'vitest/node';
3
3
  import { getVitestConfiguration, log, omit } from '../../../../utils';
4
+ import svgTransformer from '../../../../vitest/svg-transformer';
4
5
 
5
6
  type VitestConfig = NonNullable<ViteUserConfig['test']>;
6
7
 
@@ -68,5 +69,9 @@ async function getUserConfig(): Promise<ViteUserConfig> {
68
69
  /* istanbul ignore next: debug only */
69
70
  log.debug('vitest:userConfig', () => JSON.stringify(result, null, 2));
70
71
 
71
- return { test: result };
72
+ const plugins: NonNullable<ViteUserConfig['plugins']> = [svgTransformer()].filter(
73
+ ({ name }) => !omitDefault.includes(`plugins.${name}`)
74
+ );
75
+
76
+ return { test: result, ...(plugins.length ? { plugins } : {}) };
72
77
  }
@@ -25,7 +25,7 @@ jest.mock('../../../utils', () => ({
25
25
  */
26
26
 
27
27
  describe(`[startup] cli utils (${copyFiles.name})`, () => {
28
- const source = fs.mkdtempSync('src');
28
+ const source = fs.mkdtempSync('copyFiles-test-');
29
29
  const destination = 'dist';
30
30
  const files = `${source}/**/*.{${supportedExtensions.join()}}`;
31
31
  let options: Parameters<typeof copyFiles>[0];
@@ -0,0 +1,41 @@
1
+ import resolver from '../resolver';
2
+
3
+ describe('[startup] Jest resolver', () => {
4
+ const options: Partial<Parameters<typeof resolver>[1]> = { defaultResolver: jest.fn() };
5
+ let path: string;
6
+ let queryParam: string | undefined;
7
+
8
+ beforeEach(() => {
9
+ path = 'foo.svg';
10
+ queryParam = undefined;
11
+ jest.clearAllMocks();
12
+ });
13
+
14
+ const subject = () => resolver(`${path}${queryParam ?? ''}`, options as any);
15
+
16
+ function itCallsDefaultResolver() {
17
+ test('calls defaultResolver with path', () => {
18
+ subject();
19
+
20
+ expect(options.defaultResolver).toHaveBeenCalledWith(path, options);
21
+ });
22
+ }
23
+
24
+ itCallsDefaultResolver();
25
+
26
+ describe('when path includes query param', () => {
27
+ beforeEach(() => (queryParam = `?bar`));
28
+
29
+ test('omits query param', () => {
30
+ subject();
31
+
32
+ expect(options.defaultResolver).toHaveBeenCalledWith(path, expect.anything());
33
+ });
34
+ });
35
+
36
+ describe('when path is not svg', () => {
37
+ beforeEach(() => (path = 'foo'));
38
+
39
+ itCallsDefaultResolver();
40
+ });
41
+ });
@@ -0,0 +1,31 @@
1
+ import { transformSVG } from '../../utils/transform-svg';
2
+ import svgTransformer from '../svg-transformer';
3
+
4
+ jest.mock('../../utils/transform-svg', () => ({
5
+ transformSVG: jest.fn(),
6
+ }));
7
+
8
+ describe('[startup] Jest svgTransformer', () => {
9
+ const sourceText = '';
10
+ const transformSVGResult = 'foo';
11
+ const options = {} as any;
12
+ let sourcePath: string;
13
+
14
+ beforeEach(() => {
15
+ sourcePath = 'foo.svg';
16
+ jest.clearAllMocks();
17
+ jest.mocked(transformSVG).mockReturnValue(transformSVGResult);
18
+ });
19
+
20
+ const subject = () => svgTransformer.process!(sourceText, sourcePath, options);
21
+
22
+ test('returns transformed SVG', () => {
23
+ expect(subject()).toEqual({ code: transformSVGResult });
24
+ });
25
+
26
+ test('transforms SVG as component', () => {
27
+ subject();
28
+
29
+ expect(transformSVG).toHaveBeenCalledWith(`${sourcePath}?component`);
30
+ });
31
+ });
@@ -0,0 +1,9 @@
1
+ import type { SyncResolver } from 'jest-resolve';
2
+ import { SVG_PATH_REGEX } from '../utils/transform-svg';
3
+
4
+ const resolver: SyncResolver = (path, options) => {
5
+ const { type, path: pathSansType } = SVG_PATH_REGEX.exec(path)?.groups ?? {};
6
+ return options.defaultResolver(type ? pathSansType : path, options);
7
+ };
8
+
9
+ export = resolver;
@@ -0,0 +1,17 @@
1
+ import type { Transformer } from '@jest/transform';
2
+
3
+ import { transformSVG } from '../utils/transform-svg';
4
+
5
+ const svgTransformer: Transformer = {
6
+ process(_sourceText, sourcePath) {
7
+ /*
8
+ * Because Jest discards the query param and caches only one transformation,
9
+ * we can't detect or rely on how the SVG was requested. So, render all SVGs
10
+ * as component and rely on its toString() to render the "asset" version.
11
+ */
12
+ return { code: transformSVG(`${sourcePath}?component`) };
13
+ },
14
+ };
15
+
16
+ // eslint-disable-next-line import/no-default-export
17
+ export default svgTransformer;
@@ -19,11 +19,11 @@ describe('[startup] Utils', () => {
19
19
  coveragePathIgnorePatterns: ['^.+\\.d\\.ts$'],
20
20
  coverageReporters: ['html-spa', 'text', 'json', 'cobertura', 'lcov'],
21
21
  moduleNameMapper: {
22
- '\\.(css|scss|less|png|svg|svg\\?\\w+|jpg|jpeg|gif|woff|woff2|eot|ttf|otf)$':
23
- 'identity-obj-proxy',
22
+ '\\.(css|scss|less|png|jpg|jpeg|gif|woff|woff2|eot|ttf|otf)$': 'identity-obj-proxy',
24
23
  },
25
24
  modulePathIgnorePatterns: ['<rootDir>/.*/__mocks__'],
26
- preset: expect.stringMatching(/startup[\\\/]+jest/),
25
+ preset: expect.stringMatching(/startup[\\/]+jest/),
26
+ resolver: '@servicetitan/startup/jest-resolver',
27
27
  setupFiles: [expect.stringContaining(path.join('jest', 'setup.js'))],
28
28
  testEnvironment: 'jsdom',
29
29
  testPathIgnorePatterns: ['\\.yalc', ...destinationFolders],
@@ -120,5 +120,38 @@ describe('[startup] Utils', () => {
120
120
  });
121
121
  }
122
122
  );
123
+
124
+ describe('with custom "moduleNameMapper"', () => {
125
+ const customConfig = { moduleNameMapper: { '^foo$': 'bar' } };
126
+
127
+ beforeEach(() => {
128
+ jest.mocked(getJestConfiguration).mockReturnValue(customConfig);
129
+ });
130
+
131
+ function itMergesDefaultWithCustomValue() {
132
+ test('merges default with custom value', () => {
133
+ expect(subject()).toEqual(
134
+ expect.objectContaining({
135
+ moduleNameMapper: JSON.stringify({
136
+ ...customConfig.moduleNameMapper,
137
+ ...defaultConfig.moduleNameMapper,
138
+ }),
139
+ })
140
+ );
141
+ });
142
+ }
143
+
144
+ itMergesDefaultWithCustomValue();
145
+
146
+ describe('when custom value is stringified', () => {
147
+ beforeEach(() => {
148
+ jest.mocked(getJestConfiguration).mockReturnValue({
149
+ moduleNameMapper: JSON.stringify(customConfig.moduleNameMapper),
150
+ });
151
+ });
152
+
153
+ itMergesDefaultWithCustomValue();
154
+ });
155
+ });
123
156
  });
124
157
  });
@@ -0,0 +1,110 @@
1
+ import path from 'path';
2
+ import { SVG_PATH_REGEX, transformSVG } from '../transform-svg';
3
+
4
+ describe('[startup] Utils SVG_PATH_REGEX', () => {
5
+ const subject = () => SVG_PATH_REGEX;
6
+
7
+ test('captures path and type', () => {
8
+ const groups = subject().exec('foo/bar.svg?component')?.groups;
9
+ expect(groups).toEqual({ path: 'foo/bar.svg', type: 'component' });
10
+ });
11
+ });
12
+
13
+ describe(`[startup] Utils transformSVG`, () => {
14
+ let sourcePath: string;
15
+ let queryParam: string | undefined;
16
+ let options: Parameters<typeof transformSVG>[1];
17
+
18
+ beforeEach(() => {
19
+ sourcePath = 'foo.svg';
20
+ queryParam = undefined;
21
+ options = undefined;
22
+ jest.clearAllMocks();
23
+ });
24
+
25
+ const subject = () => transformSVG(`${sourcePath}${queryParam ?? ''}`, options);
26
+
27
+ function itRendersSVGString() {
28
+ test('renders SVG string', () => {
29
+ const modulePath = sourcePath.replace('node_modules/', '');
30
+ expect(subject()).toEqual(
31
+ `module.exports = { __esModule: true, default: '${modulePath}' };`
32
+ );
33
+ });
34
+ }
35
+
36
+ function itRendersSVGComponent() {
37
+ test('renders SVG component', () => {
38
+ const modulePath = sourcePath.replace('node_modules/', '');
39
+ const basename = path.basename(sourcePath);
40
+ expect(subject().replace(/\s+/g, '')).toEqual(
41
+ `
42
+ const _jsx = require('react/jsx-runtime').jsx;
43
+ const SVG = props => {
44
+ return _jsx('svg', {
45
+ href: '${modulePath}',
46
+ id: '${basename}',
47
+ ...props
48
+ });
49
+ }
50
+ SVG.toString = () => '${modulePath}';
51
+ module.exports = { __esModule: true, default: SVG };
52
+ `.replace(/\s+/g, '')
53
+ );
54
+ });
55
+ }
56
+
57
+ itRendersSVGString();
58
+
59
+ describe('with {esm: true}', () => {
60
+ beforeEach(() => (options = { esm: true }));
61
+
62
+ test('renders ESM module', () => {
63
+ expect(subject()).toEqual(`export default '${sourcePath}';`);
64
+ });
65
+ });
66
+
67
+ describe('with ?component query param', () => {
68
+ beforeEach(() => (queryParam = '?component'));
69
+
70
+ itRendersSVGComponent();
71
+ });
72
+
73
+ describe('with Windows path', () => {
74
+ beforeEach(() => (sourcePath = 'foo\\bar\\baz.svg'));
75
+
76
+ test('replaces backslash with forward slash', () => {
77
+ expect(subject()).toMatch(/'foo\/bar\/baz.svg'/);
78
+ });
79
+ });
80
+
81
+ describe('when path is not svg', () => {
82
+ beforeEach(() => (sourcePath = 'foo'));
83
+
84
+ test('throws error', () => {
85
+ expect(() => subject()).toThrow(`${sourcePath} is not an SVG file`);
86
+ });
87
+ });
88
+
89
+ describe('with Anvil2 SVG', () => {
90
+ beforeEach(() => {
91
+ sourcePath = 'node_modules/@servicetitan/anvil2/assets/foo.svg';
92
+ });
93
+
94
+ itRendersSVGComponent();
95
+
96
+ describe('with {esm: true}', () => {
97
+ beforeEach(() => (options = { esm: true }));
98
+
99
+ test('renders ESM module', () => {
100
+ expect(subject()).toMatch(/export default SVG;\s*$/);
101
+ });
102
+ });
103
+
104
+ describe('with ?asset query param', () => {
105
+ beforeEach(() => (queryParam = '?asset'));
106
+
107
+ itRendersSVGString();
108
+ });
109
+ });
110
+ });
@@ -7,8 +7,7 @@ import { omit } from './omit';
7
7
 
8
8
  function getDefaultJestConfiguration() {
9
9
  const moduleNameMapper = {
10
- '\\.(css|scss|less|png|svg|svg\\?\\w+|jpg|jpeg|gif|woff|woff2|eot|ttf|otf)$':
11
- 'identity-obj-proxy',
10
+ '\\.(css|scss|less|png|jpg|jpeg|gif|woff|woff2|eot|ttf|otf)$': 'identity-obj-proxy',
12
11
  };
13
12
 
14
13
  return {
@@ -18,6 +17,7 @@ function getDefaultJestConfiguration() {
18
17
  moduleNameMapper,
19
18
  modulePathIgnorePatterns: ['<rootDir>/.*/__mocks__'],
20
19
  preset: path.join(__dirname, '../../jest'),
20
+ resolver: '@servicetitan/startup/jest-resolver',
21
21
  setupFiles: [path.join(__dirname, '../../jest/setup.js')],
22
22
  testEnvironment: 'jsdom',
23
23
  testPathIgnorePatterns: ['\\.yalc', ...getDestinationFolders()],
@@ -48,6 +48,15 @@ export function getJestConfigCLI(args: Config.Argv): Config.Argv {
48
48
 
49
49
  const defaultConfig = omit(getDefaultJestConfiguration(), omitDefault);
50
50
 
51
+ let moduleNameMapper: Record<string, string> | undefined =
52
+ typeof config.moduleNameMapper === 'string'
53
+ ? JSON.parse(config.moduleNameMapper)
54
+ : config.moduleNameMapper;
55
+
56
+ if (defaultConfig.moduleNameMapper) {
57
+ moduleNameMapper = { ...moduleNameMapper, ...defaultConfig.moduleNameMapper };
58
+ }
59
+
51
60
  return stringifyForCLI({
52
61
  ...mergeArrayValues(defaultConfig, {
53
62
  coveragePathIgnorePatterns,
@@ -55,6 +64,7 @@ export function getJestConfigCLI(args: Config.Argv): Config.Argv {
55
64
  testPathIgnorePatterns,
56
65
  }),
57
66
  ...config,
67
+ ...(moduleNameMapper ? { moduleNameMapper } : {}),
58
68
  });
59
69
  }
60
70
 
@@ -0,0 +1,52 @@
1
+ import path from 'path';
2
+
3
+ export const SVG_PATH_REGEX = RegExp(/^(?<path>.+\.svg)(\?(?<type>\w+))?$/);
4
+
5
+ interface TransformOptions {
6
+ esm?: boolean;
7
+ }
8
+
9
+ export function transformSVG(sourcePath: string, options: TransformOptions = {}) {
10
+ const { type = getType(sourcePath), path } = SVG_PATH_REGEX.exec(sourcePath)?.groups ?? {};
11
+ if (!path) {
12
+ throw new Error(`${sourcePath} is not an SVG file`);
13
+ }
14
+
15
+ return type === 'component' ? renderComponent(path, options) : renderAsset(path, options);
16
+ }
17
+
18
+ function renderAsset(sourcePath: string, { esm }: TransformOptions) {
19
+ const modulePath = getModulePath(sourcePath);
20
+ return esm
21
+ ? `export default '${modulePath}';`
22
+ : `module.exports = { __esModule: true, default: '${modulePath}' };`;
23
+ }
24
+
25
+ function renderComponent(sourcePath: string, { esm }: TransformOptions) {
26
+ const modulePath = getModulePath(sourcePath);
27
+ return `
28
+ const _jsx = require('react/jsx-runtime').jsx;
29
+ const SVG = props => {
30
+ return _jsx('svg', {
31
+ href: '${modulePath}',
32
+ id: '${path.basename(sourcePath)}',
33
+ ...props
34
+ });
35
+ }
36
+ SVG.toString = () => '${modulePath}';
37
+ ${esm ? 'export default SVG;' : 'module.exports = { __esModule: true, default: SVG };'}
38
+ `;
39
+ }
40
+
41
+ function getModulePath(sourcePath: string) {
42
+ return path
43
+ .relative(process.cwd(), sourcePath)
44
+ .replace(/node_modules[\\/]/, '')
45
+ .replace(/\\/g, '/');
46
+ }
47
+
48
+ const ANVIL2_REGEX = new RegExp(/node_modules[\\/]@servicetitan[\\/]anvil2/);
49
+
50
+ function getType(sourcePath: string) {
51
+ return ANVIL2_REGEX.test(sourcePath) ? 'component' : 'asset';
52
+ }
@@ -0,0 +1,59 @@
1
+ import { transformSVG } from '../../utils/transform-svg';
2
+ import svgTransformer from '../svg-transformer';
3
+
4
+ jest.mock('../../utils/transform-svg', () => ({
5
+ ...jest.requireActual('../../utils/transform-svg'),
6
+ transformSVG: jest.fn(),
7
+ }));
8
+
9
+ describe('[startup] Vitest svgTransformer', () => {
10
+ const source = '';
11
+ let path: string;
12
+ let queryParam: string | undefined;
13
+
14
+ beforeEach(() => {
15
+ path = 'foo';
16
+ queryParam = undefined;
17
+ jest.clearAllMocks();
18
+ });
19
+
20
+ const subject = () => {
21
+ return (svgTransformer().transform as any)(source, `${path}${queryParam ?? ''}`);
22
+ };
23
+
24
+ test('returns undefined', () => {
25
+ expect(subject()).toBeUndefined();
26
+ });
27
+
28
+ describe('when path is SVG', () => {
29
+ const transformSVGResult = 'foo';
30
+
31
+ beforeEach(() => {
32
+ path = 'foo.svg';
33
+ jest.mocked(transformSVG).mockReturnValue(transformSVGResult);
34
+ });
35
+
36
+ test('returns transformed SVG', () => {
37
+ expect(subject()).toEqual({ code: transformSVGResult, map: null });
38
+ });
39
+
40
+ test('transforms SVG as ESM module', () => {
41
+ subject();
42
+
43
+ expect(transformSVG).toHaveBeenCalledWith(path, { esm: true });
44
+ });
45
+
46
+ describe('when path includes query param', () => {
47
+ beforeEach(() => (queryParam = '?bar'));
48
+
49
+ test('passes query param to transformSVG', () => {
50
+ subject();
51
+
52
+ expect(transformSVG).toHaveBeenCalledWith(
53
+ `${path}${queryParam}`,
54
+ expect.anything()
55
+ );
56
+ });
57
+ });
58
+ });
59
+ });
@@ -0,0 +1,17 @@
1
+ import type { Plugin } from 'vitest/config';
2
+ import { SVG_PATH_REGEX, transformSVG } from '../utils/transform-svg';
3
+
4
+ function svgTransformer(): Plugin {
5
+ return {
6
+ name: 'vitest-svg-transformer',
7
+ transform(_src, path) {
8
+ if (SVG_PATH_REGEX.test(path)) {
9
+ const code = transformSVG(path, { esm: true });
10
+ return { code, map: null };
11
+ }
12
+ },
13
+ };
14
+ }
15
+
16
+ // eslint-disable-next-line import/no-default-export
17
+ export default svgTransformer;
@@ -89,7 +89,7 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
89
89
  }
90
90
 
91
91
  beforeEach(() => {
92
- overrides = { plugins: {} };
92
+ overrides = { plugins: { MiniCssExtractPlugin: { attributes: { foo: 'bar' } } } };
93
93
  options = { name: 'app' };
94
94
 
95
95
  jest.resetAllMocks();
@@ -214,7 +214,12 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
214
214
 
215
215
  test('configures MiniCssExtractPlugin plugin', () => {
216
216
  expect(subject().plugins).toContainEqual(
217
- expect.objectContaining({ MiniCssExtractPlugin: expect.anything() })
217
+ expect.objectContaining(
218
+ new MiniCssExtractPlugin({
219
+ filename: '[name].bundle.css',
220
+ ...overrides.plugins?.MiniCssExtractPlugin,
221
+ })
222
+ )
218
223
  );
219
224
  });
220
225
 
@@ -85,7 +85,12 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
85
85
  }
86
86
 
87
87
  beforeEach(() => {
88
- overrides = { plugins: { HtmlWebpackPlugin: { favicon: 'foo' } } };
88
+ overrides = {
89
+ plugins: {
90
+ HtmlWebpackPlugin: { favicon: 'foo' },
91
+ MiniCssExtractPlugin: { attributes: { foo: 'bar' } },
92
+ },
93
+ };
89
94
  options = { name: packageName };
90
95
  dependencies = { '@servicetitan/design-system': '*' };
91
96
  sharedDependencies = {
@@ -137,7 +142,10 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
137
142
 
138
143
  test('configures MiniCssExtractPlugIn plugin', () => {
139
144
  expect(subject().plugins).toContainEqual(
140
- new MiniCssExtractPlugin({ filename: '[name].bundle.css' })
145
+ new MiniCssExtractPlugin({
146
+ filename: '[name].bundle.css',
147
+ ...overrides.plugins?.MiniCssExtractPlugin,
148
+ })
141
149
  );
142
150
  });
143
151
 
@@ -245,6 +253,10 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
245
253
  <head>
246
254
  <meta name="viewport" content="width=device-width,initial-scale=1">
247
255
  ${headTags}
256
+ <script type="text/javascript">
257
+ /* Simulate host initialization */
258
+ window.onload = () => document.querySelector("${options!.name}")?.provide({ onReady() {}});
259
+ </script>
248
260
  </head>
249
261
  <body>
250
262
  <${options!.name} style-urls="${styleUrls}" />
@@ -34,10 +34,13 @@ export function htmlPlugin(
34
34
  <head>
35
35
  <meta name="viewport" content="width=device-width,initial-scale=1">
36
36
  ${headTags}
37
+ <script type="text/javascript">
38
+ /* Simulate host initialization */
39
+ window.onload = () => document.querySelector("${name}")?.provide({ onReady() {}});
40
+ </script>
37
41
  </head>
38
42
  <body>
39
43
  <${name} style-urls="${styleUrls}" />
40
-
41
44
  ${bodyTags}
42
45
  </body>
43
46
  </html>
@@ -5,14 +5,10 @@ export function miniCssExtractPlugin(context: Context, overrides: Overrides) {
5
5
  const { isCustomStyleRules, isExposeSharedDependencies, isProduction, isWebComponent } =
6
6
  context;
7
7
 
8
- if (isProduction) {
9
- if (!isCustomStyleRules) {
10
- return new MiniCssExtractPlugin({
11
- filename: '[name].[contenthash].bundle.css',
12
- ...(overrides.plugins as any)?.MiniCssExtractPlugin,
13
- });
14
- }
15
- } else if (isWebComponent || (isExposeSharedDependencies && !isCustomStyleRules)) {
16
- return new MiniCssExtractPlugin({ filename: '[name].bundle.css' });
8
+ if (!isCustomStyleRules && (isProduction || isWebComponent || isExposeSharedDependencies)) {
9
+ return new MiniCssExtractPlugin({
10
+ filename: isProduction ? '[name].[contenthash].bundle.css' : '[name].bundle.css',
11
+ ...overrides.plugins?.MiniCssExtractPlugin,
12
+ });
17
13
  }
18
14
  }