@squide/msw 4.0.20 → 4.1.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @squide/msw
2
2
 
3
+ ## 4.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#631](https://github.com/workleap/wl-squide/pull/631) [`9bbcd7e`](https://github.com/workleap/wl-squide/commit/9bbcd7e1597d0c473a1477f608e3596390553bb4) Thanks [@patricklafrance](https://github.com/patricklafrance)! - `registerRequestHandlers` now accepts a `prepend` option (mirroring `registerRoute`'s `hoist` flag). Prepended handlers are placed before the appended ones, with registration order preserved within each group.
8
+
9
+ MSW evaluates handlers in registration order and a handler returning nothing falls through to the next matching handler, so `prepend` enables middleware-like fall-through handlers (artificial latency, request logging, chaos testing) that must run before the regular handlers — regardless of module registration timing:
10
+
11
+ ```ts
12
+ runtime.registerRequestHandlers([latencyRequestHandler], { prepend: true });
13
+ ```
14
+
3
15
  ## 4.0.20
4
16
 
5
17
  ### Patch Changes
@@ -8,6 +8,7 @@ export interface MswPluginOptions {
8
8
  }
9
9
  export interface MswPluginRegisterRequestHandlersOptions {
10
10
  logger?: Logger;
11
+ prepend?: true;
11
12
  }
12
13
  export declare class MswPlugin extends Plugin {
13
14
  #private;
package/dist/MswPlugin.js CHANGED
@@ -22,8 +22,10 @@ class MswPlugin extends Plugin {
22
22
  return this.#mswState;
23
23
  }
24
24
  registerRequestHandlers(handlers, options = {}) {
25
- const { logger } = options;
26
- this.#requestHandlerRegistry.add(handlers);
25
+ const { logger, prepend } = options;
26
+ this.#requestHandlerRegistry.add(handlers, {
27
+ prepend
28
+ });
27
29
  (logger ? logger : this._runtime.logger).withText("[squide] The following MSW request handlers has been registered:").withObject(handlers).debug();
28
30
  }
29
31
  get requestHandlers() {
@@ -1 +1 @@
1
- {"version":3,"file":"MswPlugin.js","sources":["../src/MswPlugin.ts"],"sourcesContent":["import { Plugin, type Runtime } from \"@squide/core\";\nimport type { Logger } from \"@workleap/logging\";\nimport type { RequestHandler } from \"msw\";\nimport { MswState } from \"./MswState.ts\";\nimport { RequestHandlerRegistry } from \"./RequestHandlerRegistry.ts\";\n\nexport const MswPluginName = \"msw-plugin\";\n\nexport interface MswPluginOptions {\n state?: MswState;\n}\n\nexport interface MswPluginRegisterRequestHandlersOptions {\n logger?: Logger;\n}\n\nexport class MswPlugin extends Plugin {\n readonly #mswState: MswState;\n readonly #requestHandlerRegistry: RequestHandlerRegistry;\n\n constructor(runtime: Runtime, options: MswPluginOptions = {}) {\n const {\n state = new MswState()\n } = options;\n\n super(MswPluginName, runtime);\n\n this.#mswState = state;\n this.#requestHandlerRegistry = new RequestHandlerRegistry(this.#mswState);\n }\n\n get mswState() {\n return this.#mswState;\n }\n\n registerRequestHandlers(handlers: RequestHandler[], options: MswPluginRegisterRequestHandlersOptions = {}) {\n const {\n logger\n } = options;\n\n this.#requestHandlerRegistry.add(handlers);\n\n (logger ? logger : this._runtime.logger)\n .withText(\"[squide] The following MSW request handlers has been registered:\")\n .withObject(handlers)\n .debug();\n }\n\n get requestHandlers(): RequestHandler[] {\n return this.#requestHandlerRegistry.handlers;\n }\n}\n\nexport function getMswPlugin(runtime: Runtime) {\n const plugin = runtime.getPlugin(MswPluginName, {\n throwOnNotFound: false\n }) as MswPlugin;\n\n if (!plugin) {\n throw new Error(\"[squide] The getMswPlugin function is called but no MswPlugin instance has been registered with the runtime. Did you provide a MswPlugin instance to the runtime instance or set the useMsw option of the initializeFirefly function to true?\");\n }\n\n return plugin;\n}\n"],"names":["Plugin","MswState","RequestHandlerRegistry","MswPluginName","MswPlugin","runtime","options","state","handlers","logger","getMswPlugin","plugin","Error"],"mappings":";;;;;;;AAAoD;AAGX;AAC4B;AAE9D,MAAMG,aAAaA,GAAG,aAAa;AAUnC,MAAMC,SAASA,SAASJ,MAAMA;IACxB,SAAS,CAAW;IACpB,uBAAuB,CAAyB;IAEzD,YAAYK,OAAgB,EAAEC,UAA4B,CAAC,CAAC,CAAE;QAC1D,MAAM,EACFC,QAAQ,IAAIN,QAAQA,EAAE,EACzB,GAAGK;QAEJ,KAAK,CAACH,aAAaA,EAAEE;QAErB,IAAI,CAAC,SAAS,GAAGE;QACjB,IAAI,CAAC,uBAAuB,GAAG,IAAIL,sBAAsBA,CAAC,IAAI,CAAC,SAAS;IAC5E;IAEA,IAAI,WAAW;QACX,OAAO,IAAI,CAAC,SAAS;IACzB;IAEA,wBAAwBM,QAA0B,EAAEF,UAAmD,CAAC,CAAC,EAAE;QACvG,MAAM,EACFG,MAAM,EACT,GAAGH;QAEJ,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAACE;QAEhCC,CAAAA,SAASA,SAAS,IAAI,CAAC,QAAQ,CAAC,MAAK,EACjC,QAAQ,CAAC,oEACT,UAAU,CAACD,UACX,KAAK;IACd;IAEA,IAAI,kBAAoC;QACpC,OAAO,IAAI,CAAC,uBAAuB,CAAC,QAAQ;IAChD;AACJ;AAEO,SAASE,YAAYA,CAACL,OAAgB;IACzC,MAAMM,SAASN,QAAQ,SAAS,CAACF,aAAaA,EAAE;QAC5C,iBAAiB;IACrB;IAEA,IAAI,CAACQ,QAAQ;QACT,MAAM,IAAIC,MAAM;IACpB;IAEA,OAAOD;AACX"}
1
+ {"version":3,"file":"MswPlugin.js","sources":["../src/MswPlugin.ts"],"sourcesContent":["import { Plugin, type Runtime } from \"@squide/core\";\nimport type { Logger } from \"@workleap/logging\";\nimport type { RequestHandler } from \"msw\";\nimport { MswState } from \"./MswState.ts\";\nimport { RequestHandlerRegistry } from \"./RequestHandlerRegistry.ts\";\n\nexport const MswPluginName = \"msw-plugin\";\n\nexport interface MswPluginOptions {\n state?: MswState;\n}\n\nexport interface MswPluginRegisterRequestHandlersOptions {\n logger?: Logger;\n prepend?: true;\n}\n\nexport class MswPlugin extends Plugin {\n readonly #mswState: MswState;\n readonly #requestHandlerRegistry: RequestHandlerRegistry;\n\n constructor(runtime: Runtime, options: MswPluginOptions = {}) {\n const {\n state = new MswState()\n } = options;\n\n super(MswPluginName, runtime);\n\n this.#mswState = state;\n this.#requestHandlerRegistry = new RequestHandlerRegistry(this.#mswState);\n }\n\n get mswState() {\n return this.#mswState;\n }\n\n registerRequestHandlers(handlers: RequestHandler[], options: MswPluginRegisterRequestHandlersOptions = {}) {\n const {\n logger,\n prepend\n } = options;\n\n this.#requestHandlerRegistry.add(handlers, { prepend });\n\n (logger ? logger : this._runtime.logger)\n .withText(\"[squide] The following MSW request handlers has been registered:\")\n .withObject(handlers)\n .debug();\n }\n\n get requestHandlers(): RequestHandler[] {\n return this.#requestHandlerRegistry.handlers;\n }\n}\n\nexport function getMswPlugin(runtime: Runtime) {\n const plugin = runtime.getPlugin(MswPluginName, {\n throwOnNotFound: false\n }) as MswPlugin;\n\n if (!plugin) {\n throw new Error(\"[squide] The getMswPlugin function is called but no MswPlugin instance has been registered with the runtime. Did you provide a MswPlugin instance to the runtime instance or set the useMsw option of the initializeFirefly function to true?\");\n }\n\n return plugin;\n}\n"],"names":["Plugin","MswState","RequestHandlerRegistry","MswPluginName","MswPlugin","runtime","options","state","handlers","logger","prepend","getMswPlugin","plugin","Error"],"mappings":";;;;;;;AAAoD;AAGX;AAC4B;AAE9D,MAAMG,aAAaA,GAAG,aAAa;AAWnC,MAAMC,SAASA,SAASJ,MAAMA;IACxB,SAAS,CAAW;IACpB,uBAAuB,CAAyB;IAEzD,YAAYK,OAAgB,EAAEC,UAA4B,CAAC,CAAC,CAAE;QAC1D,MAAM,EACFC,QAAQ,IAAIN,QAAQA,EAAE,EACzB,GAAGK;QAEJ,KAAK,CAACH,aAAaA,EAAEE;QAErB,IAAI,CAAC,SAAS,GAAGE;QACjB,IAAI,CAAC,uBAAuB,GAAG,IAAIL,sBAAsBA,CAAC,IAAI,CAAC,SAAS;IAC5E;IAEA,IAAI,WAAW;QACX,OAAO,IAAI,CAAC,SAAS;IACzB;IAEA,wBAAwBM,QAA0B,EAAEF,UAAmD,CAAC,CAAC,EAAE;QACvG,MAAM,EACFG,MAAM,EACNC,OAAO,EACV,GAAGJ;QAEJ,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAACE,UAAU;YAAEE;QAAQ;QAEpDD,CAAAA,SAASA,SAAS,IAAI,CAAC,QAAQ,CAAC,MAAK,EACjC,QAAQ,CAAC,oEACT,UAAU,CAACD,UACX,KAAK;IACd;IAEA,IAAI,kBAAoC;QACpC,OAAO,IAAI,CAAC,uBAAuB,CAAC,QAAQ;IAChD;AACJ;AAEO,SAASG,YAAYA,CAACN,OAAgB;IACzC,MAAMO,SAASP,QAAQ,SAAS,CAACF,aAAaA,EAAE;QAC5C,iBAAiB;IACrB;IAEA,IAAI,CAACS,QAAQ;QACT,MAAM,IAAIC,MAAM;IACpB;IAEA,OAAOD;AACX"}
@@ -1,8 +1,11 @@
1
1
  import type { RequestHandler } from "msw";
2
2
  import { MswState } from "./MswState.ts";
3
+ export interface RequestHandlerRegistryAddOptions {
4
+ prepend?: true;
5
+ }
3
6
  export declare class RequestHandlerRegistry {
4
7
  #private;
5
8
  constructor(mswState: MswState);
6
- add(handlers: RequestHandler[]): void;
9
+ add(handlers: RequestHandler[], options?: RequestHandlerRegistryAddOptions): void;
7
10
  get handlers(): RequestHandler[];
8
11
  }
@@ -1,19 +1,31 @@
1
1
  class RequestHandlerRegistry {
2
2
  #mswState;
3
- #handlers = [];
3
+ #prependedHandlers = [];
4
+ #appendedHandlers = [];
4
5
  constructor(mswState){
5
6
  this.#mswState = mswState;
6
7
  }
7
- add(handlers) {
8
+ add(handlers, options = {}) {
9
+ const { prepend = false } = options;
8
10
  if (this.#mswState.isReady) {
9
- throw new Error("[squide] MSW request handlers cannot be registered once MSW is started. Did you defer the registration of a MSW request handler?");
11
+ throw new Error("[squide] MSW request handlers cannot be registered once MSW is started. Did you defer the registration of an MSW request handler?");
12
+ }
13
+ if (prepend) {
14
+ this.#prependedHandlers.push(...handlers);
15
+ } else {
16
+ this.#appendedHandlers.push(...handlers);
10
17
  }
11
- this.#handlers.push(...handlers);
12
18
  }
19
+ // Prepended handlers are returned before the appended ones; within each group, the registration
20
+ // order is preserved. MSW evaluates handlers in order, which allows fall-through middleware
21
+ // handlers to be registered ahead of the regular handlers.
13
22
  // Must specify the return type, otherwise we get a TS2742: The inferred type cannot be named without a reference to X. This is likely not portable.
14
23
  // A type annotation is necessary.
15
24
  get handlers() {
16
- return this.#handlers;
25
+ return [
26
+ ...this.#prependedHandlers,
27
+ ...this.#appendedHandlers
28
+ ];
17
29
  }
18
30
  }
19
31
 
@@ -1 +1 @@
1
- {"version":3,"file":"RequestHandlerRegistry.js","sources":["../src/RequestHandlerRegistry.ts"],"sourcesContent":["import type { RequestHandler } from \"msw\";\nimport { MswState } from \"./MswState.ts\";\n\nexport class RequestHandlerRegistry {\n readonly #mswState: MswState;\n readonly #handlers: RequestHandler[] = [];\n\n constructor(mswState: MswState) {\n this.#mswState = mswState;\n }\n\n add(handlers: RequestHandler[]) {\n if (this.#mswState.isReady) {\n throw new Error(\"[squide] MSW request handlers cannot be registered once MSW is started. Did you defer the registration of a MSW request handler?\");\n }\n\n this.#handlers.push(...handlers);\n }\n\n // Must specify the return type, otherwise we get a TS2742: The inferred type cannot be named without a reference to X. This is likely not portable.\n // A type annotation is necessary.\n get handlers(): RequestHandler[] {\n return this.#handlers;\n }\n}\n\n"],"names":["RequestHandlerRegistry","mswState","handlers","Error"],"mappings":"AAGO,MAAMA,sBAAsBA;IACtB,SAAS,CAAW;IACpB,SAAS,GAAqB,EAAE,CAAC;IAE1C,YAAYC,QAAkB,CAAE;QAC5B,IAAI,CAAC,SAAS,GAAGA;IACrB;IAEA,IAAIC,QAA0B,EAAE;QAC5B,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE;YACxB,MAAM,IAAIC,MAAM;QACpB;QAEA,IAAI,CAAC,SAAS,CAAC,IAAI,IAAID;IAC3B;IAEA,oJAAoJ;IACpJ,kCAAkC;IAClC,IAAI,WAA6B;QAC7B,OAAO,IAAI,CAAC,SAAS;IACzB;AACJ"}
1
+ {"version":3,"file":"RequestHandlerRegistry.js","sources":["../src/RequestHandlerRegistry.ts"],"sourcesContent":["import type { RequestHandler } from \"msw\";\nimport { MswState } from \"./MswState.ts\";\n\nexport interface RequestHandlerRegistryAddOptions {\n prepend?: true;\n}\n\nexport class RequestHandlerRegistry {\n readonly #mswState: MswState;\n readonly #prependedHandlers: RequestHandler[] = [];\n readonly #appendedHandlers: RequestHandler[] = [];\n\n constructor(mswState: MswState) {\n this.#mswState = mswState;\n }\n\n add(handlers: RequestHandler[], options: RequestHandlerRegistryAddOptions = {}) {\n const {\n prepend = false\n } = options;\n\n if (this.#mswState.isReady) {\n throw new Error(\"[squide] MSW request handlers cannot be registered once MSW is started. Did you defer the registration of an MSW request handler?\");\n }\n\n if (prepend) {\n this.#prependedHandlers.push(...handlers);\n } else {\n this.#appendedHandlers.push(...handlers);\n }\n }\n\n // Prepended handlers are returned before the appended ones; within each group, the registration\n // order is preserved. MSW evaluates handlers in order, which allows fall-through middleware\n // handlers to be registered ahead of the regular handlers.\n // Must specify the return type, otherwise we get a TS2742: The inferred type cannot be named without a reference to X. This is likely not portable.\n // A type annotation is necessary.\n get handlers(): RequestHandler[] {\n return [...this.#prependedHandlers, ...this.#appendedHandlers];\n }\n}\n\n"],"names":["RequestHandlerRegistry","mswState","handlers","options","prepend","Error"],"mappings":"AAOO,MAAMA,sBAAsBA;IACtB,SAAS,CAAW;IACpB,kBAAkB,GAAqB,EAAE,CAAC;IAC1C,iBAAiB,GAAqB,EAAE,CAAC;IAElD,YAAYC,QAAkB,CAAE;QAC5B,IAAI,CAAC,SAAS,GAAGA;IACrB;IAEA,IAAIC,QAA0B,EAAEC,UAA4C,CAAC,CAAC,EAAE;QAC5E,MAAM,EACFC,UAAU,KAAK,EAClB,GAAGD;QAEJ,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE;YACxB,MAAM,IAAIE,MAAM;QACpB;QAEA,IAAID,SAAS;YACT,IAAI,CAAC,kBAAkB,CAAC,IAAI,IAAIF;QACpC,OAAO;YACH,IAAI,CAAC,iBAAiB,CAAC,IAAI,IAAIA;QACnC;IACJ;IAEA,gGAAgG;IAChG,4FAA4F;IAC5F,2DAA2D;IAC3D,oJAAoJ;IACpJ,kCAAkC;IAClC,IAAI,WAA6B;QAC7B,OAAO;eAAI,IAAI,CAAC,kBAAkB;eAAK,IAAI,CAAC,iBAAiB;SAAC;IAClE;AACJ"}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["export { getMswPlugin, MswPlugin, MswPluginName, type MswPluginOptions, type MswPluginRegisterRequestHandlersOptions } from \"./MswPlugin.ts\";\nexport { MswState, type MswReadyListener, type MswStateOptions } from \"./MswState.ts\";\n\n"],"names":["getMswPlugin","MswPlugin","MswPluginName","MswState"],"mappings":";;AAA6I;AACvD"}
1
+ {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["export { getMswPlugin, MswPlugin, MswPluginName, type MswPluginOptions, type MswPluginRegisterRequestHandlersOptions } from \"./MswPlugin.ts\";\nexport { MswState, type MswReadyListener, type MswStateOptions } from \"./MswState.ts\";\n"],"names":["getMswPlugin","MswPlugin","MswPluginName","MswState"],"mappings":";;AAA6I;AACvD"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@squide/msw",
3
3
  "author": "Workleap",
4
- "version": "4.0.20",
4
+ "version": "4.1.0",
5
5
  "description": "Add support for MSW to @squide application shell.",
6
6
  "license": "Apache-2.0",
7
7
  "repository": {
@@ -36,7 +36,7 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "@workleap/logging": "^1.3.8",
39
- "@squide/core": "^7.0.1"
39
+ "@squide/core": "^7.1.0"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@eslint/js": "9.39.2",
package/src/MswPlugin.ts CHANGED
@@ -12,6 +12,7 @@ export interface MswPluginOptions {
12
12
 
13
13
  export interface MswPluginRegisterRequestHandlersOptions {
14
14
  logger?: Logger;
15
+ prepend?: true;
15
16
  }
16
17
 
17
18
  export class MswPlugin extends Plugin {
@@ -35,10 +36,11 @@ export class MswPlugin extends Plugin {
35
36
 
36
37
  registerRequestHandlers(handlers: RequestHandler[], options: MswPluginRegisterRequestHandlersOptions = {}) {
37
38
  const {
38
- logger
39
+ logger,
40
+ prepend
39
41
  } = options;
40
42
 
41
- this.#requestHandlerRegistry.add(handlers);
43
+ this.#requestHandlerRegistry.add(handlers, { prepend });
42
44
 
43
45
  (logger ? logger : this._runtime.logger)
44
46
  .withText("[squide] The following MSW request handlers has been registered:")
@@ -1,26 +1,42 @@
1
1
  import type { RequestHandler } from "msw";
2
2
  import { MswState } from "./MswState.ts";
3
3
 
4
+ export interface RequestHandlerRegistryAddOptions {
5
+ prepend?: true;
6
+ }
7
+
4
8
  export class RequestHandlerRegistry {
5
9
  readonly #mswState: MswState;
6
- readonly #handlers: RequestHandler[] = [];
10
+ readonly #prependedHandlers: RequestHandler[] = [];
11
+ readonly #appendedHandlers: RequestHandler[] = [];
7
12
 
8
13
  constructor(mswState: MswState) {
9
14
  this.#mswState = mswState;
10
15
  }
11
16
 
12
- add(handlers: RequestHandler[]) {
17
+ add(handlers: RequestHandler[], options: RequestHandlerRegistryAddOptions = {}) {
18
+ const {
19
+ prepend = false
20
+ } = options;
21
+
13
22
  if (this.#mswState.isReady) {
14
- throw new Error("[squide] MSW request handlers cannot be registered once MSW is started. Did you defer the registration of a MSW request handler?");
23
+ throw new Error("[squide] MSW request handlers cannot be registered once MSW is started. Did you defer the registration of an MSW request handler?");
15
24
  }
16
25
 
17
- this.#handlers.push(...handlers);
26
+ if (prepend) {
27
+ this.#prependedHandlers.push(...handlers);
28
+ } else {
29
+ this.#appendedHandlers.push(...handlers);
30
+ }
18
31
  }
19
32
 
33
+ // Prepended handlers are returned before the appended ones; within each group, the registration
34
+ // order is preserved. MSW evaluates handlers in order, which allows fall-through middleware
35
+ // handlers to be registered ahead of the regular handlers.
20
36
  // Must specify the return type, otherwise we get a TS2742: The inferred type cannot be named without a reference to X. This is likely not portable.
21
37
  // A type annotation is necessary.
22
38
  get handlers(): RequestHandler[] {
23
- return this.#handlers;
39
+ return [...this.#prependedHandlers, ...this.#appendedHandlers];
24
40
  }
25
41
  }
26
42
 
package/src/index.ts CHANGED
@@ -1,3 +1,2 @@
1
1
  export { getMswPlugin, MswPlugin, MswPluginName, type MswPluginOptions, type MswPluginRegisterRequestHandlersOptions } from "./MswPlugin.ts";
2
2
  export { MswState, type MswReadyListener, type MswStateOptions } from "./MswState.ts";
3
-