@zimic/interceptor 1.3.6-canary.2 → 1.3.6-canary.4

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.
package/dist/http.js CHANGED
@@ -3,33 +3,11 @@
3
3
  var http = require('@zimic/http');
4
4
  var color2 = require('picocolors');
5
5
  var msw = require('msw');
6
- var mswBrowser = require('msw/browser');
7
- var mswNode = require('msw/node');
8
6
  var ClientSocket = require('isomorphic-ws');
9
7
 
10
8
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
11
9
 
12
- function _interopNamespace(e) {
13
- if (e && e.__esModule) return e;
14
- var n = Object.create(null);
15
- if (e) {
16
- Object.keys(e).forEach(function (k) {
17
- if (k !== 'default') {
18
- var d = Object.getOwnPropertyDescriptor(e, k);
19
- Object.defineProperty(n, k, d.get ? d : {
20
- enumerable: true,
21
- get: function () { return e[k]; }
22
- });
23
- }
24
- });
25
- }
26
- n.default = e;
27
- return Object.freeze(n);
28
- }
29
-
30
10
  var color2__default = /*#__PURE__*/_interopDefault(color2);
31
- var mswBrowser__namespace = /*#__PURE__*/_interopNamespace(mswBrowser);
32
- var mswNode__namespace = /*#__PURE__*/_interopNamespace(mswNode);
33
11
  var ClientSocket__default = /*#__PURE__*/_interopDefault(ClientSocket);
34
12
 
35
13
  // src/http/index.ts
@@ -1740,8 +1718,14 @@ var HttpInterceptorImplementation = class {
1740
1718
  }
1741
1719
  };
1742
1720
  var HttpInterceptorImplementation_default = HttpInterceptorImplementation;
1743
- var LocalHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
1744
- internalWorker;
1721
+ var importMSWNode = createCachedDynamicImport_default(() => import('msw/node'));
1722
+ var importMSWBrowser = createCachedDynamicImport_default(() => import('msw/browser'));
1723
+ var LocalHttpInterceptorWorker = class _LocalHttpInterceptorWorker extends HttpInterceptorWorker_default {
1724
+ // Re-creating MSW workers may cause issues, so we should keep a single worker instance, even if all interceptor
1725
+ // workers are stopped. See https://github.com/mswjs/msw/issues/2597.
1726
+ static mswWorker;
1727
+ static isMSWWorkerRunning = false;
1728
+ mswHttpHandler;
1745
1729
  httpHandlersByMethod = {
1746
1730
  GET: [],
1747
1731
  POST: [],
@@ -1754,52 +1738,66 @@ var LocalHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
1754
1738
  constructor(_options) {
1755
1739
  super();
1756
1740
  }
1741
+ get class() {
1742
+ return _LocalHttpInterceptorWorker;
1743
+ }
1757
1744
  get type() {
1758
1745
  return "local";
1759
1746
  }
1760
- get internalWorkerOrThrow() {
1761
- if (!this.internalWorker) {
1747
+ get mswWorkerOrThrow() {
1748
+ if (!this.class.mswWorker) {
1762
1749
  throw new NotRunningHttpInterceptorError_default();
1763
1750
  }
1764
- return this.internalWorker;
1751
+ return this.class.mswWorker;
1765
1752
  }
1766
- get internalWorkerOrCreate() {
1767
- this.internalWorker ??= this.createInternalWorker();
1768
- return this.internalWorker;
1753
+ async getMSWWorkerOrCreate() {
1754
+ this.class.mswWorker ??= await this.createMSWWorker();
1755
+ return this.class.mswWorker;
1769
1756
  }
1770
- createInternalWorker() {
1771
- const mswHttpHandler = msw.http.all("*", async (context) => {
1772
- const request = context.request;
1773
- const response = await this.createResponseForRequest(request);
1774
- return response;
1775
- });
1776
- if (isServerSide() && "setupServer" in mswNode__namespace) {
1777
- return mswNode__namespace.setupServer(mswHttpHandler);
1757
+ async createMSWWorker() {
1758
+ if (isServerSide()) {
1759
+ const mswNode = await importMSWNode();
1760
+ if ("setupServer" in mswNode) {
1761
+ return mswNode.setupServer();
1762
+ }
1778
1763
  }
1779
- if (isClientSide() && "setupWorker" in mswBrowser__namespace) {
1780
- return mswBrowser__namespace.setupWorker(mswHttpHandler);
1764
+ if (isClientSide()) {
1765
+ const mswBrowser = await importMSWBrowser();
1766
+ if ("setupWorker" in mswBrowser) {
1767
+ return mswBrowser.setupWorker();
1768
+ }
1781
1769
  }
1782
1770
  throw new UnknownHttpInterceptorPlatformError_default();
1783
1771
  }
1784
1772
  async start() {
1785
1773
  await super.sharedStart(async () => {
1786
- const internalWorker = this.internalWorkerOrCreate;
1774
+ const mswWorker = await this.getMSWWorkerOrCreate();
1787
1775
  const sharedOptions = {
1788
1776
  onUnhandledRequest: "bypass"
1789
1777
  };
1790
- if (this.isInternalBrowserWorker(internalWorker)) {
1778
+ this.mswHttpHandler = msw.http.all("*", async (context) => {
1779
+ const request = context.request;
1780
+ const response = await this.createResponseForRequest(request);
1781
+ return response;
1782
+ });
1783
+ mswWorker.use(this.mswHttpHandler);
1784
+ if (this.isInternalBrowserWorker(mswWorker)) {
1791
1785
  this.platform = "browser";
1792
- await this.startInBrowser(internalWorker, sharedOptions);
1786
+ if (!this.class.isMSWWorkerRunning) {
1787
+ await this.startInBrowser(mswWorker, sharedOptions);
1788
+ this.class.isMSWWorkerRunning = true;
1789
+ }
1793
1790
  } else {
1794
1791
  this.platform = "node";
1795
- this.startInNode(internalWorker, sharedOptions);
1792
+ this.startInNode(mswWorker, sharedOptions);
1793
+ this.class.isMSWWorkerRunning = true;
1796
1794
  }
1797
1795
  this.isRunning = true;
1798
1796
  });
1799
1797
  }
1800
- async startInBrowser(internalWorker, sharedOptions) {
1798
+ async startInBrowser(mswWorker, sharedOptions) {
1801
1799
  try {
1802
- await internalWorker.start({ ...sharedOptions, quiet: true });
1800
+ await mswWorker.start({ ...sharedOptions, quiet: true });
1803
1801
  } catch (error) {
1804
1802
  this.handleBrowserWorkerStartError(error);
1805
1803
  }
@@ -1807,36 +1805,35 @@ var LocalHttpInterceptorWorker = class extends HttpInterceptorWorker_default {
1807
1805
  handleBrowserWorkerStartError(error) {
1808
1806
  if (UnregisteredBrowserServiceWorkerError_default.matchesRawError(error)) {
1809
1807
  throw new UnregisteredBrowserServiceWorkerError_default();
1808
+ } else {
1809
+ throw error;
1810
1810
  }
1811
- throw error;
1812
1811
  }
1813
- startInNode(internalWorker, sharedOptions) {
1814
- internalWorker.listen(sharedOptions);
1812
+ startInNode(mswWorker, sharedOptions) {
1813
+ mswWorker.listen(sharedOptions);
1815
1814
  }
1816
1815
  async stop() {
1817
- await super.sharedStop(() => {
1818
- const internalWorker = this.internalWorkerOrCreate;
1819
- if (this.isInternalBrowserWorker(internalWorker)) {
1820
- this.stopInBrowser(internalWorker);
1821
- } else {
1822
- this.stopInNode(internalWorker);
1823
- }
1816
+ await super.sharedStop(async () => {
1817
+ const mswWorker = await this.getMSWWorkerOrCreate();
1824
1818
  this.clearHandlers();
1825
- this.internalWorker = void 0;
1819
+ const newMSWHandlers = mswWorker.listHandlers().filter((handler) => handler !== this.mswHttpHandler);
1820
+ mswWorker.resetHandlers(...newMSWHandlers);
1821
+ if (this.isInternalBrowserWorker(mswWorker)) ; else {
1822
+ this.stopInNode(mswWorker);
1823
+ this.class.isMSWWorkerRunning = false;
1824
+ }
1825
+ this.mswHttpHandler = void 0;
1826
1826
  this.isRunning = false;
1827
1827
  });
1828
1828
  }
1829
- stopInBrowser(internalWorker) {
1830
- internalWorker.stop();
1831
- }
1832
- stopInNode(internalWorker) {
1833
- internalWorker.close();
1829
+ stopInNode(mswWorker) {
1830
+ mswWorker.close();
1834
1831
  }
1835
1832
  isInternalBrowserWorker(worker) {
1836
1833
  return "start" in worker && "stop" in worker;
1837
1834
  }
1838
1835
  hasInternalBrowserWorker() {
1839
- return this.isInternalBrowserWorker(this.internalWorkerOrThrow);
1836
+ return this.isInternalBrowserWorker(this.mswWorkerOrThrow);
1840
1837
  }
1841
1838
  hasInternalNodeWorker() {
1842
1839
  return !this.hasInternalBrowserWorker();
@@ -2667,12 +2664,8 @@ var LocalHttpInterceptor = class {
2667
2664
  this.implementation = new HttpInterceptorImplementation_default({
2668
2665
  store: this.store,
2669
2666
  baseURL,
2670
- createWorker: () => {
2671
- return this.store.getOrCreateLocalWorker({});
2672
- },
2673
- deleteWorker: () => {
2674
- this.store.deleteLocalWorker();
2675
- },
2667
+ createWorker: () => this.store.getOrCreateLocalWorker({}),
2668
+ deleteWorker: () => this.store.deleteLocalWorker(),
2676
2669
  Handler: LocalHttpRequestHandler_default,
2677
2670
  onUnhandledRequest: options.onUnhandledRequest,
2678
2671
  requestSaving: options.requestSaving
@@ -2895,15 +2888,26 @@ var InvalidJSONError = class extends http.InvalidJSONError {
2895
2888
  };
2896
2889
  /* istanbul ignore else -- @preserve
2897
2890
  * The else is a fallback for when the error is not an instance of Error. */
2891
+ /* istanbul ignore next -- @preserve
2892
+ * This if statement only runs if concurrent calls to stop() are made, which is an edge case that is hard to
2893
+ * reliably reproduce in tests. */
2898
2894
  /* istanbul ignore if -- @preserve
2899
2895
  * This is just a type guard to ensure the value is valid. In practice, this condition should never be true. */
2900
2896
  /* istanbul ignore next -- @preserve
2901
2897
  * Ignoring because there will always be a handler for the given method and path at this point. */
2902
2898
  /* istanbul ignore if -- @preserve
2903
2899
  * Trying to access the internal worker when it does not exist should not happen. */
2900
+ /* istanbul ignore else -- @preserve
2901
+ * We still check if we actually imported the server module in case our `isServerSide()` check returns true, but
2902
+ * the environment actually resolves the browser module. */
2904
2903
  /* istanbul ignore else -- @preserve */
2904
+ /* istanbul ignore else -- @preserve
2905
+ * We still check if we actually imported the browser module in case our `isClientSide()` check returns true, but
2906
+ * the environment actually resolves the server module. */
2905
2907
  /* istanbul ignore next -- @preserve
2906
2908
  * Ignoring because checking unknown platforms is not configured in our test setup. */
2909
+ /* istanbul ignore else -- @preserve
2910
+ * Since we start the internal worker once and do not stop it, tests may not be able exercise this branch. */
2907
2911
  /* istanbul ignore next -- @preserve
2908
2912
  * Ignoring as Node.js >=20 provides a global crypto and the import fallback won't run. */
2909
2913
  /* istanbul ignore else -- @preserve