@orpc/experimental-msw 2.0.0-beta.29

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 oRPC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,165 @@
1
+ <h1 align="center">oRPC - Typesafe APIs Made Simple πŸͺ„</h1>
2
+
3
+ <div align="center">
4
+ <a href="https://codecov.io/gh/middleapi/orpc">
5
+ <img alt="codecov" src="https://codecov.io/gh/middleapi/orpc/branch/main/graph/badge.svg">
6
+ </a>
7
+ <a href="https://npmx.dev/package/@orpc/experimental-msw">
8
+ <img alt="weekly downloads" src="https://img.shields.io/npm/dw/%40orpc%2Fexperimental-msw?logo=npm" />
9
+ </a>
10
+ <a href="https://app.codspeed.io/middleapi/orpc?utm_source=badge">
11
+ <img alt="CodSpeed" src="https://img.shields.io/endpoint?url=https://codspeed.io/badge.json" />
12
+ </a>
13
+ <a href="https://github.com/middleapi/orpc/blob/main/LICENSE">
14
+ <img alt="MIT License" src="https://img.shields.io/github/license/middleapi/orpc?logo=open-source-initiative" />
15
+ </a>
16
+ <a href="https://discord.gg/TXEbwRBvQn">
17
+ <img alt="Discord" src="https://img.shields.io/discord/1308966753044398161?color=7389D8&label&logo=discord&logoColor=ffffff" />
18
+ </a>
19
+ <a href="https://deepwiki.com/middleapi/orpc">
20
+ <img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki">
21
+ </a>
22
+ </div>
23
+
24
+ ## Documentation
25
+
26
+ You can read the documentation [here](https://orpc.dev).
27
+
28
+ ## Packages
29
+
30
+ **Core**
31
+
32
+ - [@orpc/contract](https://npmx.dev/package/@orpc/contract): Define API contract as the single source of truth.
33
+ - [@orpc/server](https://npmx.dev/package/@orpc/server): Build APIs or implement contracts.
34
+ - [@orpc/client](https://npmx.dev/package/@orpc/client): Consume APIs with end-to-end type safety.
35
+ - [@orpc/openapi](https://npmx.dev/package/@orpc/openapi): Add OpenAPI compatibility to APIs.
36
+
37
+ **Schema validation**
38
+
39
+ - [@orpc/zod](https://npmx.dev/package/@orpc/zod): Integrate with [Zod](https://zod.dev/).
40
+ - [@orpc/valibot](https://npmx.dev/package/@orpc/valibot): Integrate with [Valibot](https://valibot.dev/).
41
+ - [@orpc/arktype](https://npmx.dev/package/@orpc/arktype): Integrate with [ArkType](https://arktype.io/).
42
+
43
+ **Built-in features**
44
+
45
+ - [@orpc/publisher](https://npmx.dev/package/@orpc/publisher): Pub/Sub with memory, Redis, and Upstash adapters.
46
+ - [@orpc/ratelimit](https://npmx.dev/package/@orpc/ratelimit): Rate limiting with memory, Redis, and Upstash adapters.
47
+ - [@orpc/hibernation](https://npmx.dev/package/@orpc/hibernation): Leverage Hibernation APIs like [Cloudflare's Hibernation WebSocket](https://developers.cloudflare.com/durable-objects/best-practices/websockets/#durable-objects-hibernation-websocket-api).
48
+ - [@orpc/json-schema](https://npmx.dev/package/@orpc/json-schema): Smart coercion for OpenAPI requests.
49
+
50
+ **Framework & ecosystem integrations**
51
+
52
+ - [@orpc/next](https://npmx.dev/package/@orpc/next): Integrate with [Next.js Server Functions](https://nextjs.org/docs/app/getting-started/mutating-data).
53
+ - [@orpc/ai-sdk](https://npmx.dev/package/@orpc/ai-sdk): Turn contracts and procedures into [AI SDK](https://ai-sdk.dev/) tools.
54
+ - [@orpc/tanstack-query](https://npmx.dev/package/@orpc/tanstack-query): Integrate with [TanStack Query](https://tanstack.com/query/latest).
55
+ - [@orpc/pinia-colada](https://npmx.dev/package/@orpc/pinia-colada): Integrate with [Pinia Colada](https://pinia-colada.esm.dev/).
56
+ - [@orpc/swr](https://npmx.dev/package/@orpc/swr): Integrate with [SWR](https://swr.vercel.app/).
57
+ - [@orpc/experimental-msw](https://npmx.dev/package/@orpc/experimental-msw): Mock procedures with [Mock Service Worker](https://mswjs.io/).
58
+ - [@orpc/experimental-effect](https://npmx.dev/package/@orpc/experimental-effect): Integrate with [Effect](https://effect.website/).
59
+ - [@orpc/nest](https://npmx.dev/package/@orpc/nest): Implement your contract with [NestJS](https://nestjs.com/).
60
+ - [@orpc/node](https://npmx.dev/package/@orpc/node): [Node.js](https://nodejs.org/) plugins for static file serving and large uploads.
61
+ - [@orpc/bun](https://npmx.dev/package/@orpc/bun): Adapters for [Bun's Redis](https://bun.sh/).
62
+ - [@orpc/cloudflare](https://npmx.dev/package/@orpc/cloudflare): Adapters for [Cloudflare's RateLimit and Durable Objects](https://developers.cloudflare.com/workers/).
63
+ - [@orpc/trpc](https://npmx.dev/package/@orpc/trpc): Reuse existing [tRPC](https://trpc.io/) routers within oRPC.
64
+
65
+ **Observability**
66
+
67
+ - [@orpc/opentelemetry](https://npmx.dev/package/@orpc/opentelemetry): Integrate with [OpenTelemetry](https://opentelemetry.io/) for distributed tracing.
68
+ - [@orpc/pino](https://npmx.dev/package/@orpc/pino): Integrate with [Pino](https://getpino.io/) for logging.
69
+ - [@orpc/evlog](https://npmx.dev/package/@orpc/evlog): Integrate with [Evlog](https://evlog.dev/) for logging.
70
+
71
+ ## Sponsors
72
+
73
+ Like what we build over at [middleapi](https://github.com/middleapi)? You can help keep it going here: [GitHub Sponsors](https://github.com/sponsors/dinwwwh). Every bit helps! πŸš€
74
+
75
+ ### πŸ† Platinum Sponsor
76
+
77
+ <table>
78
+ <tr>
79
+ <td align="center"><a href="https://screenshotone.com/?ref=orpc" target="_blank" rel="sponsored noopener" title="ScreenshotOne.com"><img src="https://avatars.githubusercontent.com/u/97035603?v=4" width="279" alt="ScreenshotOne.com"/><br />ScreenshotOne.com</a></td>
80
+ </tr>
81
+ </table>
82
+
83
+ ### πŸ₯ˆ Silver Sponsor
84
+
85
+ <table>
86
+ <tr>
87
+ <td align="center"><a href="https://misskey.io/?ref=orpc" target="_blank" rel="sponsored noopener" title="ζ‘δΈŠγ•γ‚“"><img src="https://avatars.githubusercontent.com/u/37681609?u=0dd4c7e4ba937cbb52b068c55914b1d8164dc0c7&amp;v=4" width="209" alt="ζ‘δΈŠγ•γ‚“"/><br />ζ‘δΈŠγ•γ‚“</a></td>
88
+ </tr>
89
+ </table>
90
+
91
+ ### Generous Sponsors
92
+
93
+ <table>
94
+ <tr>
95
+ <td align="center"><a href="https://github.com/ln-markets?ref=orpc" target="_blank" rel="sponsored noopener" title="LN Markets"><img src="https://avatars.githubusercontent.com/u/70597625?v=4" width="167" alt="LN Markets"/><br />LN Markets</a></td>
96
+ </tr>
97
+ </table>
98
+
99
+ ### Sponsors
100
+
101
+ <table>
102
+ <tr>
103
+ <td align="center"><a href="https://github.com/hrmcdonald?ref=orpc" target="_blank" rel="sponsored noopener" title="Reece McDonald"><img src="https://avatars.githubusercontent.com/u/39349270?v=4" width="139" alt="Reece McDonald"/><br />Reece McDonald</a></td>
104
+ <td align="center"><a href="https://github.com/u1-liquid?ref=orpc" target="_blank" rel="sponsored noopener" title="あわわわとーにゅ"><img src="https://avatars.githubusercontent.com/u/17376330?u=de3353804be889f009f7e0a1582daf04d0ab292d&amp;v=4" width="139" alt="あわわわとーにゅ"/><br />あわわわとーにゅ</a></td>
105
+ <td align="center"><a href="https://github.com/nicognaW?ref=orpc" target="_blank" rel="sponsored noopener" title="nk"><img src="https://avatars.githubusercontent.com/u/66731869?u=4699bda3a9092d3ec34fbd959450767bcc8b8b6d&amp;v=4" width="139" alt="nk"/><br />nk</a></td>
106
+ <td align="center"><a href="https://github.com/supastarter?ref=orpc" target="_blank" rel="sponsored noopener" title="supastarter"><img src="https://avatars.githubusercontent.com/u/110960143?v=4" width="139" alt="supastarter"/><br />supastarter</a></td>
107
+ <td align="center"><a href="https://github.com/divmgl?ref=orpc" target="_blank" rel="sponsored noopener" title="Dexter Miguel"><img src="https://avatars.githubusercontent.com/u/5452298?u=645993204be8696c085ecf0d228c3062efe2ed65&amp;v=4" width="139" alt="Dexter Miguel"/><br />Dexter Miguel</a></td>
108
+ <td align="center"><a href="https://github.com/herrfugbaum?ref=orpc" target="_blank" rel="sponsored noopener" title="herrfugbaum"><img src="https://avatars.githubusercontent.com/u/12859776?u=644dc1666d0220bc0468eb0de3c56b919f635b16&amp;v=4" width="139" alt="herrfugbaum"/><br />herrfugbaum</a></td>
109
+ </tr>
110
+ <tr>
111
+ <td align="center"><a href="https://github.com/ryota-murakami?ref=orpc" target="_blank" rel="sponsored noopener" title="Ryota Murakami"><img src="https://avatars.githubusercontent.com/u/5501268?u=599389e03340734325726ca3f8f423c021d47d7f&amp;v=4" width="139" alt="Ryota Murakami"/><br />Ryota Murakami</a></td>
112
+ <td align="center"><a href="https://github.com/dcramer?ref=orpc" target="_blank" rel="sponsored noopener" title="David Cramer"><img src="https://avatars.githubusercontent.com/u/23610?v=4" width="139" alt="David Cramer"/><br />David Cramer</a></td>
113
+ <td align="center"><a href="https://github.com/valerii15298?ref=orpc" target="_blank" rel="sponsored noopener" title="Valerii Petryniak"><img src="https://avatars.githubusercontent.com/u/44531564?u=88ac74d9bacd20401518441907acad21063cd397&amp;v=4" width="139" alt="Valerii Petryniak"/><br />Valerii Petryniak</a></td>
114
+ <td align="center"><a href="https://github.com/letstri?ref=orpc" target="_blank" rel="sponsored noopener" title="Valerii Strilets"><img src="https://avatars.githubusercontent.com/u/13253748?u=c7b10399ccc8f8081e24db94ec32cd9858e86ac3&amp;v=4" width="139" alt="Valerii Strilets"/><br />Valerii Strilets</a></td>
115
+ <td align="center"><a href="https://github.com/K-Mistele?ref=orpc" target="_blank" rel="sponsored noopener" title="Kyle Mistele"><img src="https://avatars.githubusercontent.com/u/18430555?u=3afebeb81de666e35aaac3ed46f14159d7603ffb&amp;v=4" width="139" alt="Kyle Mistele"/><br />Kyle Mistele</a></td>
116
+ <td align="center"><a href="https://github.com/christ12938?ref=orpc" target="_blank" rel="sponsored noopener" title="christ12938"><img src="https://avatars.githubusercontent.com/u/25758598?v=4" width="139" alt="christ12938"/><br />christ12938</a></td>
117
+ </tr>
118
+ <tr>
119
+ <td align="center"><a href="https://github.com/Ryanjso?ref=orpc" target="_blank" rel="sponsored noopener" title="Ryan Soderberg"><img src="https://avatars.githubusercontent.com/u/39172778?u=5ed913c31d57e7221b75784abcad48c7ebddde27&amp;v=4" width="139" alt="Ryan Soderberg"/><br />Ryan Soderberg</a></td>
120
+ <td align="center"><a href="https://github.com/itigoore01?ref=orpc" target="_blank" rel="sponsored noopener" title="shota"><img src="https://avatars.githubusercontent.com/u/11831107?u=c976a6dc7e055eb026304c46c99100ed22b0c8e0&amp;v=4" width="139" alt="shota"/><br />shota</a></td>
121
+ <td align="center"><a href="https://github.com/ellis-driscoll?ref=orpc" target="_blank" rel="sponsored noopener" title="Ellis Driscoll"><img src="https://avatars.githubusercontent.com/u/70685966?u=c5f95bc33b5991d9744abe00052542e4a2ed3cb9&amp;v=4" width="139" alt="Ellis Driscoll"/><br />Ellis Driscoll</a></td>
122
+ <td align="center"><a href="https://github.com/hoangbn?ref=orpc" target="_blank" rel="sponsored noopener" title="Hoang Nguyen"><img src="https://avatars.githubusercontent.com/u/38968280?u=c90084c6de65c56facabab7ba13a72a49ddbc3e4&amp;v=4" width="139" alt="Hoang Nguyen"/><br />Hoang Nguyen</a></td>
123
+ </tr>
124
+ </table>
125
+
126
+ ### Backers
127
+
128
+ <table>
129
+ <tr>
130
+ <td align="center"><a href="https://github.com/rhinodavid?ref=orpc" target="_blank" rel="sponsored noopener" title="David Walsh"><img src="https://avatars.githubusercontent.com/u/5778036?u=b5521f07d2f88c3db2a0dae62b5f2f8357214af0&amp;v=4" width="119" alt="David Walsh"/><br />David Walsh</a></td>
131
+ <td align="center"><a href="https://github.com/Robbe95?ref=orpc" target="_blank" rel="sponsored noopener" title="Robbe Vaes"><img src="https://avatars.githubusercontent.com/u/44748019?u=e0232402c045ad4eac7cbd217f1f47e083103b89&amp;v=4" width="119" alt="Robbe Vaes"/><br />Robbe Vaes</a></td>
132
+ <td align="center"><a href="https://github.com/aidansunbury?ref=orpc" target="_blank" rel="sponsored noopener" title="Aidan Sunbury"><img src="https://avatars.githubusercontent.com/u/64103161?v=4" width="119" alt="Aidan Sunbury"/><br />Aidan Sunbury</a></td>
133
+ <td align="center"><a href="https://github.com/soonoo?ref=orpc" target="_blank" rel="sponsored noopener" title="soonoo"><img src="https://avatars.githubusercontent.com/u/5436405?u=5d0b4aa955c87e30e6bda7f0cccae5402da99528&amp;v=4" width="119" alt="soonoo"/><br />soonoo</a></td>
134
+ <td align="center"><a href="https://github.com/kporten?ref=orpc" target="_blank" rel="sponsored noopener" title="Kevin Porten"><img src="https://avatars.githubusercontent.com/u/1839345?u=dc2263d5cfe0d927ce1a0be04a1d55dd6b55405c&amp;v=4" width="119" alt="Kevin Porten"/><br />Kevin Porten</a></td>
135
+ <td align="center"><a href="https://github.com/pumpkinlink?ref=orpc" target="_blank" rel="sponsored noopener" title="Denis"><img src="https://avatars.githubusercontent.com/u/11864620?u=5f47bbe6c65d0f6f5cf011021490238e4b0593d0&amp;v=4" width="119" alt="Denis"/><br />Denis</a></td>
136
+ <td align="center"><a href="https://github.com/christopher-kapic?ref=orpc" target="_blank" rel="sponsored noopener" title="Christopher Kapic"><img src="https://avatars.githubusercontent.com/u/59740769?u=e7ad4b72b5bf6c9eb1644c26dbf3332a8f987377&amp;v=4" width="119" alt="Christopher Kapic"/><br />Christopher Kapic</a></td>
137
+ </tr>
138
+ <tr>
139
+ <td align="center"><a href="https://github.com/thomasballinger?ref=orpc" target="_blank" rel="sponsored noopener" title="Tom Ballinger"><img src="https://avatars.githubusercontent.com/u/458879?u=4b045ac75d721b6ac2b42a74d7d37f61f0414031&amp;v=4" width="119" alt="Tom Ballinger"/><br />Tom Ballinger</a></td>
140
+ <td align="center"><a href="https://github.com/SSam0419?ref=orpc" target="_blank" rel="sponsored noopener" title="Sam"><img src="https://avatars.githubusercontent.com/u/102863520?u=3c89611f549d5070be232eb4532f690c8f2e7a65&amp;v=4" width="119" alt="Sam"/><br />Sam</a></td>
141
+ <td align="center"><a href="https://github.com/Titoine?ref=orpc" target="_blank" rel="sponsored noopener" title="Titoine"><img src="https://avatars.githubusercontent.com/u/3514286?u=1bb1e86b0c99c8a1121372e56d51a177eea12191&amp;v=4" width="119" alt="Titoine"/><br />Titoine</a></td>
142
+ <td align="center"><a href="https://github.com/Mnigos?ref=orpc" target="_blank" rel="sponsored noopener" title="Igor Makowski"><img src="https://avatars.githubusercontent.com/u/56691628?u=ee8c879478f7c151b9156aef6c74243fa3e247a8&amp;v=4" width="119" alt="Igor Makowski"/><br />Igor Makowski</a></td>
143
+ <td align="center"><a href="https://github.com/hanayashiki?ref=orpc" target="_blank" rel="sponsored noopener" title="hanayashiki"><img src="https://avatars.githubusercontent.com/u/26056783?u=06c3b9205a16fd41a871e82da1cc2a09306d53f5&amp;v=4" width="119" alt="hanayashiki"/><br />hanayashiki</a></td>
144
+ <td align="center"><a href="https://github.com/ldub?ref=orpc" target="_blank" rel="sponsored noopener" title="Lev Dubinets"><img src="https://avatars.githubusercontent.com/u/3114081?u=f547f5d5012cab54851f1b1ad72d10e537f78fc2&amp;v=4" width="119" alt="Lev Dubinets"/><br />Lev Dubinets</a></td>
145
+ <td align="center"><a href="https://github.com/mr-kelly?ref=orpc" target="_blank" rel="sponsored noopener" title="Kelly Peilin Chan"><img src="https://avatars.githubusercontent.com/u/520852?u=6b0f7105f694e7b5cacf410a3f04c7044b469dc8&amp;v=4" width="119" alt="Kelly Peilin Chan"/><br />Kelly Peilin Chan</a></td>
146
+ </tr>
147
+ <tr>
148
+ <td align="center"><a href="https://github.com/guyariely?ref=orpc" target="_blank" rel="sponsored noopener" title="Guy Ariely"><img src="https://avatars.githubusercontent.com/u/42813496?u=edb6b7f563bf28e160a290832e7da57c0506f8ca&amp;v=4" width="119" alt="Guy Ariely"/><br />Guy Ariely</a></td>
149
+ <td align="center"><a href="https://github.com/piscis?ref=orpc" target="_blank" rel="sponsored noopener" title="Alex"><img src="https://avatars.githubusercontent.com/u/326163?u=b245f368bd940cf51d08c0b6bf55f8257f359437&amp;v=4" width="119" alt="Alex"/><br />Alex</a></td>
150
+ <td align="center"><a href="https://github.com/finom?ref=orpc" target="_blank" rel="sponsored noopener" title="Andrey Gubanov"><img src="https://avatars.githubusercontent.com/u/1082083?u=c5f2daf7ebece498e85c83367bb37b4e10e2649d&amp;v=4" width="119" alt="Andrey Gubanov"/><br />Andrey Gubanov</a></td>
151
+ </tr>
152
+ </table>
153
+
154
+ With thanks to 37 past sponsors who helped get oRPC here.
155
+
156
+ ## References
157
+
158
+ oRPC is inspired by existing solutions that prioritize type safety and developer experience. Special acknowledgments to:
159
+
160
+ - [tRPC](https://trpc.io): For pioneering the concept of end-to-end type-safe RPC and influencing the development of type-safe APIs.
161
+ - [ts-rest](https://ts-rest.com): For its emphasis on contract-first development and OpenAPI integration, which have greatly inspired oRPC's feature set.
162
+
163
+ ## License
164
+
165
+ Distributed under the MIT License. See [LICENSE](https://github.com/middleapi/orpc/blob/main/LICENSE) for more information.
@@ -0,0 +1,127 @@
1
+ import { AnyORPCError } from '@orpc/client';
2
+ import { AnySchema, ErrorMap, AnyProcedureContract, InferSchemaOutput, InferSchemaInput, ORPCErrorConstructorMap, RouterContract, ProcedureContract } from '@orpc/contract';
3
+ import { Context, ProcedureConfig, Router, ProcedureHandler } from '@orpc/server';
4
+ import { FetchHandler } from '@orpc/server/fetch';
5
+ import { Value, Promisable } from '@orpc/shared';
6
+ import { ResponseResolverInfo, HttpRequestResolverExtras, PathParams, HttpHandler } from 'msw';
7
+
8
+ type HTTPProcedureUtilsOptions<TContext extends Context> = ProcedureConfig & {
9
+ /**
10
+ * The origin requests are matched against. Supports MSW wildcards.
11
+ * Set `''` to match only same-origin requests in the browser.
12
+ *
13
+ * @default '*'
14
+ */
15
+ origin?: string;
16
+ /**
17
+ * The path prefix procedures are served under, matching the `prefix`
18
+ * the corresponding handler is mounted at in production.
19
+ */
20
+ prefix?: `/${string}`;
21
+ /**
22
+ * Creates the fetch handler that serves each mock, using the same
23
+ * configuration as your production handler, such as plugins. Requests are
24
+ * matched entirely by the created handler, so any protocol works.
25
+ *
26
+ * The router passed in contains only the procedure being mocked. Requests
27
+ * the created handler does not match fall through to other MSW handlers.
28
+ *
29
+ * @see {@link https://orpc.dev/docs/integrations/msw#advanced-configuration | MSW Integration - Advanced Configuration}
30
+ */
31
+ handler: (router: Router<TContext>) => NoInfer<FetchHandler<TContext>>;
32
+ } & (object extends TContext ? {
33
+ /**
34
+ * The context passed to the created handler for each request, resolved
35
+ * with the MSW resolver information. Mock handlers receive it as
36
+ * `context`, enabling context-driven behaviors such as the Response
37
+ * Headers Plugin.
38
+ *
39
+ * Optional when an empty object can satisfy the context type,
40
+ * required otherwise.
41
+ *
42
+ * @see {@link https://orpc.dev/docs/integrations/msw#advanced-configuration | MSW Integration - Advanced Configuration}
43
+ */
44
+ context?: Value<Promisable<TContext>, [info: ResponseResolverInfo<HttpRequestResolverExtras<PathParams>>]>;
45
+ } : {
46
+ /**
47
+ * The context passed to the created handler for each request, resolved
48
+ * with the MSW resolver information. Mock handlers receive it as
49
+ * `context`, enabling context-driven behaviors such as the Response
50
+ * Headers Plugin.
51
+ *
52
+ * Optional when an empty object can satisfy the context type,
53
+ * required otherwise.
54
+ *
55
+ * @see {@link https://orpc.dev/docs/integrations/msw#advanced-configuration | MSW Integration - Advanced Configuration}
56
+ */
57
+ context: Value<Promisable<TContext>, [info: ResponseResolverInfo<HttpRequestResolverExtras<PathParams>>]>;
58
+ });
59
+ /**
60
+ * Creates typed MSW HTTP request handlers for a procedure-contract. Requests
61
+ * are matched and served by a real fetch handler, so routing, serialization,
62
+ * validation, and error envelopes always match the production handler.
63
+ *
64
+ * @see {@link https://orpc.dev/docs/integrations/msw | MSW Integration}
65
+ */
66
+ declare class HTTPProcedureUtils<TContext extends Context, TInputSchema extends AnySchema, TOutputSchema extends AnySchema, TErrorMap extends ErrorMap> {
67
+ private readonly contract;
68
+ private readonly path;
69
+ private readonly options;
70
+ /**
71
+ * Matches every request under `origin` + `prefix`, the created fetch
72
+ * handler decides whether a request targets this procedure.
73
+ */
74
+ private readonly mswPathPredicate;
75
+ private readonly prefix;
76
+ constructor(contract: AnyProcedureContract, path: readonly string[], options: HTTPProcedureUtilsOptions<TContext>);
77
+ /**
78
+ * Creates an MSW request handler that resolves the procedure with the given
79
+ * mock implementation.
80
+ *
81
+ * @see {@link https://orpc.dev/docs/integrations/msw#mocking-procedures | MSW Integration - Mocking Procedures}
82
+ */
83
+ handler(handler: ProcedureHandler<TContext, InferSchemaOutput<TInputSchema>, AnyORPCError | InferSchemaInput<TOutputSchema>, ORPCErrorConstructorMap<TErrorMap>>): HttpHandler;
84
+ /**
85
+ * Creates an MSW request handler that rejects the procedure with an error
86
+ * defined in the contract, serialized exactly like a server-thrown error.
87
+ *
88
+ * @see {@link https://orpc.dev/docs/integrations/msw#mocking-errors | MSW Integration - Mocking Errors}
89
+ */
90
+ error<TCode extends keyof TErrorMap>(code: TCode, ...rest: Parameters<ORPCErrorConstructorMap<TErrorMap>[TCode]>): HttpHandler;
91
+ /**
92
+ * Creates an MSW request handler that never resolves, useful for testing
93
+ * loading states. It rejects once the request is aborted, releasing the
94
+ * pending request's resources.
95
+ *
96
+ * @see {@link https://orpc.dev/docs/integrations/msw#mocking-loading-states | MSW Integration - Mocking Loading States}
97
+ */
98
+ loading(): HttpHandler;
99
+ /**
100
+ * Creates an MSW request handler that performs matching requests against
101
+ * the real server as-is, useful to exempt a procedure from mocking.
102
+ *
103
+ * @see {@link https://orpc.dev/docs/integrations/msw#passthrough | MSW Integration - Passthrough}
104
+ */
105
+ passthrough(): HttpHandler;
106
+ /**
107
+ * Serves the procedure through the fetch handler created by the `handler`
108
+ * option and resolves the MSW response from its result.
109
+ */
110
+ private toMSWHandler;
111
+ }
112
+
113
+ type HTTPRouterUtils<T extends RouterContract, TContext extends Context> = T extends ProcedureContract<infer UInputSchema, infer UOutputSchema, infer UErrorMap> ? HTTPProcedureUtils<TContext, UInputSchema, UOutputSchema, UErrorMap> : {
114
+ [K in keyof T]: T[K] extends RouterContract ? HTTPRouterUtils<T[K], TContext> : never;
115
+ };
116
+ type HTTPRouterUtilsOptions<TContext extends Context> = HTTPProcedureUtilsOptions<TContext>;
117
+ /**
118
+ * Creates MSW HTTP utils from a router-contract (or an implemented router),
119
+ * exposing typed MSW request handler builders for every procedure, served
120
+ * through the fetch handler created by the `handler` option.
121
+ *
122
+ * @see {@link https://orpc.dev/docs/integrations/msw | MSW Integration}
123
+ */
124
+ declare function createHTTPUtils<T extends RouterContract, TContext extends Context = object>(contract: T, options: HTTPRouterUtilsOptions<TContext>): HTTPRouterUtils<T, TContext>;
125
+
126
+ export { HTTPProcedureUtils, createHTTPUtils };
127
+ export type { HTTPProcedureUtilsOptions, HTTPRouterUtils, HTTPRouterUtilsOptions };
@@ -0,0 +1,127 @@
1
+ import { AnyORPCError } from '@orpc/client';
2
+ import { AnySchema, ErrorMap, AnyProcedureContract, InferSchemaOutput, InferSchemaInput, ORPCErrorConstructorMap, RouterContract, ProcedureContract } from '@orpc/contract';
3
+ import { Context, ProcedureConfig, Router, ProcedureHandler } from '@orpc/server';
4
+ import { FetchHandler } from '@orpc/server/fetch';
5
+ import { Value, Promisable } from '@orpc/shared';
6
+ import { ResponseResolverInfo, HttpRequestResolverExtras, PathParams, HttpHandler } from 'msw';
7
+
8
+ type HTTPProcedureUtilsOptions<TContext extends Context> = ProcedureConfig & {
9
+ /**
10
+ * The origin requests are matched against. Supports MSW wildcards.
11
+ * Set `''` to match only same-origin requests in the browser.
12
+ *
13
+ * @default '*'
14
+ */
15
+ origin?: string;
16
+ /**
17
+ * The path prefix procedures are served under, matching the `prefix`
18
+ * the corresponding handler is mounted at in production.
19
+ */
20
+ prefix?: `/${string}`;
21
+ /**
22
+ * Creates the fetch handler that serves each mock, using the same
23
+ * configuration as your production handler, such as plugins. Requests are
24
+ * matched entirely by the created handler, so any protocol works.
25
+ *
26
+ * The router passed in contains only the procedure being mocked. Requests
27
+ * the created handler does not match fall through to other MSW handlers.
28
+ *
29
+ * @see {@link https://orpc.dev/docs/integrations/msw#advanced-configuration | MSW Integration - Advanced Configuration}
30
+ */
31
+ handler: (router: Router<TContext>) => NoInfer<FetchHandler<TContext>>;
32
+ } & (object extends TContext ? {
33
+ /**
34
+ * The context passed to the created handler for each request, resolved
35
+ * with the MSW resolver information. Mock handlers receive it as
36
+ * `context`, enabling context-driven behaviors such as the Response
37
+ * Headers Plugin.
38
+ *
39
+ * Optional when an empty object can satisfy the context type,
40
+ * required otherwise.
41
+ *
42
+ * @see {@link https://orpc.dev/docs/integrations/msw#advanced-configuration | MSW Integration - Advanced Configuration}
43
+ */
44
+ context?: Value<Promisable<TContext>, [info: ResponseResolverInfo<HttpRequestResolverExtras<PathParams>>]>;
45
+ } : {
46
+ /**
47
+ * The context passed to the created handler for each request, resolved
48
+ * with the MSW resolver information. Mock handlers receive it as
49
+ * `context`, enabling context-driven behaviors such as the Response
50
+ * Headers Plugin.
51
+ *
52
+ * Optional when an empty object can satisfy the context type,
53
+ * required otherwise.
54
+ *
55
+ * @see {@link https://orpc.dev/docs/integrations/msw#advanced-configuration | MSW Integration - Advanced Configuration}
56
+ */
57
+ context: Value<Promisable<TContext>, [info: ResponseResolverInfo<HttpRequestResolverExtras<PathParams>>]>;
58
+ });
59
+ /**
60
+ * Creates typed MSW HTTP request handlers for a procedure-contract. Requests
61
+ * are matched and served by a real fetch handler, so routing, serialization,
62
+ * validation, and error envelopes always match the production handler.
63
+ *
64
+ * @see {@link https://orpc.dev/docs/integrations/msw | MSW Integration}
65
+ */
66
+ declare class HTTPProcedureUtils<TContext extends Context, TInputSchema extends AnySchema, TOutputSchema extends AnySchema, TErrorMap extends ErrorMap> {
67
+ private readonly contract;
68
+ private readonly path;
69
+ private readonly options;
70
+ /**
71
+ * Matches every request under `origin` + `prefix`, the created fetch
72
+ * handler decides whether a request targets this procedure.
73
+ */
74
+ private readonly mswPathPredicate;
75
+ private readonly prefix;
76
+ constructor(contract: AnyProcedureContract, path: readonly string[], options: HTTPProcedureUtilsOptions<TContext>);
77
+ /**
78
+ * Creates an MSW request handler that resolves the procedure with the given
79
+ * mock implementation.
80
+ *
81
+ * @see {@link https://orpc.dev/docs/integrations/msw#mocking-procedures | MSW Integration - Mocking Procedures}
82
+ */
83
+ handler(handler: ProcedureHandler<TContext, InferSchemaOutput<TInputSchema>, AnyORPCError | InferSchemaInput<TOutputSchema>, ORPCErrorConstructorMap<TErrorMap>>): HttpHandler;
84
+ /**
85
+ * Creates an MSW request handler that rejects the procedure with an error
86
+ * defined in the contract, serialized exactly like a server-thrown error.
87
+ *
88
+ * @see {@link https://orpc.dev/docs/integrations/msw#mocking-errors | MSW Integration - Mocking Errors}
89
+ */
90
+ error<TCode extends keyof TErrorMap>(code: TCode, ...rest: Parameters<ORPCErrorConstructorMap<TErrorMap>[TCode]>): HttpHandler;
91
+ /**
92
+ * Creates an MSW request handler that never resolves, useful for testing
93
+ * loading states. It rejects once the request is aborted, releasing the
94
+ * pending request's resources.
95
+ *
96
+ * @see {@link https://orpc.dev/docs/integrations/msw#mocking-loading-states | MSW Integration - Mocking Loading States}
97
+ */
98
+ loading(): HttpHandler;
99
+ /**
100
+ * Creates an MSW request handler that performs matching requests against
101
+ * the real server as-is, useful to exempt a procedure from mocking.
102
+ *
103
+ * @see {@link https://orpc.dev/docs/integrations/msw#passthrough | MSW Integration - Passthrough}
104
+ */
105
+ passthrough(): HttpHandler;
106
+ /**
107
+ * Serves the procedure through the fetch handler created by the `handler`
108
+ * option and resolves the MSW response from its result.
109
+ */
110
+ private toMSWHandler;
111
+ }
112
+
113
+ type HTTPRouterUtils<T extends RouterContract, TContext extends Context> = T extends ProcedureContract<infer UInputSchema, infer UOutputSchema, infer UErrorMap> ? HTTPProcedureUtils<TContext, UInputSchema, UOutputSchema, UErrorMap> : {
114
+ [K in keyof T]: T[K] extends RouterContract ? HTTPRouterUtils<T[K], TContext> : never;
115
+ };
116
+ type HTTPRouterUtilsOptions<TContext extends Context> = HTTPProcedureUtilsOptions<TContext>;
117
+ /**
118
+ * Creates MSW HTTP utils from a router-contract (or an implemented router),
119
+ * exposing typed MSW request handler builders for every procedure, served
120
+ * through the fetch handler created by the `handler` option.
121
+ *
122
+ * @see {@link https://orpc.dev/docs/integrations/msw | MSW Integration}
123
+ */
124
+ declare function createHTTPUtils<T extends RouterContract, TContext extends Context = object>(contract: T, options: HTTPRouterUtilsOptions<TContext>): HTTPRouterUtils<T, TContext>;
125
+
126
+ export { HTTPProcedureUtils, createHTTPUtils };
127
+ export type { HTTPProcedureUtilsOptions, HTTPRouterUtils, HTTPRouterUtilsOptions };
package/dist/index.mjs ADDED
@@ -0,0 +1,109 @@
1
+ import { implement } from '@orpc/server';
2
+ import { value, isTypescriptObject } from '@orpc/shared';
3
+ import { passthrough, http } from 'msw';
4
+ import { ProcedureContract } from '@orpc/contract';
5
+
6
+ class HTTPProcedureUtils {
7
+ constructor(contract, path, options) {
8
+ this.contract = contract;
9
+ this.path = path;
10
+ this.options = options;
11
+ const origin = this.options.origin ?? "*";
12
+ this.prefix = this.options.prefix === void 0 ? void 0 : `/${this.options.prefix.replace(/\/+$/, "").slice(1)}`;
13
+ const base = `${origin}${this.prefix === void 0 || this.prefix === "/" ? "" : this.prefix}`;
14
+ this.mswPathPredicate = base === "" || base === "*" ? "*" : `${base}/*`;
15
+ }
16
+ /**
17
+ * Matches every request under `origin` + `prefix`, the created fetch
18
+ * handler decides whether a request targets this procedure.
19
+ */
20
+ mswPathPredicate;
21
+ prefix;
22
+ /**
23
+ * Creates an MSW request handler that resolves the procedure with the given
24
+ * mock implementation.
25
+ *
26
+ * @see {@link https://orpc.dev/docs/integrations/msw#mocking-procedures | MSW Integration - Mocking Procedures}
27
+ */
28
+ handler(handler) {
29
+ const procedure = implement(this.contract, {
30
+ disableInputValidation: this.options.disableInputValidation,
31
+ disableOutputValidation: this.options.disableOutputValidation
32
+ }).handler(handler);
33
+ return this.toMSWHandler(procedure, ({ matched, response }) => matched ? response : void 0);
34
+ }
35
+ /**
36
+ * Creates an MSW request handler that rejects the procedure with an error
37
+ * defined in the contract, serialized exactly like a server-thrown error.
38
+ *
39
+ * @see {@link https://orpc.dev/docs/integrations/msw#mocking-errors | MSW Integration - Mocking Errors}
40
+ */
41
+ error(code, ...rest) {
42
+ return this.handler(({ errors }) => {
43
+ throw errors[code](...rest);
44
+ });
45
+ }
46
+ /**
47
+ * Creates an MSW request handler that never resolves, useful for testing
48
+ * loading states. It rejects once the request is aborted, releasing the
49
+ * pending request's resources.
50
+ *
51
+ * @see {@link https://orpc.dev/docs/integrations/msw#mocking-loading-states | MSW Integration - Mocking Loading States}
52
+ */
53
+ loading() {
54
+ return this.handler(({ signal }) => new Promise((_, reject) => {
55
+ signal?.addEventListener("abort", () => reject(signal.reason), { once: true });
56
+ }));
57
+ }
58
+ /**
59
+ * Creates an MSW request handler that performs matching requests against
60
+ * the real server as-is, useful to exempt a procedure from mocking.
61
+ *
62
+ * @see {@link https://orpc.dev/docs/integrations/msw#passthrough | MSW Integration - Passthrough}
63
+ */
64
+ passthrough() {
65
+ const procedure = implement(this.contract, {
66
+ disableInputValidation: true,
67
+ disableOutputValidation: true
68
+ }).handler(() => void 0);
69
+ return this.toMSWHandler(procedure, ({ matched }) => matched ? passthrough() : void 0, true);
70
+ }
71
+ /**
72
+ * Serves the procedure through the fetch handler created by the `handler`
73
+ * option and resolves the MSW response from its result.
74
+ */
75
+ toMSWHandler(procedure, resolve, cloneRequest = false) {
76
+ const router = this.path.reduceRight(
77
+ (acc, segment) => ({ [segment]: acc }),
78
+ procedure
79
+ );
80
+ const fetchHandler = this.options.handler(router);
81
+ return http.all(this.mswPathPredicate, async (info) => {
82
+ const context = await value(this.options.context, info) ?? {};
83
+ const result = await fetchHandler.handle(cloneRequest ? info.request.clone() : info.request, {
84
+ prefix: this.prefix,
85
+ context
86
+ });
87
+ return resolve(result);
88
+ });
89
+ }
90
+ }
91
+
92
+ function createHTTPUtils(contract, options) {
93
+ return createHTTPUtilsInternal(contract, options, []);
94
+ }
95
+ function createHTTPUtilsInternal(contract, options, path) {
96
+ if (contract instanceof ProcedureContract) {
97
+ return new HTTPProcedureUtils(contract, path, options);
98
+ }
99
+ if (!isTypescriptObject(contract)) {
100
+ return contract;
101
+ }
102
+ const utils = {};
103
+ for (const key in contract) {
104
+ utils[key] = createHTTPUtilsInternal(contract[key], options, [...path, key]);
105
+ }
106
+ return utils;
107
+ }
108
+
109
+ export { HTTPProcedureUtils, createHTTPUtils };
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@orpc/experimental-msw",
3
+ "type": "module",
4
+ "version": "2.0.0-beta.29",
5
+ "description": "MSW integration for oRPC: mock procedures at the network level with typed MSW request handlers",
6
+ "license": "MIT",
7
+ "funding": "https://github.com/sponsors/dinwwwh",
8
+ "homepage": "https://orpc.dev",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/middleapi/orpc.git",
12
+ "directory": "packages/msw"
13
+ },
14
+ "keywords": [
15
+ "orpc",
16
+ "msw",
17
+ "mock-service-worker"
18
+ ],
19
+ "sideEffects": false,
20
+ "exports": {
21
+ "./package.json": "./package.json",
22
+ ".": {
23
+ "types": "./dist/index.d.mts",
24
+ "import": "./dist/index.mjs",
25
+ "default": "./dist/index.mjs"
26
+ }
27
+ },
28
+ "files": [
29
+ "dist"
30
+ ],
31
+ "peerDependencies": {
32
+ "msw": ">=2.0.0"
33
+ },
34
+ "dependencies": {
35
+ "@orpc/contract": "2.0.0-beta.29",
36
+ "@orpc/shared": "2.0.0-beta.29",
37
+ "@orpc/server": "2.0.0-beta.29",
38
+ "@orpc/client": "2.0.0-beta.29"
39
+ },
40
+ "devDependencies": {
41
+ "msw": "^2.15.0",
42
+ "zod": "^4.4.3",
43
+ "@orpc/openapi": "2.0.0-beta.29"
44
+ },
45
+ "scripts": {
46
+ "build": "unbuild",
47
+ "type:check": "tsc -b"
48
+ }
49
+ }