@temporalio/nyc-test-coverage 1.5.2 → 1.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.
@@ -0,0 +1,5 @@
1
+ import { CoverageMapData } from 'istanbul-lib-coverage';
2
+ declare global {
3
+ var __coverage__: CoverageMapData;
4
+ }
5
+ export {};
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=globalCoverage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"globalCoverage.js","sourceRoot":"","sources":["../src/globalCoverage.ts"],"names":[],"mappings":""}
package/lib/index.d.ts CHANGED
@@ -3,7 +3,7 @@ import { InjectedSinks, BundleOptions, WorkerOptions } from '@temporalio/worker'
3
3
  import { CoverageSinks } from './sinks';
4
4
  declare type WebpackConfigType = ReturnType<NonNullable<BundleOptions['webpackConfigHook']>>;
5
5
  export declare class WorkflowCoverage {
6
- coverageMap: libCoverage.CoverageMap;
6
+ coverageMapsData: libCoverage.CoverageMapData[];
7
7
  private hasCoverageGlobal;
8
8
  /**
9
9
  * Add all necessary coverage-specific logic to Worker config:
@@ -36,10 +36,9 @@ export declare class WorkflowCoverage {
36
36
  */
37
37
  get sinks(): InjectedSinks<CoverageSinks>;
38
38
  /**
39
- * Modify the given Worker config to auto instrument Workflow
40
- * code using istanbul-instrumenter-loader
39
+ * Modify the given Worker config to auto instrument Workflows
41
40
  */
42
- addInstrumenterRule(workflowsPath: string, config: WebpackConfigType): WebpackConfigType;
41
+ addInstrumenterRule(config: WebpackConfigType): WebpackConfigType;
43
42
  /**
44
43
  * Merge this WorkflowCoverage's coverage map into the global coverage
45
44
  * map data `global.__coverage__`.
package/lib/index.js CHANGED
@@ -22,12 +22,16 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
22
  __setModuleDefault(result, mod);
23
23
  return result;
24
24
  };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
25
28
  Object.defineProperty(exports, "__esModule", { value: true });
26
29
  exports.WorkflowCoverage = void 0;
30
+ const node_path_1 = __importDefault(require("node:path"));
27
31
  const libCoverage = __importStar(require("istanbul-lib-coverage"));
28
32
  class WorkflowCoverage {
29
33
  constructor() {
30
- this.coverageMap = libCoverage.createCoverageMap();
34
+ this.coverageMapsData = [];
31
35
  }
32
36
  // Check if running through nyc or some other Istanbul-based tool.
33
37
  // If not, any `workflowCoverage()` tools are a no-op.
@@ -45,7 +49,6 @@ class WorkflowCoverage {
45
49
  if (!this.hasCoverageGlobal()) {
46
50
  return workerOptions;
47
51
  }
48
- const workflowsPath = workerOptions.workflowsPath;
49
52
  return {
50
53
  ...workerOptions,
51
54
  interceptors: {
@@ -59,7 +62,7 @@ class WorkflowCoverage {
59
62
  bundlerOptions: {
60
63
  ...workerOptions.bundlerOptions,
61
64
  webpackConfigHook: (config) => {
62
- config = this.addInstrumenterRule(workflowsPath, config);
65
+ config = this.addInstrumenterRule(config);
63
66
  const existingWebpackConfigHook = workerOptions?.bundlerOptions?.webpackConfigHook;
64
67
  if (existingWebpackConfigHook !== undefined) {
65
68
  return existingWebpackConfigHook(config);
@@ -81,12 +84,11 @@ class WorkflowCoverage {
81
84
  if (!this.hasCoverageGlobal()) {
82
85
  return bundleOptions;
83
86
  }
84
- const workflowsPath = bundleOptions.workflowsPath;
85
87
  return {
86
88
  ...bundleOptions,
87
89
  workflowInterceptorModules: [...(bundleOptions.workflowInterceptorModules || []), this.interceptorModule],
88
90
  webpackConfigHook: (config) => {
89
- config = this.addInstrumenterRule(workflowsPath, config);
91
+ config = this.addInstrumenterRule(config);
90
92
  const existingWebpackConfigHook = bundleOptions.webpackConfigHook;
91
93
  if (existingWebpackConfigHook !== undefined) {
92
94
  return existingWebpackConfigHook(config);
@@ -128,7 +130,7 @@ class WorkflowCoverage {
128
130
  coverage: {
129
131
  merge: {
130
132
  fn: (_workflowInfo, testCoverage) => {
131
- this.coverageMap.merge(testCoverage);
133
+ this.coverageMapsData.push(testCoverage);
132
134
  },
133
135
  callDuringReplay: false,
134
136
  },
@@ -136,26 +138,46 @@ class WorkflowCoverage {
136
138
  };
137
139
  }
138
140
  /**
139
- * Modify the given Worker config to auto instrument Workflow
140
- * code using istanbul-instrumenter-loader
141
+ * Modify the given Worker config to auto instrument Workflows
141
142
  */
142
- addInstrumenterRule(workflowsPath, config) {
143
+ addInstrumenterRule(config) {
143
144
  if (!this.hasCoverageGlobal()) {
144
145
  return config;
145
146
  }
146
- const newRule = {
147
+ const rules = config?.module?.rules || [];
148
+ if (Object.keys(require.cache).some((file) => file.includes('ts-node/register'))) {
149
+ // ts-node is currently loaded
150
+ // ts-node and SWC doesn't translate TypeScript code the same way, which will cause
151
+ // line number mismatches in generated coverage reports.
152
+ const tsLoaderRule = {
153
+ test: /\.ts$/,
154
+ loader: require.resolve('ts-loader'),
155
+ exclude: /node_modules/,
156
+ };
157
+ const swcRuleIndex = rules.findIndex((rule) => {
158
+ const loader = rule.use?.loader;
159
+ return loader && loader.indexOf('swc-loader') >= 0;
160
+ });
161
+ rules[swcRuleIndex] = tsLoaderRule;
162
+ }
163
+ rules.push({
147
164
  use: {
148
- loader: require.resolve('istanbul-instrumenter-loader'),
149
- options: { esModules: true },
165
+ loader: require.resolve('./loader'),
150
166
  },
151
167
  enforce: 'post',
152
- include: workflowsPath,
153
- };
168
+ test: /\.[tj]s$/,
169
+ exclude: [
170
+ /\/node_modules\//,
171
+ node_path_1.default.dirname(require.resolve('@temporalio/common')),
172
+ node_path_1.default.dirname(require.resolve('@temporalio/workflow')),
173
+ node_path_1.default.dirname(require.resolve('@temporalio/nyc-test-coverage')),
174
+ ],
175
+ });
154
176
  return {
155
177
  ...config,
156
178
  module: {
157
179
  ...config?.module,
158
- rules: [...(config?.module?.rules || []), newRule],
180
+ rules,
159
181
  },
160
182
  };
161
183
  }
@@ -167,16 +189,12 @@ class WorkflowCoverage {
167
189
  if (!this.hasCoverageGlobal()) {
168
190
  return;
169
191
  }
170
- /* eslint-disable @typescript-eslint/ban-ts-comment */
171
- // @ts-ignore
172
- this.coverageMap.merge(global.__coverage__);
173
- const coverageMapData = Object.keys(this.coverageMap.data).reduce((cur, path) => {
174
- const fileCoverage = this.coverageMap.data[path];
175
- cur[path] = fileCoverage.data;
176
- return cur;
177
- }, {});
178
- // @ts-ignore
179
- global.__coverage__ = coverageMapData;
192
+ const coverageMap = libCoverage.createCoverageMap();
193
+ this.coverageMapsData.unshift(global.__coverage__);
194
+ for (const data of this.coverageMapsData)
195
+ coverageMap.merge(data);
196
+ this.coverageMapsData = [];
197
+ global.__coverage__ = coverageMap.data;
180
198
  }
181
199
  }
182
200
  exports.WorkflowCoverage = WorkflowCoverage;
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -11,8 +11,13 @@ const interceptors = () => ({
11
11
  /* eslint-disable @typescript-eslint/ban-ts-comment */
12
12
  // @ts-ignore
13
13
  const globalCoverage = global.__coverage__;
14
- coverage.merge(JSON.parse(JSON.stringify(globalCoverage)));
15
- clearCoverage(globalCoverage);
14
+ if (globalCoverage) {
15
+ // Send coverage data through the sink to be merged into the _real_ global coverage map
16
+ // Make a deep copy first, otherwise clearCoverage may wipe out the data
17
+ // before it actually get processed by the sink
18
+ coverage.merge(JSON.parse(JSON.stringify(globalCoverage)));
19
+ clearCoverage(globalCoverage);
20
+ }
16
21
  return next(input);
17
22
  },
18
23
  },
@@ -1 +1 @@
1
- {"version":3,"file":"interceptors.js","sourceRoot":"","sources":["../src/interceptors.ts"],"names":[],"mappings":";;;AACA,mDAAwE;AAGxE,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAA,qBAAU,GAAiB,CAAC;AAEjD,0BAA0B;AACnB,MAAM,YAAY,GAAG,GAAyB,EAAE,CAAC,CAAC;IACvD,SAAS,EAAE;QACT;YACE,kBAAkB,CAAC,KAAK,EAAE,IAAI;gBAC5B,sDAAsD;gBACtD,aAAa;gBACb,MAAM,cAAc,GAAoB,MAAM,CAAC,YAAY,CAAC;gBAE5D,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;gBAC3D,aAAa,CAAC,cAAc,CAAC,CAAC;gBAE9B,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC;SACF;KACF;CACF,CAAC,CAAC;AAfU,QAAA,YAAY,gBAetB;AAEH,SAAS,aAAa,CAAC,QAAyB;IAC9C,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;QACxC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;YACjD,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;SAC7B;KACF;AACH,CAAC"}
1
+ {"version":3,"file":"interceptors.js","sourceRoot":"","sources":["../src/interceptors.ts"],"names":[],"mappings":";;;AACA,mDAAwE;AAGxE,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAA,qBAAU,GAAiB,CAAC;AAEjD,0BAA0B;AACnB,MAAM,YAAY,GAAG,GAAyB,EAAE,CAAC,CAAC;IACvD,SAAS,EAAE;QACT;YACE,kBAAkB,CAAC,KAAK,EAAE,IAAI;gBAC5B,sDAAsD;gBACtD,aAAa;gBACb,MAAM,cAAc,GAAoB,MAAM,CAAC,YAAY,CAAC;gBAC5D,IAAI,cAAc,EAAE;oBAClB,uFAAuF;oBACvF,wEAAwE;oBACxE,+CAA+C;oBAC/C,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;oBAC3D,aAAa,CAAC,cAAc,CAAC,CAAC;iBAC/B;gBAED,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC;SACF;KACF;CACF,CAAC,CAAC;AAnBU,QAAA,YAAY,gBAmBtB;AAEH,SAAS,aAAa,CAAC,QAAyB;IAC9C,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;QACxC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;YACjD,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;SAC7B;KACF;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { LoaderDefinitionFunction } from 'webpack';
2
+ declare const instrumentWithIstanbulLoader: LoaderDefinitionFunction;
3
+ export default instrumentWithIstanbulLoader;
package/lib/loader.js ADDED
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ const istanbul_lib_instrument_1 = require("istanbul-lib-instrument");
27
+ const convert = __importStar(require("convert-source-map"));
28
+ const instrumentWithIstanbulLoader = function (source, sourceMap) {
29
+ let srcMap = sourceMap ?? convert.fromSource(source)?.sourcemap;
30
+ if (typeof srcMap === 'string')
31
+ srcMap = JSON.parse(srcMap);
32
+ const instrumenter = (0, istanbul_lib_instrument_1.createInstrumenter)({
33
+ esModules: true,
34
+ produceSourceMap: true,
35
+ });
36
+ instrumenter.instrument(source, this.resourcePath, (error, instrumentedSource) => {
37
+ this.callback(error, instrumentedSource, instrumenter.lastSourceMap());
38
+ }, srcMap);
39
+ };
40
+ exports.default = instrumentWithIstanbulLoader;
41
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qEAA6D;AAC7D,4DAA8C;AAG9C,MAAM,4BAA4B,GAA6B,UAAU,MAAM,EAAE,SAAS;IACxF,IAAI,MAAM,GAAG,SAAS,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;IAChE,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAE5D,MAAM,YAAY,GAAG,IAAA,4CAAkB,EAAC;QACtC,SAAS,EAAE,IAAI;QACf,gBAAgB,EAAE,IAAI;KACvB,CAAC,CAAC;IAEH,YAAY,CAAC,UAAU,CACrB,MAAM,EACN,IAAI,CAAC,YAAY,EACjB,CAAC,KAAK,EAAE,kBAAkB,EAAE,EAAE;QAC5B,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,kBAAkB,EAAE,YAAY,CAAC,aAAa,EAAS,CAAC,CAAC;IAChF,CAAC,EACD,MAAa,CACd,CAAC;AACJ,CAAC,CAAC;AAEF,kBAAe,4BAA4B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@temporalio/nyc-test-coverage",
3
- "version": "1.5.2",
3
+ "version": "1.7.0",
4
4
  "description": "Temporal.io SDK code coverage integration",
5
5
  "keywords": [
6
6
  "temporal",
@@ -8,10 +8,15 @@
8
8
  "testing",
9
9
  "coverage"
10
10
  ],
11
- "homepage": "https://github.com/temporalio/sdk-typescript/tree/main/packages/testing",
11
+ "homepage": "https://github.com/temporalio/sdk-typescript/tree/main/packages/nyc=test-coverage",
12
12
  "bugs": {
13
13
  "url": "https://github.com/temporalio/sdk-typescript/issues"
14
14
  },
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/temporalio/sdk-typescript.git",
18
+ "directory": "packages/nyc-test-coverage"
19
+ },
15
20
  "license": "MIT",
16
21
  "author": "Temporal Technologies Inc. <sdk@temporal.io>",
17
22
  "main": "lib/index.js",
@@ -21,16 +26,21 @@
21
26
  "src"
22
27
  ],
23
28
  "dependencies": {
24
- "@temporalio/worker": "^1.5.2",
25
- "@temporalio/workflow": "^1.5.2",
26
- "istanbul-instrumenter-loader": "^3.0.1",
27
- "istanbul-lib-coverage": "^3.2.0"
29
+ "@temporalio/worker": "1.7.0",
30
+ "@temporalio/workflow": "1.7.0",
31
+ "convert-source-map": "^2.0.0",
32
+ "istanbul-lib-coverage": "^3.2.0",
33
+ "istanbul-lib-instrument": "^5.2.1",
34
+ "ts-loader": "^9.4.2"
28
35
  },
29
36
  "devDependencies": {
30
- "@types/istanbul-lib-coverage": "^2.0.4"
37
+ "@types/convert-source-map": "^2.0.0",
38
+ "@types/istanbul-lib-coverage": "^2.0.4",
39
+ "@types/istanbul-lib-instrument": "^1.7.4",
40
+ "@types/webpack": "^5.28.0"
31
41
  },
32
42
  "publishConfig": {
33
43
  "access": "public"
34
44
  },
35
- "gitHead": "d32adfd8537661c3740767ca1a3862392ca702e2"
45
+ "gitHead": "2b32bac62f879b35238b487d3aaed093a1e449a7"
36
46
  }
@@ -0,0 +1,8 @@
1
+ import { CoverageMapData } from 'istanbul-lib-coverage';
2
+
3
+ declare global {
4
+ // eslint-disable-next-line no-var
5
+ var __coverage__: CoverageMapData;
6
+ }
7
+
8
+ export {};
package/src/index.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import path from 'node:path';
1
2
  import * as libCoverage from 'istanbul-lib-coverage';
2
3
  import { InjectedSinks, BundleOptions, WorkerOptions } from '@temporalio/worker';
3
4
  import { CoverageSinks } from './sinks';
@@ -6,7 +7,7 @@ import { CoverageSinks } from './sinks';
6
7
  type WebpackConfigType = ReturnType<NonNullable<BundleOptions['webpackConfigHook']>>;
7
8
 
8
9
  export class WorkflowCoverage {
9
- coverageMap = libCoverage.createCoverageMap();
10
+ coverageMapsData: libCoverage.CoverageMapData[] = [];
10
11
 
11
12
  // Check if running through nyc or some other Istanbul-based tool.
12
13
  // If not, any `workflowCoverage()` tools are a no-op.
@@ -29,8 +30,6 @@ export class WorkflowCoverage {
29
30
  return workerOptions;
30
31
  }
31
32
 
32
- const workflowsPath = workerOptions.workflowsPath;
33
-
34
33
  return {
35
34
  ...workerOptions,
36
35
  interceptors: {
@@ -44,7 +43,7 @@ export class WorkflowCoverage {
44
43
  bundlerOptions: {
45
44
  ...workerOptions.bundlerOptions,
46
45
  webpackConfigHook: (config: WebpackConfigType) => {
47
- config = this.addInstrumenterRule(workflowsPath, config);
46
+ config = this.addInstrumenterRule(config);
48
47
 
49
48
  const existingWebpackConfigHook = workerOptions?.bundlerOptions?.webpackConfigHook;
50
49
  if (existingWebpackConfigHook !== undefined) {
@@ -73,12 +72,11 @@ export class WorkflowCoverage {
73
72
  return bundleOptions;
74
73
  }
75
74
 
76
- const workflowsPath = bundleOptions.workflowsPath;
77
75
  return {
78
76
  ...bundleOptions,
79
77
  workflowInterceptorModules: [...(bundleOptions.workflowInterceptorModules || []), this.interceptorModule],
80
78
  webpackConfigHook: (config: WebpackConfigType) => {
81
- config = this.addInstrumenterRule(workflowsPath, config);
79
+ config = this.addInstrumenterRule(config);
82
80
 
83
81
  const existingWebpackConfigHook = bundleOptions.webpackConfigHook;
84
82
  if (existingWebpackConfigHook !== undefined) {
@@ -131,7 +129,7 @@ export class WorkflowCoverage {
131
129
  coverage: {
132
130
  merge: {
133
131
  fn: (_workflowInfo, testCoverage) => {
134
- this.coverageMap.merge(testCoverage);
132
+ this.coverageMapsData.push(testCoverage);
135
133
  },
136
134
  callDuringReplay: false,
137
135
  },
@@ -140,28 +138,52 @@ export class WorkflowCoverage {
140
138
  }
141
139
 
142
140
  /**
143
- * Modify the given Worker config to auto instrument Workflow
144
- * code using istanbul-instrumenter-loader
141
+ * Modify the given Worker config to auto instrument Workflows
145
142
  */
146
- addInstrumenterRule(workflowsPath: string, config: WebpackConfigType): WebpackConfigType {
143
+ addInstrumenterRule(config: WebpackConfigType): WebpackConfigType {
147
144
  if (!this.hasCoverageGlobal()) {
148
145
  return config;
149
146
  }
150
147
 
151
- const newRule = {
148
+ const rules = config?.module?.rules || [];
149
+
150
+ if (Object.keys(require.cache).some((file) => file.includes('ts-node/register'))) {
151
+ // ts-node is currently loaded
152
+ // ts-node and SWC doesn't translate TypeScript code the same way, which will cause
153
+ // line number mismatches in generated coverage reports.
154
+ const tsLoaderRule = {
155
+ test: /\.ts$/,
156
+ loader: require.resolve('ts-loader'),
157
+ exclude: /node_modules/,
158
+ };
159
+
160
+ const swcRuleIndex = rules.findIndex((rule) => {
161
+ const loader = (rule as any).use?.loader;
162
+ return loader && loader.indexOf('swc-loader') >= 0;
163
+ });
164
+
165
+ rules[swcRuleIndex] = tsLoaderRule;
166
+ }
167
+
168
+ rules.push({
152
169
  use: {
153
- loader: require.resolve('istanbul-instrumenter-loader'),
154
- options: { esModules: true },
170
+ loader: require.resolve('./loader'),
155
171
  },
156
172
  enforce: 'post' as const,
157
- include: workflowsPath,
158
- };
173
+ test: /\.[tj]s$/,
174
+ exclude: [
175
+ /\/node_modules\//,
176
+ path.dirname(require.resolve('@temporalio/common')),
177
+ path.dirname(require.resolve('@temporalio/workflow')),
178
+ path.dirname(require.resolve('@temporalio/nyc-test-coverage')),
179
+ ],
180
+ });
159
181
 
160
182
  return {
161
183
  ...config,
162
184
  module: {
163
185
  ...config?.module,
164
- rules: [...(config?.module?.rules || []), newRule],
186
+ rules,
165
187
  },
166
188
  };
167
189
  }
@@ -175,21 +197,11 @@ export class WorkflowCoverage {
175
197
  return;
176
198
  }
177
199
 
178
- /* eslint-disable @typescript-eslint/ban-ts-comment */
179
- // @ts-ignore
180
- this.coverageMap.merge(global.__coverage__);
181
-
182
- const coverageMapData: libCoverage.CoverageMapData = Object.keys(this.coverageMap.data).reduce(
183
- (cur: libCoverage.CoverageMapData, path) => {
184
- const fileCoverage = this.coverageMap.data[path] as libCoverage.FileCoverage;
185
-
186
- cur[path] = fileCoverage.data;
187
- return cur;
188
- },
189
- {}
190
- );
200
+ const coverageMap = libCoverage.createCoverageMap();
201
+ this.coverageMapsData.unshift(global.__coverage__);
202
+ for (const data of this.coverageMapsData) coverageMap.merge(data);
203
+ this.coverageMapsData = [];
191
204
 
192
- // @ts-ignore
193
- global.__coverage__ = coverageMapData;
205
+ global.__coverage__ = coverageMap.data;
194
206
  }
195
207
  }
@@ -12,9 +12,13 @@ export const interceptors = (): WorkflowInterceptors => ({
12
12
  /* eslint-disable @typescript-eslint/ban-ts-comment */
13
13
  // @ts-ignore
14
14
  const globalCoverage: CoverageMapData = global.__coverage__;
15
-
16
- coverage.merge(JSON.parse(JSON.stringify(globalCoverage)));
17
- clearCoverage(globalCoverage);
15
+ if (globalCoverage) {
16
+ // Send coverage data through the sink to be merged into the _real_ global coverage map
17
+ // Make a deep copy first, otherwise clearCoverage may wipe out the data
18
+ // before it actually get processed by the sink
19
+ coverage.merge(JSON.parse(JSON.stringify(globalCoverage)));
20
+ clearCoverage(globalCoverage);
21
+ }
18
22
 
19
23
  return next(input);
20
24
  },
package/src/loader.ts ADDED
@@ -0,0 +1,24 @@
1
+ import { createInstrumenter } from 'istanbul-lib-instrument';
2
+ import * as convert from 'convert-source-map';
3
+ import type { LoaderDefinitionFunction } from 'webpack';
4
+
5
+ const instrumentWithIstanbulLoader: LoaderDefinitionFunction = function (source, sourceMap): void {
6
+ let srcMap = sourceMap ?? convert.fromSource(source)?.sourcemap;
7
+ if (typeof srcMap === 'string') srcMap = JSON.parse(srcMap);
8
+
9
+ const instrumenter = createInstrumenter({
10
+ esModules: true,
11
+ produceSourceMap: true,
12
+ });
13
+
14
+ instrumenter.instrument(
15
+ source,
16
+ this.resourcePath,
17
+ (error, instrumentedSource) => {
18
+ this.callback(error, instrumentedSource, instrumenter.lastSourceMap() as any);
19
+ },
20
+ srcMap as any
21
+ );
22
+ };
23
+
24
+ export default instrumentWithIstanbulLoader;