@servicetitan/startup 36.1.0 → 36.1.2-canary.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/cli/commands/coverage-finalize.d.ts +16 -0
  2. package/dist/cli/commands/coverage-finalize.d.ts.map +1 -0
  3. package/dist/cli/commands/coverage-finalize.js +41 -0
  4. package/dist/cli/commands/coverage-finalize.js.map +1 -0
  5. package/dist/cli/commands/registry/coverage-finalize.d.ts +5 -0
  6. package/dist/cli/commands/registry/coverage-finalize.d.ts.map +1 -0
  7. package/dist/cli/commands/registry/coverage-finalize.js +17 -0
  8. package/dist/cli/commands/registry/coverage-finalize.js.map +1 -0
  9. package/dist/cli/commands/test/runners/vitest.js +2 -4
  10. package/dist/cli/commands/test/runners/vitest.js.map +1 -1
  11. package/dist/cypress/config/webpack-config.d.ts.map +1 -1
  12. package/dist/cypress/config/webpack-config.js +28 -1
  13. package/dist/cypress/config/webpack-config.js.map +1 -1
  14. package/dist/utils/default-excludes.d.ts +14 -0
  15. package/dist/utils/default-excludes.d.ts.map +1 -0
  16. package/dist/utils/default-excludes.js +23 -0
  17. package/dist/utils/default-excludes.js.map +1 -0
  18. package/dist/utils/get-coverage-aliases.d.ts +23 -0
  19. package/dist/utils/get-coverage-aliases.d.ts.map +1 -0
  20. package/dist/utils/get-coverage-aliases.js +41 -0
  21. package/dist/utils/get-coverage-aliases.js.map +1 -0
  22. package/dist/utils/get-coverage-source-patterns.d.ts +21 -0
  23. package/dist/utils/get-coverage-source-patterns.d.ts.map +1 -0
  24. package/dist/utils/get-coverage-source-patterns.js +39 -0
  25. package/dist/utils/get-coverage-source-patterns.js.map +1 -0
  26. package/dist/utils/get-jest-config.js +3 -4
  27. package/dist/utils/get-jest-config.js.map +1 -1
  28. package/dist/utils/index.d.ts +1 -0
  29. package/dist/utils/index.d.ts.map +1 -1
  30. package/dist/utils/index.js +1 -0
  31. package/dist/utils/index.js.map +1 -1
  32. package/dist/webpack/configs/rules/js-rules.d.ts +1 -1
  33. package/dist/webpack/configs/rules/js-rules.d.ts.map +1 -1
  34. package/dist/webpack/configs/rules/js-rules.js +2 -11
  35. package/dist/webpack/configs/rules/js-rules.js.map +1 -1
  36. package/dist/webpack/configs/rules/ts-coverage-rules.d.ts +22 -0
  37. package/dist/webpack/configs/rules/ts-coverage-rules.d.ts.map +1 -0
  38. package/dist/webpack/configs/rules/ts-coverage-rules.js +48 -0
  39. package/dist/webpack/configs/rules/ts-coverage-rules.js.map +1 -0
  40. package/package.json +10 -11
  41. package/src/cli/commands/test/runners/__tests__/vitest.test.ts +10 -9
  42. package/src/cli/commands/test/runners/vitest.ts +3 -8
  43. package/src/cypress/config/__tests__/webpack-config.test.ts +28 -1
  44. package/src/cypress/config/webpack-config.ts +29 -4
  45. package/src/utils/__tests__/default-excludes.test.ts +25 -0
  46. package/src/utils/__tests__/get-jest-config.test.ts +6 -6
  47. package/src/utils/default-excludes.ts +24 -0
  48. package/src/utils/get-jest-config.ts +3 -3
  49. package/src/utils/index.ts +1 -0
  50. package/src/webpack/__tests__/create-webpack-config.test.ts +1 -2
  51. package/src/webpack/configs/rules/js-rules.ts +2 -4
@@ -0,0 +1,16 @@
1
+ import type { entry } from './registry/coverage-finalize';
2
+ import { Command } from './types';
3
+ /**
4
+ * Copies .nyc_output/out.json to coverage/coverage-final.json.
5
+ *
6
+ * The `publish-frontend-test-coverage` GHA workflow expects every test command
7
+ * to produce coverage/coverage-final.json so it can be uploaded as an artifact
8
+ * and merged with `npx nyc merge`.
9
+ *
10
+ * Run this after cypress component or e2e tests complete, instead of the
11
+ * manual `node scripts/remap-coverage.js && nyc report --reporter=json` steps.
12
+ */
13
+ export declare class CoverageFinalize extends Command<typeof entry> {
14
+ execute(): Promise<void>;
15
+ }
16
+ //# sourceMappingURL=coverage-finalize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coverage-finalize.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/coverage-finalize.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAKlC;;;;;;;;;GASG;AACH,qBAAa,gBAAiB,SAAQ,OAAO,CAAC,OAAO,KAAK,CAAC;IACjD,OAAO;CAiBhB"}
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "CoverageFinalize", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return CoverageFinalize;
9
+ }
10
+ });
11
+ const _nodefs = /*#__PURE__*/ _interop_require_default(require("node:fs"));
12
+ const _nodepath = /*#__PURE__*/ _interop_require_default(require("node:path"));
13
+ const _utils = require("../../utils");
14
+ const _types = require("./types");
15
+ function _interop_require_default(obj) {
16
+ return obj && obj.__esModule ? obj : {
17
+ default: obj
18
+ };
19
+ }
20
+ const INPUT_PATH = _nodepath.default.join('.nyc_output', 'out.json');
21
+ const OUTPUT_PATH = _nodepath.default.join('coverage', 'coverage-final.json');
22
+ class CoverageFinalize extends _types.Command {
23
+ async execute() {
24
+ if (!_nodefs.default.existsSync(INPUT_PATH)) {
25
+ _utils.log.error(`Coverage file not found: ${INPUT_PATH}`);
26
+ process.exit(1);
27
+ }
28
+ const outputDir = _nodepath.default.dirname(OUTPUT_PATH);
29
+ if (!_nodefs.default.existsSync(outputDir)) {
30
+ _nodefs.default.mkdirSync(outputDir, {
31
+ recursive: true
32
+ });
33
+ }
34
+ _nodefs.default.copyFileSync(INPUT_PATH, OUTPUT_PATH);
35
+ const data = JSON.parse(_nodefs.default.readFileSync(OUTPUT_PATH, 'utf8'));
36
+ const fileCount = Object.keys(data).length;
37
+ _utils.log.info(`Coverage finalized: ${fileCount} files → ${OUTPUT_PATH}`);
38
+ }
39
+ }
40
+
41
+ //# sourceMappingURL=coverage-finalize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/cli/commands/coverage-finalize.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport { log } from '../../utils';\nimport type { entry } from './registry/coverage-finalize';\nimport { Command } from './types';\n\nconst INPUT_PATH = path.join('.nyc_output', 'out.json');\nconst OUTPUT_PATH = path.join('coverage', 'coverage-final.json');\n\n/**\n * Copies .nyc_output/out.json to coverage/coverage-final.json.\n *\n * The `publish-frontend-test-coverage` GHA workflow expects every test command\n * to produce coverage/coverage-final.json so it can be uploaded as an artifact\n * and merged with `npx nyc merge`.\n *\n * Run this after cypress component or e2e tests complete, instead of the\n * manual `node scripts/remap-coverage.js && nyc report --reporter=json` steps.\n */\nexport class CoverageFinalize extends Command<typeof entry> {\n async execute() {\n if (!fs.existsSync(INPUT_PATH)) {\n log.error(`Coverage file not found: ${INPUT_PATH}`);\n process.exit(1);\n }\n\n const outputDir = path.dirname(OUTPUT_PATH);\n if (!fs.existsSync(outputDir)) {\n fs.mkdirSync(outputDir, { recursive: true });\n }\n\n fs.copyFileSync(INPUT_PATH, OUTPUT_PATH);\n\n const data = JSON.parse(fs.readFileSync(OUTPUT_PATH, 'utf8'));\n const fileCount = Object.keys(data).length;\n log.info(`Coverage finalized: ${fileCount} files → ${OUTPUT_PATH}`);\n }\n}\n"],"names":["CoverageFinalize","INPUT_PATH","path","join","OUTPUT_PATH","Command","execute","fs","existsSync","log","error","process","exit","outputDir","dirname","mkdirSync","recursive","copyFileSync","data","JSON","parse","readFileSync","fileCount","Object","keys","length","info"],"mappings":";;;;+BAmBaA;;;eAAAA;;;+DAnBE;iEACE;uBACG;uBAEI;;;;;;AAExB,MAAMC,aAAaC,iBAAI,CAACC,IAAI,CAAC,eAAe;AAC5C,MAAMC,cAAcF,iBAAI,CAACC,IAAI,CAAC,YAAY;AAYnC,MAAMH,yBAAyBK,cAAO;IACzC,MAAMC,UAAU;QACZ,IAAI,CAACC,eAAE,CAACC,UAAU,CAACP,aAAa;YAC5BQ,UAAG,CAACC,KAAK,CAAC,CAAC,yBAAyB,EAAET,YAAY;YAClDU,QAAQC,IAAI,CAAC;QACjB;QAEA,MAAMC,YAAYX,iBAAI,CAACY,OAAO,CAACV;QAC/B,IAAI,CAACG,eAAE,CAACC,UAAU,CAACK,YAAY;YAC3BN,eAAE,CAACQ,SAAS,CAACF,WAAW;gBAAEG,WAAW;YAAK;QAC9C;QAEAT,eAAE,CAACU,YAAY,CAAChB,YAAYG;QAE5B,MAAMc,OAAOC,KAAKC,KAAK,CAACb,eAAE,CAACc,YAAY,CAACjB,aAAa;QACrD,MAAMkB,YAAYC,OAAOC,IAAI,CAACN,MAAMO,MAAM;QAC1ChB,UAAG,CAACiB,IAAI,CAAC,CAAC,oBAAoB,EAAEJ,UAAU,SAAS,EAAElB,aAAa;IACtE;AACJ"}
@@ -0,0 +1,5 @@
1
+ export declare const entry: {
2
+ description: string;
3
+ allowRunFromGlobal: true;
4
+ };
5
+ //# sourceMappingURL=coverage-finalize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coverage-finalize.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/registry/coverage-finalize.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,KAAK;;;CAGhB,CAAC"}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "entry", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return entry;
9
+ }
10
+ });
11
+ const _defineentry = require("./define-entry");
12
+ const entry = (0, _defineentry.defineEntry)({
13
+ description: 'Write .nyc_output/out.json to coverage/coverage-final.json for CI collection',
14
+ allowRunFromGlobal: true
15
+ });
16
+
17
+ //# sourceMappingURL=coverage-finalize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/cli/commands/registry/coverage-finalize.ts"],"sourcesContent":["import { defineEntry } from './define-entry';\n\nexport const entry = defineEntry({\n description: 'Write .nyc_output/out.json to coverage/coverage-final.json for CI collection',\n allowRunFromGlobal: true,\n});\n"],"names":["entry","defineEntry","description","allowRunFromGlobal"],"mappings":";;;;+BAEaA;;;eAAAA;;;6BAFe;AAErB,MAAMA,QAAQC,IAAAA,wBAAW,EAAC;IAC7BC,aAAa;IACbC,oBAAoB;AACxB"}
@@ -49,9 +49,7 @@ function getDefaultConfig() {
49
49
  coverage: {
50
50
  exclude: [
51
51
  ..._config.coverageConfigDefaults.exclude,
52
- '**/__mocks__/**',
53
- '**/*.stories.*',
54
- '\\.yalc'
52
+ ...(0, _utils.getDefaultExcludes)()
55
53
  ],
56
54
  include: [
57
55
  '**/*.{ts,tsx}'
@@ -67,7 +65,7 @@ function getDefaultConfig() {
67
65
  environment: 'jsdom',
68
66
  exclude: [
69
67
  ..._config.configDefaults.exclude,
70
- '\\.yalc'
68
+ ...(0, _utils.getDefaultExcludes)()
71
69
  ],
72
70
  restoreMocks: true,
73
71
  server: {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/cli/commands/test/runners/vitest.ts"],"sourcesContent":["import { configDefaults, coverageConfigDefaults, mergeConfig, ViteUserConfig } from 'vitest/config';\nimport { parseCLI, resolveConfig, startVitest } 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;QAOPmC;IANJ,MAAM,EAAEA,UAAU,EAAE,GAAG,MAAMC,IAAAA,mBAAa;IAE1C,MAAM,EAAEC,cAAc,EAAE,EAAE,GAAGC,QAAQ,GAAGC,IAAAA,6BAAsB;IAE9D,MAAM7B,SAAS8B,IAAAA,mBAAW,EACtBA,IAAAA,mBAAW,EAACC,IAAAA,WAAI,EAAClB,oBAAoBc,cAAcC,UACnDH,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"}
1
+ {"version":3,"sources":["../../../../../src/cli/commands/test/runners/vitest.ts"],"sourcesContent":["import { configDefaults, coverageConfigDefaults, mergeConfig, ViteUserConfig } from 'vitest/config';\nimport { parseCLI, resolveConfig, startVitest } from 'vitest/node';\nimport { getDefaultExcludes, 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: [...coverageConfigDefaults.exclude, ...getDefaultExcludes()],\n include: ['**/*.{ts,tsx}'],\n reporter: ['html-spa', 'text', 'json', 'cobertura', 'lcov'],\n },\n environment: 'jsdom',\n exclude: [...configDefaults.exclude, ...getDefaultExcludes()],\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","getDefaultExcludes","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;uBACiB;uEAC3C;;;;;;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;mBAAIC,8BAAsB,CAACD,OAAO;mBAAKE,IAAAA,yBAAkB;aAAG;YACrEC,SAAS;gBAAC;aAAgB;YAC1BC,UAAU;gBAAC;gBAAY;gBAAQ;gBAAQ;gBAAa;aAAO;QAC/D;QACAC,aAAa;QACbL,SAAS;eAAIM,sBAAc,CAACN,OAAO;eAAKE,IAAAA,yBAAkB;SAAG;QAC7DK,cAAc;QACdC,QAAQ;YAAEC,MAAM;gBAAEC,QAAQ;oBAAC;iBAAuB;YAAC;QAAE;IACzD;AACJ;AAEA,eAAenC;QAOPoC;IANJ,MAAM,EAAEA,UAAU,EAAE,GAAG,MAAMC,IAAAA,mBAAa;IAE1C,MAAM,EAAEC,cAAc,EAAE,EAAE,GAAGC,QAAQ,GAAGC,IAAAA,6BAAsB;IAE9D,MAAM9B,SAAS+B,IAAAA,mBAAW,EACtBA,IAAAA,mBAAW,EAACC,IAAAA,WAAI,EAACnB,oBAAoBe,cAAcC,UACnDH,mBAAAA,WAAWO,IAAI,cAAfP,8BAAAA,mBAAmB,CAAC;IAGxB,oCAAoC,GACpCjB,UAAG,CAACC,KAAK,CAAC,qBAAqB,IAAMC,KAAKC,SAAS,CAACZ,QAAQ,MAAM;IAElE,MAAMkC,UAAkD;QAACC,IAAAA,uBAAc;KAAG,CAAC1C,MAAM,CAC7E,CAAC,EAAE2C,IAAI,EAAE,GAAK,CAACR,YAAYS,QAAQ,CAAC,CAAC,QAAQ,EAAED,MAAM;IAGzD,OAAO;QAAEH,MAAMjC;QAAQ,GAAIkC,QAAQI,MAAM,GAAG;YAAEJ;QAAQ,IAAI,CAAC,CAAC;IAAE;AAClE"}
@@ -1 +1 @@
1
- {"version":3,"file":"webpack-config.d.ts","sourceRoot":"","sources":["../../../src/cypress/config/webpack-config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAK7C,OAAO,EAAW,SAAS,EAAe,MAAM,uBAAuB,CAAC;AAExE,wBAAgB,aAAa,CAAC,SAAS,CAAC,EAAE,SAAS,GAAG,aAAa,CAiBlE"}
1
+ {"version":3,"file":"webpack-config.d.ts","sourceRoot":"","sources":["../../../src/cypress/config/webpack-config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAe,MAAM,SAAS,CAAC;AAK1D,OAAO,EAAW,SAAS,EAAe,MAAM,uBAAuB,CAAC;AAExE,wBAAgB,aAAa,CAAC,SAAS,CAAC,EAAE,SAAS,GAAG,aAAa,CAiBlE"}
@@ -45,6 +45,7 @@ function webpackConfig(overrides) {
45
45
  }
46
46
  function getContext() {
47
47
  return {
48
+ codeCoverage: true,
48
49
  destination: '',
49
50
  isProduction: false,
50
51
  name: '',
@@ -57,6 +58,7 @@ function getRules(context, overrides) {
57
58
  const { rules } = (0, _configs.rulesConfig)(context, overrides);
58
59
  return [
59
60
  getSwcLoaderRule(),
61
+ getSwcIstanbulRule(),
60
62
  ...rules
61
63
  ];
62
64
  }
@@ -65,12 +67,37 @@ function getSwcLoaderRule() {
65
67
  const swcOptions = (0, _tasks.getSwcOptions)(tsConfig);
66
68
  return {
67
69
  test: /\.tsx?$/,
68
- exclude: /node_modules/,
70
+ exclude: /(node_modules|\.yalc)/,
69
71
  use: {
70
72
  loader: 'swc-loader',
71
73
  options: swcOptions
72
74
  }
73
75
  };
74
76
  }
77
+ function getSwcIstanbulRule() {
78
+ return {
79
+ /*
80
+ * enforce: 'pre' ensures this loader runs BEFORE swc-loader, so istanbul
81
+ * instruments the original TypeScript source rather than compiled JS output.
82
+ * This means fnMap/statementMap positions reflect TypeScript line numbers,
83
+ * matching what Jest and Vitest produce.
84
+ * parserPlugins are required because istanbul-lib-instrument uses Babel
85
+ * internally, which cannot parse TypeScript syntax by default.
86
+ */ enforce: 'pre',
87
+ test: /\.tsx?$/,
88
+ exclude: /(node_modules|\.yalc)/,
89
+ use: {
90
+ loader: '@jsdevtools/coverage-istanbul-loader',
91
+ options: {
92
+ compact: false,
93
+ produceSourceMap: true,
94
+ parserPlugins: [
95
+ 'typescript',
96
+ 'jsx'
97
+ ]
98
+ }
99
+ }
100
+ };
101
+ }
75
102
 
76
103
  //# sourceMappingURL=webpack-config.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/cypress/config/webpack-config.ts"],"sourcesContent":["import { inspect } from 'node:util';\nimport type { Configuration } from 'webpack';\nimport merge from 'webpack-merge';\nimport { getSwcOptions } from '../../cli/tasks';\nimport { TSConfig } from '../../cli/utils';\nimport { getTsConfigWithFallback, log } from '../../utils';\nimport { Context, Overrides, rulesConfig } from '../../webpack/configs';\n\nexport function webpackConfig(overrides?: Overrides): Configuration {\n const context = getContext();\n const rules = getRules(context, overrides ?? {});\n\n /* istanbul ignore next: debug only */\n log.debug('cypress-config:webpack-config', () => inspect({ rules }, { depth: null }));\n\n const config: Configuration = {\n module: {\n rules,\n },\n resolve: {\n extensions: ['.ts', '.tsx', '.js', '.jsx'],\n },\n };\n\n return merge(config, overrides?.configuration ?? {});\n}\n\nfunction getContext(): Context {\n return {\n destination: '',\n isProduction: false,\n name: '',\n packageData: {} as any,\n sharedDependencies: {},\n source: '',\n };\n}\n\nfunction getRules(context: Context, overrides: Overrides) {\n const { rules } = rulesConfig(context, overrides);\n\n return [getSwcLoaderRule(), ...rules];\n}\n\nfunction getSwcLoaderRule() {\n const tsConfig = new TSConfig(getTsConfigWithFallback());\n\n const swcOptions = getSwcOptions(tsConfig);\n\n return {\n test: /\\.tsx?$/,\n exclude: /node_modules/,\n use: {\n loader: 'swc-loader',\n options: swcOptions,\n },\n };\n}\n"],"names":["webpackConfig","overrides","context","getContext","rules","getRules","log","debug","inspect","depth","config","module","resolve","extensions","merge","configuration","destination","isProduction","name","packageData","sharedDependencies","source","rulesConfig","getSwcLoaderRule","tsConfig","TSConfig","getTsConfigWithFallback","swcOptions","getSwcOptions","test","exclude","use","loader","options"],"mappings":";;;;+BAQgBA;;;eAAAA;;;0BARQ;qEAEN;uBACY;uBACL;wBACoB;yBACG;;;;;;AAEzC,SAASA,cAAcC,SAAqB;;IAC/C,MAAMC,UAAUC;IAChB,MAAMC,QAAQC,SAASH,SAASD,sBAAAA,uBAAAA,YAAa,CAAC;IAE9C,oCAAoC,GACpCK,WAAG,CAACC,KAAK,CAAC,iCAAiC,IAAMC,IAAAA,iBAAO,EAAC;YAAEJ;QAAM,GAAG;YAAEK,OAAO;QAAK;IAElF,MAAMC,SAAwB;QAC1BC,QAAQ;YACJP;QACJ;QACAQ,SAAS;YACLC,YAAY;gBAAC;gBAAO;gBAAQ;gBAAO;aAAO;QAC9C;IACJ;IAEA,OAAOC,IAAAA,qBAAK,EAACJ,gBAAQT,sBAAAA,gCAAAA,UAAWc,aAAa,uCAAI,CAAC;AACtD;AAEA,SAASZ;IACL,OAAO;QACHa,aAAa;QACbC,cAAc;QACdC,MAAM;QACNC,aAAa,CAAC;QACdC,oBAAoB,CAAC;QACrBC,QAAQ;IACZ;AACJ;AAEA,SAAShB,SAASH,OAAgB,EAAED,SAAoB;IACpD,MAAM,EAAEG,KAAK,EAAE,GAAGkB,IAAAA,oBAAW,EAACpB,SAASD;IAEvC,OAAO;QAACsB;WAAuBnB;KAAM;AACzC;AAEA,SAASmB;IACL,MAAMC,WAAW,IAAIC,eAAQ,CAACC,IAAAA,+BAAuB;IAErD,MAAMC,aAAaC,IAAAA,oBAAa,EAACJ;IAEjC,OAAO;QACHK,MAAM;QACNC,SAAS;QACTC,KAAK;YACDC,QAAQ;YACRC,SAASN;QACb;IACJ;AACJ"}
1
+ {"version":3,"sources":["../../../src/cypress/config/webpack-config.ts"],"sourcesContent":["import { inspect } from 'node:util';\nimport type { Configuration, RuleSetRule } from 'webpack';\nimport merge from 'webpack-merge';\nimport { getSwcOptions } from '../../cli/tasks';\nimport { TSConfig } from '../../cli/utils';\nimport { getTsConfigWithFallback, log } from '../../utils';\nimport { Context, Overrides, rulesConfig } from '../../webpack/configs';\n\nexport function webpackConfig(overrides?: Overrides): Configuration {\n const context = getContext();\n const rules = getRules(context, overrides ?? {});\n\n /* istanbul ignore next: debug only */\n log.debug('cypress-config:webpack-config', () => inspect({ rules }, { depth: null }));\n\n const config: Configuration = {\n module: {\n rules,\n },\n resolve: {\n extensions: ['.ts', '.tsx', '.js', '.jsx'],\n },\n };\n\n return merge(config, overrides?.configuration ?? {});\n}\n\nfunction getContext(): Context {\n return {\n codeCoverage: true,\n destination: '',\n isProduction: false,\n name: '',\n packageData: {} as any,\n sharedDependencies: {},\n source: '',\n };\n}\n\nfunction getRules(context: Context, overrides: Overrides) {\n const { rules } = rulesConfig(context, overrides);\n\n return [getSwcLoaderRule(), getSwcIstanbulRule(), ...rules];\n}\n\nfunction getSwcLoaderRule(): RuleSetRule {\n const tsConfig = new TSConfig(getTsConfigWithFallback());\n\n const swcOptions = getSwcOptions(tsConfig);\n\n return {\n test: /\\.tsx?$/,\n exclude: /(node_modules|\\.yalc)/,\n use: {\n loader: 'swc-loader',\n options: swcOptions,\n },\n };\n}\n\nfunction getSwcIstanbulRule(): RuleSetRule {\n return {\n /*\n * enforce: 'pre' ensures this loader runs BEFORE swc-loader, so istanbul\n * instruments the original TypeScript source rather than compiled JS output.\n * This means fnMap/statementMap positions reflect TypeScript line numbers,\n * matching what Jest and Vitest produce.\n * parserPlugins are required because istanbul-lib-instrument uses Babel\n * internally, which cannot parse TypeScript syntax by default.\n */\n enforce: 'pre',\n test: /\\.tsx?$/,\n exclude: /(node_modules|\\.yalc)/,\n use: {\n loader: '@jsdevtools/coverage-istanbul-loader',\n options: {\n compact: false,\n produceSourceMap: true,\n parserPlugins: ['typescript', 'jsx'],\n },\n },\n };\n}\n"],"names":["webpackConfig","overrides","context","getContext","rules","getRules","log","debug","inspect","depth","config","module","resolve","extensions","merge","configuration","codeCoverage","destination","isProduction","name","packageData","sharedDependencies","source","rulesConfig","getSwcLoaderRule","getSwcIstanbulRule","tsConfig","TSConfig","getTsConfigWithFallback","swcOptions","getSwcOptions","test","exclude","use","loader","options","enforce","compact","produceSourceMap","parserPlugins"],"mappings":";;;;+BAQgBA;;;eAAAA;;;0BARQ;qEAEN;uBACY;uBACL;wBACoB;yBACG;;;;;;AAEzC,SAASA,cAAcC,SAAqB;;IAC/C,MAAMC,UAAUC;IAChB,MAAMC,QAAQC,SAASH,SAASD,sBAAAA,uBAAAA,YAAa,CAAC;IAE9C,oCAAoC,GACpCK,WAAG,CAACC,KAAK,CAAC,iCAAiC,IAAMC,IAAAA,iBAAO,EAAC;YAAEJ;QAAM,GAAG;YAAEK,OAAO;QAAK;IAElF,MAAMC,SAAwB;QAC1BC,QAAQ;YACJP;QACJ;QACAQ,SAAS;YACLC,YAAY;gBAAC;gBAAO;gBAAQ;gBAAO;aAAO;QAC9C;IACJ;IAEA,OAAOC,IAAAA,qBAAK,EAACJ,gBAAQT,sBAAAA,gCAAAA,UAAWc,aAAa,uCAAI,CAAC;AACtD;AAEA,SAASZ;IACL,OAAO;QACHa,cAAc;QACdC,aAAa;QACbC,cAAc;QACdC,MAAM;QACNC,aAAa,CAAC;QACdC,oBAAoB,CAAC;QACrBC,QAAQ;IACZ;AACJ;AAEA,SAASjB,SAASH,OAAgB,EAAED,SAAoB;IACpD,MAAM,EAAEG,KAAK,EAAE,GAAGmB,IAAAA,oBAAW,EAACrB,SAASD;IAEvC,OAAO;QAACuB;QAAoBC;WAAyBrB;KAAM;AAC/D;AAEA,SAASoB;IACL,MAAME,WAAW,IAAIC,eAAQ,CAACC,IAAAA,+BAAuB;IAErD,MAAMC,aAAaC,IAAAA,oBAAa,EAACJ;IAEjC,OAAO;QACHK,MAAM;QACNC,SAAS;QACTC,KAAK;YACDC,QAAQ;YACRC,SAASN;QACb;IACJ;AACJ;AAEA,SAASJ;IACL,OAAO;QACH;;;;;;;SAOC,GACDW,SAAS;QACTL,MAAM;QACNC,SAAS;QACTC,KAAK;YACDC,QAAQ;YACRC,SAAS;gBACLE,SAAS;gBACTC,kBAAkB;gBAClBC,eAAe;oBAAC;oBAAc;iBAAM;YACxC;QACJ;IACJ;AACJ"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Returns default exclusions applied to both test running and coverage
3
+ * collection in Jest and Vitest.
4
+ *
5
+ * Patterns use regex syntax (for Jest testPathIgnorePatterns /
6
+ * coveragePathIgnorePatterns) and double as substring matches in Vitest's
7
+ * micromatch-based exclude / coverage.exclude.
8
+ *
9
+ * Destination folders (compiled output dirs from each package's tsconfig
10
+ * outDir) are included so that dist/ files are excluded from tests and
11
+ * coverage across all runners.
12
+ */
13
+ export declare function getDefaultExcludes(): string[];
14
+ //# sourceMappingURL=default-excludes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default-excludes.d.ts","sourceRoot":"","sources":["../../src/utils/default-excludes.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,EAAE,CAS7C"}
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "getDefaultExcludes", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return getDefaultExcludes;
9
+ }
10
+ });
11
+ const _getdestinationfolders = require("./get-destination-folders");
12
+ function getDefaultExcludes() {
13
+ return [
14
+ '__mocks__',
15
+ '\\.stories\\.',
16
+ '\\.yalc',
17
+ '\\.claude',
18
+ '\\.d\\.ts',
19
+ ...(0, _getdestinationfolders.getDestinationFolders)()
20
+ ];
21
+ }
22
+
23
+ //# sourceMappingURL=default-excludes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/default-excludes.ts"],"sourcesContent":["import { getDestinationFolders } from './get-destination-folders';\n\n/**\n * Returns default exclusions applied to both test running and coverage\n * collection in Jest and Vitest.\n *\n * Patterns use regex syntax (for Jest testPathIgnorePatterns /\n * coveragePathIgnorePatterns) and double as substring matches in Vitest's\n * micromatch-based exclude / coverage.exclude.\n *\n * Destination folders (compiled output dirs from each package's tsconfig\n * outDir) are included so that dist/ files are excluded from tests and\n * coverage across all runners.\n */\nexport function getDefaultExcludes(): string[] {\n return [\n '__mocks__',\n '\\\\.stories\\\\.',\n '\\\\.yalc',\n '\\\\.claude',\n '\\\\.d\\\\.ts',\n ...getDestinationFolders(),\n ];\n}\n"],"names":["getDefaultExcludes","getDestinationFolders"],"mappings":";;;;+BAcgBA;;;eAAAA;;;uCAdsB;AAc/B,SAASA;IACZ,OAAO;QACH;QACA;QACA;QACA;QACA;WACGC,IAAAA,4CAAqB;KAC3B;AACL"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Returns a webpack `resolve.alias` map that redirects workspace package imports
3
+ * to their TypeScript source directories when building with code coverage enabled.
4
+ *
5
+ * For each workspace package that declares a `main` entry point, this function:
6
+ * 1. Reads `compilerOptions.rootDir` from the package's tsconfig
7
+ * 2. Builds an alias from the package name to its resolved source root directory
8
+ *
9
+ * This ensures that the coverage-istanbul-loader instruments the original TypeScript
10
+ * source files (rather than compiled `dist/*.js` output), so coverage data contains
11
+ * correct `src/` file paths and TypeScript source positions — matching what jest and
12
+ * vitest produce.
13
+ *
14
+ * Only packages with both a `main` field and a tsconfig `compilerOptions.rootDir`
15
+ * are included. Packages without `main` (e.g. webpack bundle apps) are skipped
16
+ * since they are not imported by other packages and need no alias.
17
+ *
18
+ * Example: for a package `@scope/common` at `packages/common` with
19
+ * `tsconfig.json` containing `{ "compilerOptions": { "rootDir": "src" } }`,
20
+ * the returned alias is `{ "@scope/common": "/abs/path/packages/common/src" }`.
21
+ */
22
+ export declare function getCoverageAliases(): Record<string, string>;
23
+ //# sourceMappingURL=get-coverage-aliases.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-coverage-aliases.d.ts","sourceRoot":"","sources":["../../src/utils/get-coverage-aliases.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAuB3D"}
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "getCoverageAliases", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return getCoverageAliases;
9
+ }
10
+ });
11
+ const _nodefs = /*#__PURE__*/ _interop_require_default(require("node:fs"));
12
+ const _nodepath = /*#__PURE__*/ _interop_require_default(require("node:path"));
13
+ const _findpackages = require("./find-packages");
14
+ const _gettsconfig = require("./get-tsconfig");
15
+ const _readjson = require("./read-json");
16
+ function _interop_require_default(obj) {
17
+ return obj && obj.__esModule ? obj : {
18
+ default: obj
19
+ };
20
+ }
21
+ function getCoverageAliases() {
22
+ const packages = (0, _findpackages.findPackages)();
23
+ const aliases = {};
24
+ for (const pkg of packages){
25
+ var _tsConfig_compilerOptions;
26
+ // Only alias packages that are consumed as libraries (have a main entry point).
27
+ // Apps / webpack bundles have no main and are never imported by other packages.
28
+ if (!pkg.main) continue;
29
+ const tsConfigPath = (0, _gettsconfig.getTsConfig)(pkg.location);
30
+ if (!_nodefs.default.existsSync(tsConfigPath)) continue;
31
+ const tsConfig = (0, _readjson.readJsonSafe)(tsConfigPath);
32
+ const rootDir = tsConfig === null || tsConfig === void 0 ? void 0 : (_tsConfig_compilerOptions = tsConfig.compilerOptions) === null || _tsConfig_compilerOptions === void 0 ? void 0 : _tsConfig_compilerOptions.rootDir;
33
+ if (!rootDir) continue;
34
+ const srcDir = _nodepath.default.resolve(pkg.location, rootDir);
35
+ if (!_nodefs.default.existsSync(srcDir)) continue;
36
+ aliases[pkg.name] = srcDir;
37
+ }
38
+ return aliases;
39
+ }
40
+
41
+ //# sourceMappingURL=get-coverage-aliases.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/get-coverage-aliases.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport { findPackages } from './find-packages';\nimport { getTsConfig } from './get-tsconfig';\nimport { readJsonSafe } from './read-json';\n\n/**\n * Returns a webpack `resolve.alias` map that redirects workspace package imports\n * to their TypeScript source directories when building with code coverage enabled.\n *\n * For each workspace package that declares a `main` entry point, this function:\n * 1. Reads `compilerOptions.rootDir` from the package's tsconfig\n * 2. Builds an alias from the package name to its resolved source root directory\n *\n * This ensures that the coverage-istanbul-loader instruments the original TypeScript\n * source files (rather than compiled `dist/*.js` output), so coverage data contains\n * correct `src/` file paths and TypeScript source positions — matching what jest and\n * vitest produce.\n *\n * Only packages with both a `main` field and a tsconfig `compilerOptions.rootDir`\n * are included. Packages without `main` (e.g. webpack bundle apps) are skipped\n * since they are not imported by other packages and need no alias.\n *\n * Example: for a package `@scope/common` at `packages/common` with\n * `tsconfig.json` containing `{ \"compilerOptions\": { \"rootDir\": \"src\" } }`,\n * the returned alias is `{ \"@scope/common\": \"/abs/path/packages/common/src\" }`.\n */\nexport function getCoverageAliases(): Record<string, string> {\n const packages = findPackages();\n const aliases: Record<string, string> = {};\n\n for (const pkg of packages) {\n // Only alias packages that are consumed as libraries (have a main entry point).\n // Apps / webpack bundles have no main and are never imported by other packages.\n if (!pkg.main) continue;\n\n const tsConfigPath = getTsConfig(pkg.location);\n if (!fs.existsSync(tsConfigPath)) continue;\n\n const tsConfig = readJsonSafe<{ compilerOptions?: { rootDir?: string } }>(tsConfigPath);\n const rootDir = tsConfig?.compilerOptions?.rootDir;\n if (!rootDir) continue;\n\n const srcDir = path.resolve(pkg.location, rootDir);\n if (!fs.existsSync(srcDir)) continue;\n\n aliases[pkg.name] = srcDir;\n }\n\n return aliases;\n}\n"],"names":["getCoverageAliases","packages","findPackages","aliases","pkg","tsConfig","main","tsConfigPath","getTsConfig","location","fs","existsSync","readJsonSafe","rootDir","compilerOptions","srcDir","path","resolve","name"],"mappings":";;;;+BA2BgBA;;;eAAAA;;;+DA3BD;iEACE;8BACY;6BACD;0BACC;;;;;;AAuBtB,SAASA;IACZ,MAAMC,WAAWC,IAAAA,0BAAY;IAC7B,MAAMC,UAAkC,CAAC;IAEzC,KAAK,MAAMC,OAAOH,SAAU;YASRI;QARhB,gFAAgF;QAChF,gFAAgF;QAChF,IAAI,CAACD,IAAIE,IAAI,EAAE;QAEf,MAAMC,eAAeC,IAAAA,wBAAW,EAACJ,IAAIK,QAAQ;QAC7C,IAAI,CAACC,eAAE,CAACC,UAAU,CAACJ,eAAe;QAElC,MAAMF,WAAWO,IAAAA,sBAAY,EAA6CL;QAC1E,MAAMM,UAAUR,qBAAAA,gCAAAA,4BAAAA,SAAUS,eAAe,cAAzBT,gDAAAA,0BAA2BQ,OAAO;QAClD,IAAI,CAACA,SAAS;QAEd,MAAME,SAASC,iBAAI,CAACC,OAAO,CAACb,IAAIK,QAAQ,EAAEI;QAC1C,IAAI,CAACH,eAAE,CAACC,UAAU,CAACI,SAAS;QAE5BZ,OAAO,CAACC,IAAIc,IAAI,CAAC,GAAGH;IACxB;IAEA,OAAOZ;AACX"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Returns glob patterns scoped to each workspace package's source directory,
3
+ * suitable for use as `collectCoverageFrom` (Jest) or `coverage.include` (Vitest).
4
+ *
5
+ * The source directory is read from `compilerOptions.rootDir` in each package's
6
+ * tsconfig rather than assumed to be `src/`, since rootDir is configurable.
7
+ * Falls back to `src` if no rootDir is found.
8
+ *
9
+ * Patterns are relative to `process.cwd()` (the project root). For a workspace
10
+ * whose resolved location is `/root/packages/application` with rootDir `src`,
11
+ * the returned pattern is `packages/application/src/**\/*.{ts,tsx}`.
12
+ *
13
+ * This avoids collecting coverage for unrelated files such as `.yalc/`,
14
+ * `node_modules/`, config files in the repo root, `.storybook/`, etc.
15
+ *
16
+ * If no workspace packages are found (e.g. a single-package repo without a
17
+ * workspaces config) the function falls back to `['**\/*.{ts,tsx}']` so that
18
+ * coverage collection still works.
19
+ */
20
+ export declare function getCoverageSourcePatterns(): string[];
21
+ //# sourceMappingURL=get-coverage-source-patterns.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-coverage-source-patterns.d.ts","sourceRoot":"","sources":["../../src/utils/get-coverage-source-patterns.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,EAAE,CAiBpD"}
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "getCoverageSourcePatterns", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return getCoverageSourcePatterns;
9
+ }
10
+ });
11
+ const _nodefs = /*#__PURE__*/ _interop_require_default(require("node:fs"));
12
+ const _path = /*#__PURE__*/ _interop_require_default(require("path"));
13
+ const _findpackages = require("./find-packages");
14
+ const _gettsconfig = require("./get-tsconfig");
15
+ const _readjson = require("./read-json");
16
+ function _interop_require_default(obj) {
17
+ return obj && obj.__esModule ? obj : {
18
+ default: obj
19
+ };
20
+ }
21
+ function getCoverageSourcePatterns() {
22
+ const packages = (0, _findpackages.findPackages)();
23
+ if (packages.length === 0) {
24
+ return [
25
+ '**/*.{ts,tsx}'
26
+ ];
27
+ }
28
+ return packages.map((pkg)=>{
29
+ var _ref;
30
+ var _tsConfig_compilerOptions;
31
+ const tsConfigPath = (0, _gettsconfig.getTsConfig)(pkg.location);
32
+ const tsConfig = _nodefs.default.existsSync(tsConfigPath) ? (0, _readjson.readJsonSafe)(tsConfigPath) : undefined;
33
+ const rootDir = (_ref = tsConfig === null || tsConfig === void 0 ? void 0 : (_tsConfig_compilerOptions = tsConfig.compilerOptions) === null || _tsConfig_compilerOptions === void 0 ? void 0 : _tsConfig_compilerOptions.rootDir) !== null && _ref !== void 0 ? _ref : 'src';
34
+ const rel = _path.default.relative(process.cwd(), pkg.location).replace(/\\/g, '/');
35
+ return `${rel}/${rootDir}/**/*.{ts,tsx}`;
36
+ });
37
+ }
38
+
39
+ //# sourceMappingURL=get-coverage-source-patterns.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/get-coverage-source-patterns.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'path';\nimport { findPackages } from './find-packages';\nimport { getTsConfig } from './get-tsconfig';\nimport { readJsonSafe } from './read-json';\n\n/**\n * Returns glob patterns scoped to each workspace package's source directory,\n * suitable for use as `collectCoverageFrom` (Jest) or `coverage.include` (Vitest).\n *\n * The source directory is read from `compilerOptions.rootDir` in each package's\n * tsconfig rather than assumed to be `src/`, since rootDir is configurable.\n * Falls back to `src` if no rootDir is found.\n *\n * Patterns are relative to `process.cwd()` (the project root). For a workspace\n * whose resolved location is `/root/packages/application` with rootDir `src`,\n * the returned pattern is `packages/application/src/**\\/*.{ts,tsx}`.\n *\n * This avoids collecting coverage for unrelated files such as `.yalc/`,\n * `node_modules/`, config files in the repo root, `.storybook/`, etc.\n *\n * If no workspace packages are found (e.g. a single-package repo without a\n * workspaces config) the function falls back to `['**\\/*.{ts,tsx}']` so that\n * coverage collection still works.\n */\nexport function getCoverageSourcePatterns(): string[] {\n const packages = findPackages();\n\n if (packages.length === 0) {\n return ['**/*.{ts,tsx}'];\n }\n\n return packages.map(pkg => {\n const tsConfigPath = getTsConfig(pkg.location);\n const tsConfig = fs.existsSync(tsConfigPath)\n ? readJsonSafe<{ compilerOptions?: { rootDir?: string } }>(tsConfigPath)\n : undefined;\n const rootDir = tsConfig?.compilerOptions?.rootDir ?? 'src';\n\n const rel = path.relative(process.cwd(), pkg.location).replace(/\\\\/g, '/');\n return `${rel}/${rootDir}/**/*.{ts,tsx}`;\n });\n}\n"],"names":["getCoverageSourcePatterns","packages","findPackages","length","map","pkg","tsConfig","tsConfigPath","getTsConfig","location","fs","existsSync","readJsonSafe","undefined","rootDir","compilerOptions","rel","path","relative","process","cwd","replace"],"mappings":";;;;+BAyBgBA;;;eAAAA;;;+DAzBD;6DACE;8BACY;6BACD;0BACC;;;;;;AAqBtB,SAASA;IACZ,MAAMC,WAAWC,IAAAA,0BAAY;IAE7B,IAAID,SAASE,MAAM,KAAK,GAAG;QACvB,OAAO;YAAC;SAAgB;IAC5B;IAEA,OAAOF,SAASG,GAAG,CAACC,CAAAA;;YAKAC;QAJhB,MAAMC,eAAeC,IAAAA,wBAAW,EAACH,IAAII,QAAQ;QAC7C,MAAMH,WAAWI,eAAE,CAACC,UAAU,CAACJ,gBACzBK,IAAAA,sBAAY,EAA6CL,gBACzDM;QACN,MAAMC,kBAAUR,qBAAAA,gCAAAA,4BAAAA,SAAUS,eAAe,cAAzBT,gDAAAA,0BAA2BQ,OAAO,uCAAI;QAEtD,MAAME,MAAMC,aAAI,CAACC,QAAQ,CAACC,QAAQC,GAAG,IAAIf,IAAII,QAAQ,EAAEY,OAAO,CAAC,OAAO;QACtE,OAAO,GAAGL,IAAI,CAAC,EAAEF,QAAQ,cAAc,CAAC;IAC5C;AACJ"}
@@ -9,8 +9,8 @@ Object.defineProperty(exports, "getJestConfigCLI", {
9
9
  }
10
10
  });
11
11
  const _path = /*#__PURE__*/ _interop_require_default(require("path"));
12
+ const _defaultexcludes = require("./default-excludes");
12
13
  const _getconfiguration = require("./get-configuration");
13
- const _getdestinationfolders = require("./get-destination-folders");
14
14
  const _omit = require("./omit");
15
15
  const _toarray = require("./to-array");
16
16
  function _interop_require_default(obj) {
@@ -27,7 +27,7 @@ function getDefaultJestConfiguration() {
27
27
  '**/*.{ts,tsx}'
28
28
  ],
29
29
  coveragePathIgnorePatterns: [
30
- '^.+\\.d\\.ts$'
30
+ ...(0, _defaultexcludes.getDefaultExcludes)()
31
31
  ],
32
32
  coverageReporters: [
33
33
  'html-spa',
@@ -47,8 +47,7 @@ function getDefaultJestConfiguration() {
47
47
  ],
48
48
  testEnvironment: 'jsdom',
49
49
  testPathIgnorePatterns: [
50
- '\\.yalc',
51
- ...(0, _getdestinationfolders.getDestinationFolders)()
50
+ ...(0, _defaultexcludes.getDefaultExcludes)()
52
51
  ],
53
52
  testRunner: 'jest-circus/runner',
54
53
  transformIgnorePatterns: [
@@ -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 { omit } from './omit';\nimport { toArray } from './to-array';\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 const reporters: string[] | undefined =\n typeof config.reporters === 'string' ? [config.reporters] : config.reporters;\n\n return stringifyForCLI({\n ...mergeArrayValues(defaultConfig, {\n coveragePathIgnorePatterns,\n setupFiles,\n testPathIgnorePatterns,\n }),\n ...config,\n ...(moduleNameMapper ? { moduleNameMapper } : {}),\n ...(reporters ? { reporters } : {}),\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","reporters","stringifyForCLI","mergeArrayValues","arrayValues","Object","keys","reduce","result","key","newValue","toArray","value","stringify"],"mappings":";;;;+BAoCgBA;;;eAAAA;;;6DAnCC;kCACoB;uCACC;sBACjB;yBACG;;;;;;AAExB,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,MAAMyB,YACF,OAAON,OAAOM,SAAS,KAAK,WAAW;QAACN,OAAOM,SAAS;KAAC,GAAGN,OAAOM,SAAS;IAEhF,OAAOC,gBAAgB;QACnB,GAAGC,iBAAiBN,eAAe;YAC/BnB;YACAQ;YACAE;QACJ,EAAE;QACF,GAAGO,MAAM;QACT,GAAInB,mBAAmB;YAAEA;QAAiB,IAAI,CAAC,CAAC;QAChD,GAAIyB,YAAY;YAAEA;QAAU,IAAI,CAAC,CAAC;IACtC;AACJ;AAEA,SAASE,iBACLR,MAAW,EACXS,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,GAAGb;AACP;AAEA,SAASO,gBAAgBP,MAAW;IAChC,OAAO;QAAC;QAAuB;QAAW;QAAoB;KAAY,CAACY,MAAM,CAC7E,CAACC,QAAQC;QACL,MAAMG,QAAQJ,MAAM,CAACC,IAAI;QACzB,IAAIG,SAAS,OAAOA,UAAU,UAAU;YACpCJ,MAAM,CAACC,IAAI,GAAGV,KAAKc,SAAS,CAACL,MAAM,CAACC,IAAI;QAC5C;QACA,OAAOD;IACX,GACAb;AAER"}
1
+ {"version":3,"sources":["../../src/utils/get-jest-config.ts"],"sourcesContent":["import { Config } from '@jest/types';\nimport path from 'path';\nimport { getDefaultExcludes } from './default-excludes';\nimport { getJestConfiguration } from './get-configuration';\nimport { omit } from './omit';\nimport { toArray } from './to-array';\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: [...getDefaultExcludes()],\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: [...getDefaultExcludes()],\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 const reporters: string[] | undefined =\n typeof config.reporters === 'string' ? [config.reporters] : config.reporters;\n\n return stringifyForCLI({\n ...mergeArrayValues(defaultConfig, {\n coveragePathIgnorePatterns,\n setupFiles,\n testPathIgnorePatterns,\n }),\n ...config,\n ...(moduleNameMapper ? { moduleNameMapper } : {}),\n ...(reporters ? { reporters } : {}),\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","getDefaultExcludes","coverageReporters","modulePathIgnorePatterns","preset","path","join","__dirname","resolver","setupFiles","testEnvironment","testPathIgnorePatterns","testRunner","transformIgnorePatterns","verbose","args","omitDefault","config","getJestConfiguration","defaultConfig","omit","JSON","parse","reporters","stringifyForCLI","mergeArrayValues","arrayValues","Object","keys","reduce","result","key","newValue","toArray","value","stringify"],"mappings":";;;;+BAoCgBA;;;eAAAA;;;6DAnCC;iCACkB;kCACE;sBAChB;yBACG;;;;;;AAExB,SAASC;IACL,MAAMC,mBAAmB;QACrB,+DAA+D;IACnE;IAEA,OAAO;QACHC,qBAAqB;YAAC;SAAgB;QACtCC,4BAA4B;eAAIC,IAAAA,mCAAkB;SAAG;QACrDC,mBAAmB;YAAC;YAAY;YAAQ;YAAQ;YAAa;SAAO;QACpEJ;QACAK,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;eAAIV,IAAAA,mCAAkB;SAAG;QACjDW,YAAY;QACZC,yBAAyB;YAAC;SAA6D;QACvFC,SAAS;IACb;AAKJ;AAKO,SAASlB,iBAAiBmB,IAAiB;IAC9C,MAAM,EACFf,0BAA0B,EAC1BgB,cAAc,EAAE,EAChBP,UAAU,EACVE,sBAAsB,EACtB,GAAGM,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,MAAMyB,YACF,OAAON,OAAOM,SAAS,KAAK,WAAW;QAACN,OAAOM,SAAS;KAAC,GAAGN,OAAOM,SAAS;IAEhF,OAAOC,gBAAgB;QACnB,GAAGC,iBAAiBN,eAAe;YAC/BnB;YACAS;YACAE;QACJ,EAAE;QACF,GAAGM,MAAM;QACT,GAAInB,mBAAmB;YAAEA;QAAiB,IAAI,CAAC,CAAC;QAChD,GAAIyB,YAAY;YAAEA;QAAU,IAAI,CAAC,CAAC;IACtC;AACJ;AAEA,SAASE,iBACLR,MAAW,EACXS,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,GAAGb;AACP;AAEA,SAASO,gBAAgBP,MAAW;IAChC,OAAO;QAAC;QAAuB;QAAW;QAAoB;KAAY,CAACY,MAAM,CAC7E,CAACC,QAAQC;QACL,MAAMG,QAAQJ,MAAM,CAACC,IAAI;QACzB,IAAIG,SAAS,OAAOA,UAAU,UAAU;YACpCJ,MAAM,CAACC,IAAI,GAAGV,KAAKc,SAAS,CAACL,MAAM,CAACC,IAAI;QAC5C;QACA,OAAOD;IACX,GACAb;AAER"}
@@ -1,3 +1,4 @@
1
+ export * from './default-excludes';
1
2
  export * from './find-packages';
2
3
  export * from './find-up';
3
4
  export * from './format-duration';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,OAAO,CAAC;AACtB,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,OAAO,CAAC;AACtB,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
+ _export_star(require("./default-excludes"), exports);
5
6
  _export_star(require("./find-packages"), exports);
6
7
  _export_star(require("./find-up"), exports);
7
8
  _export_star(require("./format-duration"), exports);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/index.ts"],"sourcesContent":["export * from './find-packages';\nexport * from './find-up';\nexport * from './format-duration';\nexport * from './format-relative-date';\nexport * from './get-base-tsconfig';\nexport * from './get-branch-configs';\nexport * from './get-configuration';\nexport * from './get-destination-folders';\nexport * from './get-folders';\nexport * from './get-jest-config';\nexport * from './get-package-data';\nexport * from './get-package-name';\nexport * from './get-packages';\nexport * from './get-startup-version';\nexport * from './get-tsconfig';\nexport * from './get-tsconfig-with-fallback';\nexport * from './load-shared-dependencies';\nexport * from './log';\nexport * from './log-errors';\nexport * from './omit';\nexport * from './pick';\nexport * from './prettify';\nexport * from './read-json';\nexport * from './to-array';\n"],"names":[],"mappings":";;;;qBAAc;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA"}
1
+ {"version":3,"sources":["../../src/utils/index.ts"],"sourcesContent":["export * from './default-excludes';\nexport * from './find-packages';\nexport * from './find-up';\nexport * from './format-duration';\nexport * from './format-relative-date';\nexport * from './get-base-tsconfig';\nexport * from './get-branch-configs';\nexport * from './get-configuration';\nexport * from './get-destination-folders';\nexport * from './get-folders';\nexport * from './get-jest-config';\nexport * from './get-package-data';\nexport * from './get-package-name';\nexport * from './get-packages';\nexport * from './get-startup-version';\nexport * from './get-tsconfig';\nexport * from './get-tsconfig-with-fallback';\nexport * from './load-shared-dependencies';\nexport * from './log';\nexport * from './log-errors';\nexport * from './omit';\nexport * from './pick';\nexport * from './prettify';\nexport * from './read-json';\nexport * from './to-array';\n"],"names":[],"mappings":";;;;qBAAc;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA"}
@@ -1,4 +1,4 @@
1
1
  import { RuleSetRule } from 'webpack';
2
2
  import { Context } from '../types';
3
- export declare function jsRules({ codeCoverage, destination }: Context): RuleSetRule[];
3
+ export declare function jsRules({ codeCoverage }: Context): RuleSetRule[];
4
4
  //# sourceMappingURL=js-rules.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"js-rules.d.ts","sourceRoot":"","sources":["../../../../src/webpack/configs/rules/js-rules.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAEnC,wBAAgB,OAAO,CAAC,EAAE,YAAY,EAAE,WAAW,EAAE,EAAE,OAAO,GAAG,WAAW,EAAE,CAqC7E"}
1
+ {"version":3,"file":"js-rules.d.ts","sourceRoot":"","sources":["../../../../src/webpack/configs/rules/js-rules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAEnC,wBAAgB,OAAO,CAAC,EAAE,YAAY,EAAE,EAAE,OAAO,GAAG,WAAW,EAAE,CAoChE"}
@@ -8,13 +8,7 @@ Object.defineProperty(exports, "jsRules", {
8
8
  return jsRules;
9
9
  }
10
10
  });
11
- const _path = /*#__PURE__*/ _interop_require_default(require("path"));
12
- function _interop_require_default(obj) {
13
- return obj && obj.__esModule ? obj : {
14
- default: obj
15
- };
16
- }
17
- function jsRules({ codeCoverage, destination }) {
11
+ function jsRules({ codeCoverage }) {
18
12
  const result = [
19
13
  {
20
14
  enforce: 'pre',
@@ -39,10 +33,7 @@ function jsRules({ codeCoverage, destination }) {
39
33
  result.push({
40
34
  enforce: 'post',
41
35
  test: /\.js$/,
42
- include: [
43
- _path.default.resolve(destination)
44
- ],
45
- exclude: /node_modules/,
36
+ exclude: /(node_modules|\.yalc)/,
46
37
  use: {
47
38
  loader: '@jsdevtools/coverage-istanbul-loader',
48
39
  options: {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/webpack/configs/rules/js-rules.ts"],"sourcesContent":["import path from 'path';\nimport { RuleSetRule } from 'webpack';\nimport { Context } from '../types';\n\nexport function jsRules({ codeCoverage, destination }: Context): RuleSetRule[] {\n const result: RuleSetRule[] = [\n {\n enforce: 'pre',\n test: /\\.js$/,\n exclude: /node_modules/,\n loader: 'source-map-loader',\n },\n {\n test: /\\.js$/,\n resolve: {\n fullySpecified: false,\n },\n },\n {\n test: /\\.worker\\.js$/,\n use: { loader: 'worker-loader' },\n },\n ];\n\n if (codeCoverage) {\n result.push({\n enforce: 'post',\n test: /\\.js$/,\n include: [path.resolve(destination)],\n exclude: /node_modules/,\n use: {\n loader: '@jsdevtools/coverage-istanbul-loader',\n options: {\n compact: false,\n produceSourceMap: true,\n },\n },\n });\n }\n\n return result;\n}\n"],"names":["jsRules","codeCoverage","destination","result","enforce","test","exclude","loader","resolve","fullySpecified","use","push","include","path","options","compact","produceSourceMap"],"mappings":";;;;+BAIgBA;;;eAAAA;;;6DAJC;;;;;;AAIV,SAASA,QAAQ,EAAEC,YAAY,EAAEC,WAAW,EAAW;IAC1D,MAAMC,SAAwB;QAC1B;YACIC,SAAS;YACTC,MAAM;YACNC,SAAS;YACTC,QAAQ;QACZ;QACA;YACIF,MAAM;YACNG,SAAS;gBACLC,gBAAgB;YACpB;QACJ;QACA;YACIJ,MAAM;YACNK,KAAK;gBAAEH,QAAQ;YAAgB;QACnC;KACH;IAED,IAAIN,cAAc;QACdE,OAAOQ,IAAI,CAAC;YACRP,SAAS;YACTC,MAAM;YACNO,SAAS;gBAACC,aAAI,CAACL,OAAO,CAACN;aAAa;YACpCI,SAAS;YACTI,KAAK;gBACDH,QAAQ;gBACRO,SAAS;oBACLC,SAAS;oBACTC,kBAAkB;gBACtB;YACJ;QACJ;IACJ;IAEA,OAAOb;AACX"}
1
+ {"version":3,"sources":["../../../../src/webpack/configs/rules/js-rules.ts"],"sourcesContent":["import { RuleSetRule } from 'webpack';\nimport { Context } from '../types';\n\nexport function jsRules({ codeCoverage }: Context): RuleSetRule[] {\n const result: RuleSetRule[] = [\n {\n enforce: 'pre',\n test: /\\.js$/,\n exclude: /node_modules/,\n loader: 'source-map-loader',\n },\n {\n test: /\\.js$/,\n resolve: {\n fullySpecified: false,\n },\n },\n {\n test: /\\.worker\\.js$/,\n use: { loader: 'worker-loader' },\n },\n ];\n\n if (codeCoverage) {\n result.push({\n enforce: 'post',\n test: /\\.js$/,\n exclude: /(node_modules|\\.yalc)/,\n use: {\n loader: '@jsdevtools/coverage-istanbul-loader',\n options: {\n compact: false,\n produceSourceMap: true,\n },\n },\n });\n }\n\n return result;\n}\n"],"names":["jsRules","codeCoverage","result","enforce","test","exclude","loader","resolve","fullySpecified","use","push","options","compact","produceSourceMap"],"mappings":";;;;+BAGgBA;;;eAAAA;;;AAAT,SAASA,QAAQ,EAAEC,YAAY,EAAW;IAC7C,MAAMC,SAAwB;QAC1B;YACIC,SAAS;YACTC,MAAM;YACNC,SAAS;YACTC,QAAQ;QACZ;QACA;YACIF,MAAM;YACNG,SAAS;gBACLC,gBAAgB;YACpB;QACJ;QACA;YACIJ,MAAM;YACNK,KAAK;gBAAEH,QAAQ;YAAgB;QACnC;KACH;IAED,IAAIL,cAAc;QACdC,OAAOQ,IAAI,CAAC;YACRP,SAAS;YACTC,MAAM;YACNC,SAAS;YACTI,KAAK;gBACDH,QAAQ;gBACRK,SAAS;oBACLC,SAAS;oBACTC,kBAAkB;gBACtB;YACJ;QACJ;IACJ;IAEA,OAAOX;AACX"}
@@ -0,0 +1,22 @@
1
+ import type { RuleSetRule } from 'webpack';
2
+ import { Context } from '../types';
3
+ /**
4
+ * Webpack rules for TypeScript source files when building with code coverage.
5
+ *
6
+ * Normally the main webpack build only processes pre-compiled `.js` files
7
+ * (TypeScript is compiled to JS before webpack runs). When code coverage is
8
+ * enabled, workspace package imports are aliased from their `dist/` output to
9
+ * their `src/` TypeScript source (via `resolve.alias` in `resolve-config.ts`),
10
+ * so webpack now encounters raw `.ts`/`.tsx` files that need a compiler.
11
+ *
12
+ * Processing order for `.ts`/`.tsx` files:
13
+ * 1. `coverage-istanbul-loader` (`enforce: 'pre'`) — instruments the original
14
+ * TypeScript source, recording fnMap/statementMap positions from the TS AST.
15
+ * `parserPlugins: ['typescript', 'jsx']` lets babel parse TypeScript syntax.
16
+ * 2. `swc-loader` (normal) — compiles the instrumented TypeScript to JavaScript.
17
+ *
18
+ * This mirrors the cypress component test webpack config, ensuring e2e coverage
19
+ * uses the same instrumentation strategy and produces matching source positions.
20
+ */
21
+ export declare function tsCoverageRules({ codeCoverage }: Context): RuleSetRule[];
22
+ //# sourceMappingURL=ts-coverage-rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ts-coverage-rules.d.ts","sourceRoot":"","sources":["../../../../src/webpack/configs/rules/ts-coverage-rules.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAI3C,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAEnC;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAAC,EAAE,YAAY,EAAE,EAAE,OAAO,GAAG,WAAW,EAAE,CA+BxE"}
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "tsCoverageRules", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return tsCoverageRules;
9
+ }
10
+ });
11
+ const _tasks = require("../../../cli/tasks");
12
+ const _utils = require("../../../cli/utils");
13
+ const _utils1 = require("../../../utils");
14
+ function tsCoverageRules({ codeCoverage }) {
15
+ if (!codeCoverage) {
16
+ return [];
17
+ }
18
+ const tsConfig = new _utils.TSConfig((0, _utils1.getTsConfigWithFallback)());
19
+ const swcOptions = (0, _tasks.getSwcOptions)(tsConfig);
20
+ return [
21
+ {
22
+ test: /\.tsx?$/,
23
+ exclude: /(node_modules|\.yalc)/,
24
+ use: {
25
+ loader: 'swc-loader',
26
+ options: swcOptions
27
+ }
28
+ },
29
+ {
30
+ enforce: 'pre',
31
+ test: /\.tsx?$/,
32
+ exclude: /(node_modules|\.yalc)/,
33
+ use: {
34
+ loader: '@jsdevtools/coverage-istanbul-loader',
35
+ options: {
36
+ compact: false,
37
+ produceSourceMap: true,
38
+ parserPlugins: [
39
+ 'typescript',
40
+ 'jsx'
41
+ ]
42
+ }
43
+ }
44
+ }
45
+ ];
46
+ }
47
+
48
+ //# sourceMappingURL=ts-coverage-rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/webpack/configs/rules/ts-coverage-rules.ts"],"sourcesContent":["import type { RuleSetRule } from 'webpack';\nimport { getSwcOptions } from '../../../cli/tasks';\nimport { TSConfig } from '../../../cli/utils';\nimport { getTsConfigWithFallback } from '../../../utils';\nimport { Context } from '../types';\n\n/**\n * Webpack rules for TypeScript source files when building with code coverage.\n *\n * Normally the main webpack build only processes pre-compiled `.js` files\n * (TypeScript is compiled to JS before webpack runs). When code coverage is\n * enabled, workspace package imports are aliased from their `dist/` output to\n * their `src/` TypeScript source (via `resolve.alias` in `resolve-config.ts`),\n * so webpack now encounters raw `.ts`/`.tsx` files that need a compiler.\n *\n * Processing order for `.ts`/`.tsx` files:\n * 1. `coverage-istanbul-loader` (`enforce: 'pre'`) — instruments the original\n * TypeScript source, recording fnMap/statementMap positions from the TS AST.\n * `parserPlugins: ['typescript', 'jsx']` lets babel parse TypeScript syntax.\n * 2. `swc-loader` (normal) — compiles the instrumented TypeScript to JavaScript.\n *\n * This mirrors the cypress component test webpack config, ensuring e2e coverage\n * uses the same instrumentation strategy and produces matching source positions.\n */\nexport function tsCoverageRules({ codeCoverage }: Context): RuleSetRule[] {\n if (!codeCoverage) {\n return [];\n }\n\n const tsConfig = new TSConfig(getTsConfigWithFallback());\n const swcOptions = getSwcOptions(tsConfig);\n\n return [\n {\n test: /\\.tsx?$/,\n exclude: /(node_modules|\\.yalc)/,\n use: {\n loader: 'swc-loader',\n options: swcOptions,\n },\n },\n {\n enforce: 'pre',\n test: /\\.tsx?$/,\n exclude: /(node_modules|\\.yalc)/,\n use: {\n loader: '@jsdevtools/coverage-istanbul-loader',\n options: {\n compact: false,\n produceSourceMap: true,\n parserPlugins: ['typescript', 'jsx'],\n },\n },\n },\n ];\n}\n"],"names":["tsCoverageRules","codeCoverage","tsConfig","TSConfig","getTsConfigWithFallback","swcOptions","getSwcOptions","test","exclude","use","loader","options","enforce","compact","produceSourceMap","parserPlugins"],"mappings":";;;;+BAwBgBA;;;eAAAA;;;uBAvBc;uBACL;wBACe;AAqBjC,SAASA,gBAAgB,EAAEC,YAAY,EAAW;IACrD,IAAI,CAACA,cAAc;QACf,OAAO,EAAE;IACb;IAEA,MAAMC,WAAW,IAAIC,eAAQ,CAACC,IAAAA,+BAAuB;IACrD,MAAMC,aAAaC,IAAAA,oBAAa,EAACJ;IAEjC,OAAO;QACH;YACIK,MAAM;YACNC,SAAS;YACTC,KAAK;gBACDC,QAAQ;gBACRC,SAASN;YACb;QACJ;QACA;YACIO,SAAS;YACTL,MAAM;YACNC,SAAS;YACTC,KAAK;gBACDC,QAAQ;gBACRC,SAAS;oBACLE,SAAS;oBACTC,kBAAkB;oBAClBC,eAAe;wBAAC;wBAAc;qBAAM;gBACxC;YACJ;QACJ;KACH;AACL"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@servicetitan/startup",
3
- "version": "36.1.0",
3
+ "version": "36.1.2-canary.1",
4
4
  "description": "CLI to create multi-package Lerna projects with TypeScript and React",
5
5
  "homepage": "https://docs.st.dev/docs/frontend/uikit/startup",
6
6
  "repository": {
@@ -17,8 +17,8 @@
17
17
  "typings": "./dist/index.d.ts",
18
18
  "exports": {
19
19
  ".": {
20
- "default": "./dist/index.js",
21
- "types": "./dist/index.d.ts"
20
+ "types": "./dist/index.d.ts",
21
+ "default": "./dist/index.js"
22
22
  },
23
23
  "./@types/cypress": {
24
24
  "types": "./dist/cypress/types/index.d.ts"
@@ -60,16 +60,16 @@
60
60
  "@jest/core": "~30.3.0",
61
61
  "@jest/types": "~30.3.0",
62
62
  "@jsdevtools/coverage-istanbul-loader": "^3.0.5",
63
- "@servicetitan/eslint-config": "36.1.0",
64
- "@servicetitan/install": "36.1.0",
65
- "@servicetitan/startup-utils": "36.1.0",
66
- "@servicetitan/stylelint-config": "36.1.0",
63
+ "@servicetitan/eslint-config": "36.1.1",
64
+ "@servicetitan/install": "36.1.1",
65
+ "@servicetitan/startup-utils": "36.1.1",
66
+ "@servicetitan/stylelint-config": "36.1.1",
67
67
  "@svgr/webpack": "^8.1.0",
68
68
  "@swc/cli": "^0.8.1",
69
69
  "@swc/core": "1.15.24",
70
70
  "@types/debug": "^4.1.12",
71
71
  "@types/jest": "~30.0.0",
72
- "@vitest/coverage-v8": "^4.1.2",
72
+ "@vitest/coverage-v8": "^4.1.4",
73
73
  "chalk": "~4.1.2",
74
74
  "cli-table3": "^0.6.5",
75
75
  "cpx2": "8.0.2",
@@ -115,7 +115,7 @@
115
115
  "ts-node": "~10.9.2",
116
116
  "typed-css-modules": "~0.9.1",
117
117
  "typescript": "5.9.3",
118
- "vitest": "^4.1.2",
118
+ "vitest": "^4.1.4",
119
119
  "webpack": "~5.105.4",
120
120
  "webpack-assets-manifest": "~6.5.1",
121
121
  "webpack-bundle-analyzer": "^5.3.0",
@@ -146,6 +146,5 @@
146
146
  },
147
147
  "cli": {
148
148
  "webpack": false
149
- },
150
- "gitHead": "b7b5cade33151c4d183faf498ddc1321694b7b2b"
149
+ }
151
150
  }
@@ -2,6 +2,7 @@ import deepmerge from 'deepmerge';
2
2
  import { fs, vol } from 'memfs';
3
3
  import { configDefaults, coverageConfigDefaults, mergeConfig, ViteUserConfig } from 'vitest/config';
4
4
  import { parseCLI, resolveConfig, startVitest } from 'vitest/node';
5
+ import { getDefaultExcludes } from '../../../../../utils';
5
6
  import { Vitest } from '../vitest';
6
7
 
7
8
  /**
@@ -20,20 +21,21 @@ jest.mock('vitest/', () => ({
20
21
 
21
22
  jest.mock('fs', () => fs);
22
23
 
24
+ jest.mock('../../../../../utils', () => ({
25
+ ...jest.requireActual('../../../../../utils'),
26
+ getDefaultExcludes: jest.fn(),
27
+ }));
28
+
23
29
  describe(`[startup] Test ${Vitest.name}`, () => {
30
+ const mockDefaultExcludes = ['foo', 'bar'];
24
31
  const defaultConfig: ViteUserConfig['test'] = {
25
32
  coverage: {
26
33
  include: ['**/*.{ts,tsx}'],
27
- exclude: [
28
- ...coverageConfigDefaults.exclude,
29
- '**/__mocks__/**',
30
- '**/*.stories.*',
31
- '\\.yalc',
32
- ],
34
+ exclude: [...coverageConfigDefaults.exclude, ...mockDefaultExcludes],
33
35
  reporter: ['html-spa', 'text', 'json', 'cobertura', 'lcov'],
34
36
  },
35
37
  environment: 'jsdom',
36
- exclude: [...configDefaults.exclude, '\\.yalc'],
38
+ exclude: [...configDefaults.exclude, ...mockDefaultExcludes],
37
39
  restoreMocks: true,
38
40
  server: { deps: { inline: ['@servicetitan/anvil2'] } },
39
41
  };
@@ -41,6 +43,7 @@ describe(`[startup] Test ${Vitest.name}`, () => {
41
43
  beforeEach(() => {
42
44
  jest.clearAllMocks();
43
45
 
46
+ jest.mocked(getDefaultExcludes).mockReturnValue(mockDefaultExcludes);
44
47
  jest.mocked(mergeConfig).mockImplementation((a, b) => deepmerge(a, b));
45
48
  jest.mocked(parseCLI).mockReturnValue({ filter: [], options: {} });
46
49
  jest.mocked(resolveConfig).mockResolvedValue({ viteConfig: {} } as any);
@@ -192,8 +195,6 @@ describe(`[startup] Test ${Vitest.name}`, () => {
192
195
  });
193
196
  });
194
197
  });
195
-
196
- test('can use omitDefault to replace coverage.include', () => {});
197
198
  });
198
199
 
199
200
  describe('with command line options', () => {
@@ -1,6 +1,6 @@
1
1
  import { configDefaults, coverageConfigDefaults, mergeConfig, ViteUserConfig } from 'vitest/config';
2
2
  import { parseCLI, resolveConfig, startVitest } from 'vitest/node';
3
- import { getVitestConfiguration, log, omit } from '../../../../utils';
3
+ import { getDefaultExcludes, getVitestConfiguration, log, omit } from '../../../../utils';
4
4
  import svgTransformer from '../../../../vitest/svg-transformer';
5
5
 
6
6
  type VitestConfig = NonNullable<ViteUserConfig['test']>;
@@ -40,17 +40,12 @@ function getCliOptions() {
40
40
  function getDefaultConfig(): VitestConfig {
41
41
  return {
42
42
  coverage: {
43
- exclude: [
44
- ...coverageConfigDefaults.exclude,
45
- '**/__mocks__/**',
46
- '**/*.stories.*',
47
- '\\.yalc',
48
- ],
43
+ exclude: [...coverageConfigDefaults.exclude, ...getDefaultExcludes()],
49
44
  include: ['**/*.{ts,tsx}'],
50
45
  reporter: ['html-spa', 'text', 'json', 'cobertura', 'lcov'],
51
46
  },
52
47
  environment: 'jsdom',
53
- exclude: [...configDefaults.exclude, '\\.yalc'],
48
+ exclude: [...configDefaults.exclude, ...getDefaultExcludes()],
54
49
  restoreMocks: true,
55
50
  server: { deps: { inline: ['@servicetitan/anvil2'] } }, // fixes css parser errors
56
51
  };
@@ -45,6 +45,15 @@ describe(`[startup/cypress-config] ${webpackConfig.name}`, () => {
45
45
  );
46
46
  });
47
47
 
48
+ test('enables code coverage', () => {
49
+ subject();
50
+
51
+ expect(rulesConfig).toHaveBeenCalledWith(
52
+ expect.objectContaining({ codeCoverage: true }),
53
+ expect.anything()
54
+ );
55
+ });
56
+
48
57
  test('includes all rules from rulesConfig', () => {
49
58
  const result = subject();
50
59
 
@@ -59,12 +68,30 @@ describe(`[startup/cypress-config] ${webpackConfig.name}`, () => {
59
68
  expect(result.module!.rules).toContainEqual(
60
69
  expect.objectContaining({
61
70
  test: /\.tsx?$/,
62
- exclude: /node_modules/,
71
+ exclude: /(node_modules|\.yalc)/,
63
72
  use: { loader: 'swc-loader', options: mockSwcOptions },
64
73
  })
65
74
  );
66
75
  });
67
76
 
77
+ test('adds coverage-istanbul-loader rule before swc-loader', () => {
78
+ const result = subject();
79
+
80
+ expect(result.module!.rules).toContainEqual(
81
+ expect.objectContaining({
82
+ enforce: 'pre',
83
+ test: /\.tsx?$/,
84
+ exclude: /(node_modules|\.yalc)/,
85
+ use: {
86
+ loader: '@jsdevtools/coverage-istanbul-loader',
87
+ options: expect.objectContaining({
88
+ parserPlugins: ['typescript', 'jsx'],
89
+ }),
90
+ },
91
+ })
92
+ );
93
+ });
94
+
68
95
  test('passes tsconfig content to getSwcOptions', () => {
69
96
  subject();
70
97
 
@@ -1,5 +1,5 @@
1
1
  import { inspect } from 'node:util';
2
- import type { Configuration } from 'webpack';
2
+ import type { Configuration, RuleSetRule } from 'webpack';
3
3
  import merge from 'webpack-merge';
4
4
  import { getSwcOptions } from '../../cli/tasks';
5
5
  import { TSConfig } from '../../cli/utils';
@@ -27,6 +27,7 @@ export function webpackConfig(overrides?: Overrides): Configuration {
27
27
 
28
28
  function getContext(): Context {
29
29
  return {
30
+ codeCoverage: true,
30
31
  destination: '',
31
32
  isProduction: false,
32
33
  name: '',
@@ -39,20 +40,44 @@ function getContext(): Context {
39
40
  function getRules(context: Context, overrides: Overrides) {
40
41
  const { rules } = rulesConfig(context, overrides);
41
42
 
42
- return [getSwcLoaderRule(), ...rules];
43
+ return [getSwcLoaderRule(), getSwcIstanbulRule(), ...rules];
43
44
  }
44
45
 
45
- function getSwcLoaderRule() {
46
+ function getSwcLoaderRule(): RuleSetRule {
46
47
  const tsConfig = new TSConfig(getTsConfigWithFallback());
47
48
 
48
49
  const swcOptions = getSwcOptions(tsConfig);
49
50
 
50
51
  return {
51
52
  test: /\.tsx?$/,
52
- exclude: /node_modules/,
53
+ exclude: /(node_modules|\.yalc)/,
53
54
  use: {
54
55
  loader: 'swc-loader',
55
56
  options: swcOptions,
56
57
  },
57
58
  };
58
59
  }
60
+
61
+ function getSwcIstanbulRule(): RuleSetRule {
62
+ return {
63
+ /*
64
+ * enforce: 'pre' ensures this loader runs BEFORE swc-loader, so istanbul
65
+ * instruments the original TypeScript source rather than compiled JS output.
66
+ * This means fnMap/statementMap positions reflect TypeScript line numbers,
67
+ * matching what Jest and Vitest produce.
68
+ * parserPlugins are required because istanbul-lib-instrument uses Babel
69
+ * internally, which cannot parse TypeScript syntax by default.
70
+ */
71
+ enforce: 'pre',
72
+ test: /\.tsx?$/,
73
+ exclude: /(node_modules|\.yalc)/,
74
+ use: {
75
+ loader: '@jsdevtools/coverage-istanbul-loader',
76
+ options: {
77
+ compact: false,
78
+ produceSourceMap: true,
79
+ parserPlugins: ['typescript', 'jsx'],
80
+ },
81
+ },
82
+ };
83
+ }
@@ -0,0 +1,25 @@
1
+ import { getDestinationFolders } from '../get-destination-folders';
2
+ import { getDefaultExcludes } from '../default-excludes';
3
+
4
+ jest.mock('../get-destination-folders');
5
+
6
+ describe('[startup] getDefaultExcludes', () => {
7
+ const destinationFolders = ['packages/app/dist/', 'packages/common/dist/'];
8
+
9
+ beforeEach(() => {
10
+ jest.clearAllMocks();
11
+ jest.mocked(getDestinationFolders).mockReturnValue(destinationFolders);
12
+ });
13
+
14
+ const subject = () => getDefaultExcludes();
15
+
16
+ test('includes standard exclusion patterns', () => {
17
+ expect(subject()).toEqual(
18
+ expect.arrayContaining(['__mocks__', '\\.stories\\.', '\\.yalc', '\\.claude', '\\.d\\.ts'])
19
+ );
20
+ });
21
+
22
+ test('includes destination folders', () => {
23
+ expect(subject()).toEqual(expect.arrayContaining(destinationFolders));
24
+ });
25
+ });
@@ -1,21 +1,21 @@
1
1
  import { Config } from '@jest/types';
2
2
  import path from 'path';
3
+ import { getDefaultExcludes } from '../default-excludes';
3
4
  import { getJestConfiguration } from '../get-configuration';
4
- import { getDestinationFolders } from '../get-destination-folders';
5
5
  import { getJestConfigCLI } from '../get-jest-config';
6
6
  import { pick } from '../pick';
7
7
 
8
- jest.mock('../get-destination-folders');
8
+ jest.mock('../default-excludes');
9
9
  jest.mock('../get-configuration', () => ({
10
10
  ...jest.requireActual('../get-configuration'),
11
11
  getJestConfiguration: jest.fn(),
12
12
  }));
13
13
 
14
14
  describe('[startup] Utils', () => {
15
- const destinationFolders = ['dist'];
15
+ const defaultExcludes = ['foo', 'bar'];
16
16
  const defaultConfig: Record<string, any> = {
17
17
  collectCoverageFrom: ['**/*.{ts,tsx}'],
18
- coveragePathIgnorePatterns: ['^.+\\.d\\.ts$'],
18
+ coveragePathIgnorePatterns: defaultExcludes,
19
19
  coverageReporters: ['html-spa', 'text', 'json', 'cobertura', 'lcov'],
20
20
  moduleNameMapper: {
21
21
  '\\.(css|scss|less|png|jpg|jpeg|gif|woff|woff2|eot|ttf|otf)$': 'identity-obj-proxy',
@@ -25,14 +25,14 @@ describe('[startup] Utils', () => {
25
25
  resolver: '@servicetitan/startup/jest-resolver',
26
26
  setupFiles: [expect.stringContaining(path.join('jest', 'setup.js'))],
27
27
  testEnvironment: 'jsdom',
28
- testPathIgnorePatterns: ['\\.yalc', ...destinationFolders],
28
+ testPathIgnorePatterns: defaultExcludes,
29
29
  testRunner: 'jest-circus/runner',
30
30
  transformIgnorePatterns: ['node_modules/(?!(@servicetitan|@react-hook|nanoid|axios)/)'],
31
31
  verbose: true,
32
32
  };
33
33
 
34
34
  beforeEach(() => {
35
- jest.mocked(getDestinationFolders).mockReturnValue(destinationFolders);
35
+ jest.mocked(getDefaultExcludes).mockReturnValue(defaultExcludes);
36
36
  jest.mocked(getJestConfiguration).mockReturnValue({});
37
37
  });
38
38
 
@@ -0,0 +1,24 @@
1
+ import { getDestinationFolders } from './get-destination-folders';
2
+
3
+ /**
4
+ * Returns default exclusions applied to both test running and coverage
5
+ * collection in Jest and Vitest.
6
+ *
7
+ * Patterns use regex syntax (for Jest testPathIgnorePatterns /
8
+ * coveragePathIgnorePatterns) and double as substring matches in Vitest's
9
+ * micromatch-based exclude / coverage.exclude.
10
+ *
11
+ * Destination folders (compiled output dirs from each package's tsconfig
12
+ * outDir) are included so that dist/ files are excluded from tests and
13
+ * coverage across all runners.
14
+ */
15
+ export function getDefaultExcludes(): string[] {
16
+ return [
17
+ '__mocks__',
18
+ '\\.stories\\.',
19
+ '\\.yalc',
20
+ '\\.claude',
21
+ '\\.d\\.ts',
22
+ ...getDestinationFolders(),
23
+ ];
24
+ }
@@ -1,7 +1,7 @@
1
1
  import { Config } from '@jest/types';
2
2
  import path from 'path';
3
+ import { getDefaultExcludes } from './default-excludes';
3
4
  import { getJestConfiguration } from './get-configuration';
4
- import { getDestinationFolders } from './get-destination-folders';
5
5
  import { omit } from './omit';
6
6
  import { toArray } from './to-array';
7
7
 
@@ -12,7 +12,7 @@ function getDefaultJestConfiguration() {
12
12
 
13
13
  return {
14
14
  collectCoverageFrom: ['**/*.{ts,tsx}'],
15
- coveragePathIgnorePatterns: ['^.+\\.d\\.ts$'],
15
+ coveragePathIgnorePatterns: [...getDefaultExcludes()],
16
16
  coverageReporters: ['html-spa', 'text', 'json', 'cobertura', 'lcov'],
17
17
  moduleNameMapper,
18
18
  modulePathIgnorePatterns: ['<rootDir>/.*/__mocks__'],
@@ -20,7 +20,7 @@ function getDefaultJestConfiguration() {
20
20
  resolver: '@servicetitan/startup/jest-resolver',
21
21
  setupFiles: [path.join(__dirname, '../../jest/setup.js')],
22
22
  testEnvironment: 'jsdom',
23
- testPathIgnorePatterns: ['\\.yalc', ...getDestinationFolders()],
23
+ testPathIgnorePatterns: [...getDefaultExcludes()],
24
24
  testRunner: 'jest-circus/runner',
25
25
  transformIgnorePatterns: ['node_modules/(?!(@servicetitan|@react-hook|nanoid|axios)/)'],
26
26
  verbose: true,
@@ -1,3 +1,4 @@
1
+ export * from './default-excludes';
1
2
  export * from './find-packages';
2
3
  export * from './find-up';
3
4
  export * from './format-duration';
@@ -421,8 +421,7 @@ describe(`[startup] ${createWebpackConfig.name}`, () => {
421
421
  expect.objectContaining({
422
422
  enforce: 'post',
423
423
  test: /\.js$/,
424
- include: [path.resolve(destination)],
425
- exclude: /node_modules/,
424
+ exclude: /(node_modules|\.yalc)/,
426
425
  use: expect.objectContaining({
427
426
  loader: '@jsdevtools/coverage-istanbul-loader',
428
427
  options: {
@@ -1,8 +1,7 @@
1
- import path from 'path';
2
1
  import { RuleSetRule } from 'webpack';
3
2
  import { Context } from '../types';
4
3
 
5
- export function jsRules({ codeCoverage, destination }: Context): RuleSetRule[] {
4
+ export function jsRules({ codeCoverage }: Context): RuleSetRule[] {
6
5
  const result: RuleSetRule[] = [
7
6
  {
8
7
  enforce: 'pre',
@@ -26,8 +25,7 @@ export function jsRules({ codeCoverage, destination }: Context): RuleSetRule[] {
26
25
  result.push({
27
26
  enforce: 'post',
28
27
  test: /\.js$/,
29
- include: [path.resolve(destination)],
30
- exclude: /node_modules/,
28
+ exclude: /(node_modules|\.yalc)/,
31
29
  use: {
32
30
  loader: '@jsdevtools/coverage-istanbul-loader',
33
31
  options: {