@orpc/server 1.14.11 → 1.14.13

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 (78) hide show
  1. package/README.md +98 -52
  2. package/dist/adapters/aws-lambda/index.d.mts +46 -0
  3. package/dist/adapters/aws-lambda/index.d.ts +46 -0
  4. package/dist/adapters/aws-lambda/index.mjs +40 -0
  5. package/dist/adapters/bun-ws/index.d.mts +36 -0
  6. package/dist/adapters/bun-ws/index.d.ts +36 -0
  7. package/dist/adapters/bun-ws/index.mjs +47 -0
  8. package/dist/adapters/crossws/index.d.mts +21 -45
  9. package/dist/adapters/crossws/index.d.ts +21 -45
  10. package/dist/adapters/crossws/index.mjs +18 -40
  11. package/dist/adapters/fastify/index.d.mts +53 -0
  12. package/dist/adapters/fastify/index.d.ts +53 -0
  13. package/dist/adapters/fastify/index.mjs +52 -0
  14. package/dist/adapters/fetch/index.d.mts +96 -64
  15. package/dist/adapters/fetch/index.d.ts +96 -64
  16. package/dist/adapters/fetch/index.mjs +139 -34
  17. package/dist/adapters/message-port/index.d.mts +34 -49
  18. package/dist/adapters/message-port/index.d.ts +34 -49
  19. package/dist/adapters/message-port/index.mjs +37 -68
  20. package/dist/adapters/node/index.d.mts +71 -63
  21. package/dist/adapters/node/index.d.ts +71 -63
  22. package/dist/adapters/node/index.mjs +113 -36
  23. package/dist/adapters/standard/index.d.mts +18 -16
  24. package/dist/adapters/standard/index.d.ts +18 -16
  25. package/dist/adapters/standard/index.mjs +5 -5
  26. package/dist/adapters/standard-peer/index.d.mts +14 -12
  27. package/dist/adapters/standard-peer/index.d.ts +14 -12
  28. package/dist/adapters/standard-peer/index.mjs +21 -2
  29. package/dist/adapters/websocket/index.d.mts +38 -53
  30. package/dist/adapters/websocket/index.d.ts +38 -53
  31. package/dist/adapters/websocket/index.mjs +42 -59
  32. package/dist/adapters/ws/index.d.mts +31 -0
  33. package/dist/adapters/ws/index.d.ts +31 -0
  34. package/dist/adapters/ws/index.mjs +41 -0
  35. package/dist/helpers/index.d.mts +4 -4
  36. package/dist/helpers/index.d.ts +4 -4
  37. package/dist/helpers/index.mjs +5 -13
  38. package/dist/hibernation/index.d.mts +44 -0
  39. package/dist/hibernation/index.d.ts +44 -0
  40. package/dist/hibernation/index.mjs +65 -0
  41. package/dist/index.d.mts +770 -166
  42. package/dist/index.d.ts +770 -166
  43. package/dist/index.mjs +399 -306
  44. package/dist/plugins/index.d.mts +121 -214
  45. package/dist/plugins/index.d.ts +121 -214
  46. package/dist/plugins/index.mjs +214 -576
  47. package/dist/shared/server.7cEtMB30.d.ts +74 -0
  48. package/dist/shared/server.B8gYOD5g.d.mts +12 -0
  49. package/dist/shared/server.BqadksTP.d.mts +74 -0
  50. package/dist/shared/server.C8_sRzQB.d.mts +42 -0
  51. package/dist/shared/server.CMf4nKky.mjs +230 -0
  52. package/dist/shared/server.ChyoA9XY.d.ts +42 -0
  53. package/dist/shared/server.D8IXzfqT.d.ts +32 -0
  54. package/dist/shared/server.DEBcqOjg.mjs +418 -0
  55. package/dist/shared/{server.W91HSRkE.mjs → server.DZ5BIITo.mjs} +2 -2
  56. package/dist/shared/server.DzE6WeuY.d.mts +32 -0
  57. package/dist/shared/server.EfTOZ2Q7.d.ts +12 -0
  58. package/dist/shared/server.TEVCLCFC.mjs +39 -0
  59. package/dist/shared/server.qKsRrdxW.d.mts +193 -0
  60. package/dist/shared/server.qKsRrdxW.d.ts +193 -0
  61. package/package.json +56 -26
  62. package/dist/extensions/callable.d.mts +0 -10
  63. package/dist/extensions/callable.d.ts +0 -10
  64. package/dist/extensions/callable.mjs +0 -11
  65. package/dist/shared/server.15O7oC1p.d.mts +0 -61
  66. package/dist/shared/server.B4BnEWWm.d.mts +0 -67
  67. package/dist/shared/server.BhsVw7m7.d.ts +0 -104
  68. package/dist/shared/server.BoiFpNT7.mjs +0 -224
  69. package/dist/shared/server.COPVXhDG.mjs +0 -271
  70. package/dist/shared/server.CX4vUnDk.mjs +0 -11
  71. package/dist/shared/server.CcR4kgje.d.mts +0 -206
  72. package/dist/shared/server.CcR4kgje.d.ts +0 -206
  73. package/dist/shared/server.CnN50DHH.d.ts +0 -67
  74. package/dist/shared/server.DBs0rrf9.mjs +0 -41
  75. package/dist/shared/server.DDFizwfU.d.mts +0 -104
  76. package/dist/shared/server.D_QauotT.mjs +0 -30
  77. package/dist/shared/server.DofEOwf-.mjs +0 -237
  78. package/dist/shared/server.m3szVJGU.d.ts +0 -61
package/dist/index.mjs CHANGED
@@ -1,399 +1,492 @@
1
- import { mergeErrorMap, resolveMetaPlugins, getHiddenMetaPlugins, ProcedureContract } from '@orpc/contract';
2
- export { ValidationError, asyncIteratorObject, defineMeta, eventIterator, reconcileORPCError, type } from '@orpc/contract';
3
- import { toArray, bindMethods, getOrBind, isTypescriptObject, resolveMaybeOptionalOptions } from '@orpc/shared';
4
- export { AsyncIteratorClass, asyncIteratorToStream, asyncIteratorToUnproxiedDataStream, asyncIteratorToStream as eventIteratorToStream, asyncIteratorToUnproxiedDataStream as eventIteratorToUnproxiedDataStream, onAsyncIteratorObjectError, onError, onFinish, onReadableStreamError, onStart, onSuccess, streamToAsyncIteratorObject, streamToAsyncIteratorObject as streamToEventIterator } from '@orpc/shared';
5
- import { L as Lazy, P as Procedure, c as createProcedureClient } from './shared/server.DofEOwf-.mjs';
6
- export { a as createORPCErrorConstructorMap, u as unlazy } from './shared/server.DofEOwf-.mjs';
7
- import { D as DecoratedProcedure } from './shared/server.DBs0rrf9.mjs';
8
- import { b as augmentRouter, d as augmentImplementedRouter, e as withHiddenRouterContract, f as createGuardedProcedureLazy, g as getRouter } from './shared/server.BoiFpNT7.mjs';
9
- export { a as DEFAULT_ERROR_STATUS, D as DEFAULT_SUCCESS_STATUS, h as call, c as createContractProcedure, i as getHiddenRouterContract, u as unlazyRouter, j as walkProcedureContractsAsync, w as walkProcedureContractsSync } from './shared/server.BoiFpNT7.mjs';
10
- import { RECURSIVE_CLIENT_UNWRAP_KEYS } from '@orpc/client';
11
- export { COMMON_ERROR_STATUS_MAP, ORPCError, RPCJsonSerializer, RPCSerializer, cloneORPCError, isDefinedError, isInferableError, safe, toORPCError } from '@orpc/client';
12
- export { ErrorEvent, getEventMeta, unwrapEvent, withEventMeta } from '@standardserver/core';
1
+ import { mergeErrorMap, mergeMeta, mergeRoute, mergePrefix, mergeTags, isContractProcedure, getContractRouter, fallbackContractConfig } from '@orpc/contract';
2
+ export { ValidationError, eventIterator, type, validateORPCError } from '@orpc/contract';
3
+ import { P as Procedure, b as addMiddleware, c as createProcedureClient, e as enhanceRouter, l as lazy, s as setHiddenRouterContract, u as unlazy, g as getRouter, i as isProcedure, d as isLazy, f as createAssertedLazyProcedure } from './shared/server.DEBcqOjg.mjs';
4
+ export { L as LAZY_SYMBOL, p as call, r as createAccessibleLazyRouter, a as createContractedProcedure, h as createORPCErrorConstructorMap, q as getHiddenRouterContract, j as getLazyMeta, n as isStartWithMiddlewares, m as mergeCurrentContext, o as mergeMiddlewares, k as middlewareOutputFn, v as resolveContractProcedures, t as traverseContractProcedures, w as unlazyRouter } from './shared/server.DEBcqOjg.mjs';
5
+ import { toORPCError } from '@orpc/client';
6
+ export { ORPCError, isDefinedError, safe } from '@orpc/client';
7
+ import { isObject, resolveMaybeOptionalOptions } from '@orpc/shared';
8
+ export { AsyncIteratorClass, EventPublisher, asyncIteratorToStream as eventIteratorToStream, asyncIteratorToUnproxiedDataStream as eventIteratorToUnproxiedDataStream, onError, onFinish, onStart, onSuccess, streamToAsyncIteratorClass as streamToEventIterator } from '@orpc/shared';
9
+ export { ErrorEvent, getEventMeta, withEventMeta } from '@orpc/standard-server';
10
+
11
+ const DEFAULT_CONFIG = {
12
+ initialInputValidationIndex: 0,
13
+ initialOutputValidationIndex: 0,
14
+ dedupeLeadingMiddlewares: true
15
+ };
16
+ function fallbackConfig(key, value) {
17
+ if (value === void 0) {
18
+ return DEFAULT_CONFIG[key];
19
+ }
20
+ return value;
21
+ }
13
22
 
14
23
  function decorateMiddleware(middleware) {
15
24
  const decorated = ((...args) => middleware(...args));
16
- decorated["~orpc"] = middleware["~orpc"];
17
- Object.defineProperty(decorated, "name", {
18
- value: middleware.name
19
- });
20
- decorated.adaptInput = (adapt) => {
25
+ decorated.mapInput = (mapInput) => {
21
26
  const mapped = decorateMiddleware(
22
- (opts, input, ...args) => {
23
- return middleware(opts, adapt(input), ...args);
24
- }
27
+ (options, input, ...rest) => middleware(options, mapInput(input), ...rest)
25
28
  );
26
- mapped["~orpc"] = middleware["~orpc"];
27
- Object.defineProperty(mapped, "name", {
28
- value: middleware.name
29
- });
30
29
  return mapped;
31
30
  };
32
- decorated.errors = (errors) => {
33
- const newMiddleware = decorateMiddleware(decorated);
34
- newMiddleware["~orpc"] = {
35
- ...decorated["~orpc"],
36
- errorMap: mergeErrorMap(decorated["~orpc"]?.errorMap, errors)
37
- };
38
- return newMiddleware;
39
- };
40
- decorated.use = (usedMiddleware) => {
41
- const merged = decorateMiddleware((opts, ...args) => {
42
- return middleware(
43
- {
44
- ...opts,
45
- async next(nextOpts1) {
46
- const result = await usedMiddleware({
47
- ...opts,
48
- context: { ...opts.context, ...nextOpts1?.context },
49
- next(nextOpts2, ...args2) {
50
- return opts.next({
51
- ...opts,
52
- context: {
53
- ...nextOpts1?.context,
54
- ...nextOpts2?.context
55
- }
56
- }, ...args2);
57
- }
58
- }, ...args);
59
- return {
60
- ...result,
61
- context: {
62
- ...nextOpts1?.context,
63
- ...result.context
64
- }
65
- };
66
- }
67
- },
68
- ...args
69
- );
70
- });
71
- merged["~orpc"] = {
72
- ...decorated["~orpc"],
73
- errorMap: mergeErrorMap(usedMiddleware["~orpc"]?.errorMap, decorated["~orpc"]?.errorMap),
74
- metaPlugins: [
75
- ...toArray(middleware["~orpc"]?.metaPlugins),
76
- ...toArray(usedMiddleware["~orpc"]?.metaPlugins)
77
- ]
78
- };
79
- Object.defineProperty(merged, "name", {
80
- value: `${middleware.name} + ${usedMiddleware.name}`
31
+ decorated.concat = (concatMiddleware, mapInput) => {
32
+ const mapped = mapInput ? decorateMiddleware(concatMiddleware).mapInput(mapInput) : concatMiddleware;
33
+ const concatted = decorateMiddleware((options, input, output, ...rest) => {
34
+ const merged = middleware({
35
+ ...options,
36
+ next: (...[nextOptions1]) => mapped({
37
+ ...options,
38
+ context: { ...options.context, ...nextOptions1?.context },
39
+ next: (...[nextOptions2]) => options.next({ context: { ...nextOptions1?.context, ...nextOptions2?.context } })
40
+ }, input, output, ...rest)
41
+ }, input, output, ...rest);
42
+ return merged;
81
43
  });
82
- return merged;
44
+ return concatted;
83
45
  };
84
46
  return decorated;
85
47
  }
86
48
 
49
+ function createActionableClient(client) {
50
+ const action = async (input) => {
51
+ try {
52
+ return [null, await client(input)];
53
+ } catch (error) {
54
+ if (error instanceof Error && "digest" in error && typeof error.digest === "string" && error.digest.startsWith("NEXT_")) {
55
+ throw error;
56
+ }
57
+ if (error instanceof Response && "options" in error && isObject(error.options) || isObject(error) && error.isNotFound === true) {
58
+ throw error;
59
+ }
60
+ return [toORPCError(error).toJSON(), void 0];
61
+ }
62
+ };
63
+ return action;
64
+ }
65
+
66
+ class DecoratedProcedure extends Procedure {
67
+ /**
68
+ * Adds type-safe custom errors.
69
+ * The provided errors are spared-merged with any existing errors.
70
+ *
71
+ * @see {@link https://orpc.dev/docs/error-handling#type%E2%80%90safe-error-handling Type-Safe Error Handling Docs}
72
+ */
73
+ errors(errors) {
74
+ return new DecoratedProcedure({
75
+ ...this["~orpc"],
76
+ errorMap: mergeErrorMap(this["~orpc"].errorMap, errors)
77
+ });
78
+ }
79
+ /**
80
+ * Sets or updates the metadata.
81
+ * The provided metadata is spared-merged with any existing metadata.
82
+ *
83
+ * @see {@link https://orpc.dev/docs/metadata Metadata Docs}
84
+ */
85
+ meta(meta) {
86
+ return new DecoratedProcedure({
87
+ ...this["~orpc"],
88
+ meta: mergeMeta(this["~orpc"].meta, meta)
89
+ });
90
+ }
91
+ /**
92
+ * Sets or updates the route definition.
93
+ * The provided route is spared-merged with any existing route.
94
+ * This option is typically relevant when integrating with OpenAPI.
95
+ *
96
+ * @see {@link https://orpc.dev/docs/openapi/routing OpenAPI Routing Docs}
97
+ * @see {@link https://orpc.dev/docs/openapi/input-output-structure OpenAPI Input/Output Structure Docs}
98
+ */
99
+ route(route) {
100
+ return new DecoratedProcedure({
101
+ ...this["~orpc"],
102
+ route: mergeRoute(this["~orpc"].route, route)
103
+ });
104
+ }
105
+ use(middleware, mapInput) {
106
+ const mapped = mapInput ? decorateMiddleware(middleware).mapInput(mapInput) : middleware;
107
+ return new DecoratedProcedure({
108
+ ...this["~orpc"],
109
+ middlewares: addMiddleware(this["~orpc"].middlewares, mapped)
110
+ });
111
+ }
112
+ /**
113
+ * Make this procedure callable (works like a function while still being a procedure).
114
+ *
115
+ * @see {@link https://orpc.dev/docs/client/server-side Server-side Client Docs}
116
+ */
117
+ callable(...rest) {
118
+ const client = createProcedureClient(this, ...rest);
119
+ return new Proxy(client, {
120
+ get: (target, key) => {
121
+ return Reflect.has(this, key) ? Reflect.get(this, key) : Reflect.get(target, key);
122
+ },
123
+ has: (target, key) => {
124
+ return Reflect.has(this, key) || Reflect.has(target, key);
125
+ }
126
+ });
127
+ }
128
+ /**
129
+ * Make this procedure compatible with server action.
130
+ *
131
+ * @see {@link https://orpc.dev/docs/server-action Server Action Docs}
132
+ */
133
+ actionable(...rest) {
134
+ const action = createActionableClient(createProcedureClient(this, ...rest));
135
+ return new Proxy(action, {
136
+ get: (target, key) => {
137
+ return Reflect.has(this, key) ? Reflect.get(this, key) : Reflect.get(target, key);
138
+ },
139
+ has: (target, key) => {
140
+ return Reflect.has(this, key) || Reflect.has(target, key);
141
+ }
142
+ });
143
+ }
144
+ }
145
+
87
146
  class Builder {
147
+ /**
148
+ * This property holds the defined options.
149
+ */
88
150
  "~orpc";
89
- constructor(definition) {
90
- this["~orpc"] = definition;
151
+ constructor(def) {
152
+ this["~orpc"] = def;
91
153
  }
92
- static create() {
154
+ /**
155
+ * Sets or overrides the config.
156
+ *
157
+ * @see {@link https://orpc.dev/docs/client/server-side#middlewares-order Middlewares Order Docs}
158
+ * @see {@link https://orpc.dev/docs/best-practices/dedupe-middleware#configuration Dedupe Middleware Docs}
159
+ */
160
+ $config(config) {
161
+ const inputValidationCount = this["~orpc"].inputValidationIndex - fallbackConfig("initialInputValidationIndex", this["~orpc"].config.initialInputValidationIndex);
162
+ const outputValidationCount = this["~orpc"].outputValidationIndex - fallbackConfig("initialOutputValidationIndex", this["~orpc"].config.initialOutputValidationIndex);
93
163
  return new Builder({
94
- errorMap: {},
95
- meta: {},
96
- orderedMiddlewares: []
164
+ ...this["~orpc"],
165
+ config,
166
+ dedupeLeadingMiddlewares: fallbackConfig("dedupeLeadingMiddlewares", config.dedupeLeadingMiddlewares),
167
+ inputValidationIndex: fallbackConfig("initialInputValidationIndex", config.initialInputValidationIndex) + inputValidationCount,
168
+ outputValidationIndex: fallbackConfig("initialOutputValidationIndex", config.initialOutputValidationIndex) + outputValidationCount
97
169
  });
98
170
  }
171
+ /**
172
+ * Set or override the initial context.
173
+ *
174
+ * @see {@link https://orpc.dev/docs/context Context Docs}
175
+ */
99
176
  $context() {
100
- return this;
101
- }
102
- $config(config) {
103
177
  return new Builder({
104
178
  ...this["~orpc"],
105
- ...config
179
+ middlewares: [],
180
+ inputValidationIndex: fallbackConfig("initialInputValidationIndex", this["~orpc"].config.initialInputValidationIndex),
181
+ outputValidationIndex: fallbackConfig("initialOutputValidationIndex", this["~orpc"].config.initialOutputValidationIndex)
106
182
  });
107
183
  }
108
- meta(...plugins) {
109
- const [meta, metaPlugins] = resolveMetaPlugins(
110
- this["~orpc"].meta,
111
- this["~orpc"].metaPlugins,
112
- plugins
113
- );
184
+ /**
185
+ * Sets or overrides the initial meta.
186
+ *
187
+ * @see {@link https://orpc.dev/docs/metadata Metadata Docs}
188
+ */
189
+ $meta(initialMeta) {
114
190
  return new Builder({
115
191
  ...this["~orpc"],
116
- meta,
117
- metaPlugins
192
+ meta: initialMeta
118
193
  });
119
194
  }
120
- errors(errors) {
121
- let builder = new Builder({
195
+ /**
196
+ * Sets or overrides the initial route.
197
+ * This option is typically relevant when integrating with OpenAPI.
198
+ *
199
+ * @see {@link https://orpc.dev/docs/openapi/routing OpenAPI Routing Docs}
200
+ * @see {@link https://orpc.dev/docs/openapi/input-output-structure OpenAPI Input/Output Structure Docs}
201
+ */
202
+ $route(initialRoute) {
203
+ return new Builder({
122
204
  ...this["~orpc"],
123
- errorMap: mergeErrorMap(this["~orpc"].errorMap, errors)
205
+ route: initialRoute
124
206
  });
125
- const plugins = getHiddenMetaPlugins(errors);
126
- if (plugins) {
127
- builder = builder.meta(...plugins);
128
- }
129
- return builder;
130
207
  }
131
- use(middleware) {
132
- let builder = new Builder({
208
+ /**
209
+ * Sets or overrides the initial input schema.
210
+ *
211
+ * @see {@link https://orpc.dev/docs/procedure#initial-configuration Initial Procedure Configuration Docs}
212
+ */
213
+ $input(initialInputSchema) {
214
+ return new Builder({
133
215
  ...this["~orpc"],
134
- errorMap: mergeErrorMap(middleware["~orpc"]?.errorMap ?? {}, this["~orpc"].errorMap),
135
- orderedMiddlewares: [...this["~orpc"].orderedMiddlewares, {
136
- middleware,
137
- inputSchemasLengthAtUse: this["~orpc"].inputSchemas?.length,
138
- outputSchemasLengthAtUse: this["~orpc"].outputSchemas?.length
139
- }]
216
+ inputSchema: initialInputSchema
140
217
  });
141
- if (middleware["~orpc"]?.metaPlugins) {
142
- builder = builder.meta(...middleware["~orpc"]?.metaPlugins);
143
- }
144
- return builder;
145
218
  }
219
+ /**
220
+ * Creates a middleware.
221
+ *
222
+ * @see {@link https://orpc.dev/docs/middleware Middleware Docs}
223
+ */
146
224
  middleware(middleware) {
147
- const allMiddlewares = [
148
- ...this["~orpc"].orderedMiddlewares.map(({ middleware: middleware2 }) => middleware2),
149
- middleware
150
- ];
151
- let current = decorateMiddleware(allMiddlewares.shift());
152
- for (const mid of allMiddlewares) {
153
- current = current.use(mid);
154
- }
155
- current["~orpc"] = {
156
- ...current["~orpc"],
157
- errorMap: this["~orpc"].errorMap,
158
- metaPlugins: [
159
- ...toArray(this["~orpc"].metaPlugins),
160
- ...toArray(middleware["~orpc"]?.metaPlugins)
161
- ]
162
- };
163
- return current;
225
+ return decorateMiddleware(middleware);
164
226
  }
165
- input(schema) {
166
- let builder = new Builder({
227
+ /**
228
+ * Adds type-safe custom errors.
229
+ * The provided errors are spared-merged with any existing errors.
230
+ *
231
+ * @see {@link https://orpc.dev/docs/error-handling#type%E2%80%90safe-error-handling Type-Safe Error Handling Docs}
232
+ */
233
+ errors(errors) {
234
+ return new Builder({
167
235
  ...this["~orpc"],
168
- inputSchemas: [...toArray(this["~orpc"].inputSchemas), schema]
236
+ errorMap: mergeErrorMap(this["~orpc"].errorMap, errors)
169
237
  });
170
- const plugins = getHiddenMetaPlugins(schema);
171
- if (plugins) {
172
- builder = builder.meta(...plugins);
173
- }
174
- return builder;
175
238
  }
176
- output(schema) {
177
- let builder = new Builder({
239
+ use(middleware, mapInput) {
240
+ const mapped = mapInput ? decorateMiddleware(middleware).mapInput(mapInput) : middleware;
241
+ return new Builder({
178
242
  ...this["~orpc"],
179
- outputSchemas: [...toArray(this["~orpc"].outputSchemas), schema]
243
+ middlewares: addMiddleware(this["~orpc"].middlewares, mapped)
180
244
  });
181
- const plugins = getHiddenMetaPlugins(schema);
182
- if (plugins) {
183
- builder = builder.meta(...plugins);
184
- }
185
- return builder;
186
245
  }
187
- handler(handler) {
188
- let procedure = new DecoratedProcedure({
246
+ /**
247
+ * Sets or updates the metadata.
248
+ * The provided metadata is spared-merged with any existing metadata.
249
+ *
250
+ * @see {@link https://orpc.dev/docs/metadata Metadata Docs}
251
+ */
252
+ meta(meta) {
253
+ return new Builder({
189
254
  ...this["~orpc"],
190
- handler
255
+ meta: mergeMeta(this["~orpc"].meta, meta)
191
256
  });
192
- const plugins = getHiddenMetaPlugins(handler);
193
- if (plugins) {
194
- procedure = procedure.meta(...plugins);
195
- }
196
- return procedure;
197
257
  }
198
- router(router) {
199
- return augmentRouter(router, {
258
+ /**
259
+ * Sets or updates the route definition.
260
+ * The provided route is spared-merged with any existing route.
261
+ * This option is typically relevant when integrating with OpenAPI.
262
+ *
263
+ * @see {@link https://orpc.dev/docs/openapi/routing OpenAPI Routing Docs}
264
+ * @see {@link https://orpc.dev/docs/openapi/input-output-structure OpenAPI Input/Output Structure Docs}
265
+ */
266
+ route(route) {
267
+ return new Builder({
200
268
  ...this["~orpc"],
201
- middlewares: this["~orpc"].orderedMiddlewares.map(({ middleware }) => middleware)
269
+ route: mergeRoute(this["~orpc"].route, route)
202
270
  });
203
271
  }
204
- lazy(loader) {
205
- return new Lazy({
206
- loader: async () => {
207
- const { default: router } = await loader();
208
- return {
209
- default: this.router(router)
210
- };
211
- },
212
- meta: this["~orpc"].meta,
213
- metaPlugins: this["~orpc"].metaPlugins
272
+ /**
273
+ * Defines the input validation schema.
274
+ *
275
+ * @see {@link https://orpc.dev/docs/procedure#input-output-validation Input Validation Docs}
276
+ */
277
+ input(schema) {
278
+ return new Builder({
279
+ ...this["~orpc"],
280
+ inputSchema: schema,
281
+ inputValidationIndex: fallbackConfig("initialInputValidationIndex", this["~orpc"].config.initialInputValidationIndex) + this["~orpc"].middlewares.length
214
282
  });
215
283
  }
216
- }
217
- const os = Builder.create();
218
-
219
- class ProcedureImplementer {
220
- "~orpc";
221
- constructor(definition) {
222
- this["~orpc"] = definition;
223
- }
224
- "use"(middleware) {
225
- return new ProcedureImplementer({
284
+ /**
285
+ * Defines the output validation schema.
286
+ *
287
+ * @see {@link https://orpc.dev/docs/procedure#input-output-validation Output Validation Docs}
288
+ */
289
+ output(schema) {
290
+ return new Builder({
226
291
  ...this["~orpc"],
227
- orderedMiddlewares: [...this["~orpc"].orderedMiddlewares, {
228
- middleware,
229
- inputSchemasLengthAtUse: this["~orpc"].inputSchemas?.length,
230
- outputSchemasLengthAtUse: this["~orpc"].outputSchemas?.length
231
- }]
292
+ outputSchema: schema,
293
+ outputValidationIndex: fallbackConfig("initialOutputValidationIndex", this["~orpc"].config.initialOutputValidationIndex) + this["~orpc"].middlewares.length
232
294
  });
233
295
  }
234
- "handler"(handler) {
235
- return new ImplementedProcedure({
296
+ /**
297
+ * Defines the handler of the procedure.
298
+ *
299
+ * @see {@link https://orpc.dev/docs/procedure Procedure Docs}
300
+ */
301
+ handler(handler) {
302
+ return new DecoratedProcedure({
236
303
  ...this["~orpc"],
237
- handler,
238
- /**
239
- * When enabled, errors returned (not thrown) by the handler are passed through as-is,
240
- * rather than being transformed into inferrable errors.
241
- *
242
- * This is intended for the contract-first approach, where the procedure adheres to an
243
- * external contract and returned errors should not affect the inferred contract types.
244
- */
245
- opaqueReturnedErrors: true
304
+ handler
246
305
  });
247
306
  }
248
- }
249
- class ImplementedProcedure extends Procedure {
250
- use(middleware) {
251
- return new ImplementedProcedure({
307
+ /**
308
+ * Prefixes all procedures in the router.
309
+ * The provided prefix is post-appended to any existing router prefix.
310
+ *
311
+ * @note This option does not affect procedures that do not define a path in their route definition.
312
+ *
313
+ * @see {@link https://orpc.dev/docs/openapi/routing#route-prefixes OpenAPI Route Prefixes Docs}
314
+ */
315
+ prefix(prefix) {
316
+ return new Builder({
252
317
  ...this["~orpc"],
253
- orderedMiddlewares: [...this["~orpc"].orderedMiddlewares, {
254
- middleware,
255
- inputSchemasLengthAtUse: this["~orpc"].inputSchemas?.length,
256
- outputSchemasLengthAtUse: this["~orpc"].outputSchemas?.length
257
- }]
318
+ prefix: mergePrefix(this["~orpc"].prefix, prefix)
258
319
  });
259
320
  }
260
- }
261
-
262
- class SharedRouterImplementer {
263
- constructor(contract, config, middlewares) {
264
- this.contract = contract;
265
- this.config = config;
266
- this.middlewares = middlewares;
267
- }
268
- static create(contract, config, middlewares = []) {
269
- return new SharedRouterImplementer(
270
- contract,
271
- config,
272
- middlewares
273
- );
274
- }
275
- use(middleware) {
276
- return createRouterImplementerInternal(this.contract, this.config, [...this.middlewares, middleware]);
277
- }
278
- middleware(middleware) {
279
- const allMiddlewares = [
280
- ...this.middlewares,
281
- middleware
282
- ];
283
- let current = decorateMiddleware(allMiddlewares.shift());
284
- for (const mid of allMiddlewares) {
285
- current = current.use(mid);
286
- }
287
- return current;
321
+ /**
322
+ * Adds tags to all procedures in the router.
323
+ * This helpful when you want to group procedures together in the OpenAPI specification.
324
+ *
325
+ * @see {@link https://orpc.dev/docs/openapi/openapi-specification#operation-metadata OpenAPI Operation Metadata Docs}
326
+ */
327
+ tag(...tags) {
328
+ return new Builder({
329
+ ...this["~orpc"],
330
+ tags: mergeTags(this["~orpc"].tags, tags)
331
+ });
288
332
  }
333
+ /**
334
+ * Applies all of the previously defined options to the specified router.
335
+ *
336
+ * @see {@link https://orpc.dev/docs/router#extending-router Extending Router Docs}
337
+ */
289
338
  router(router) {
290
- if (this.middlewares.length) {
291
- router = augmentImplementedRouter(router, {
292
- ...this.config,
293
- middlewares: this.middlewares
294
- });
295
- }
296
- return withHiddenRouterContract(router, this.contract);
339
+ return enhanceRouter(router, this["~orpc"]);
297
340
  }
341
+ /**
342
+ * Create a lazy router
343
+ * And applies all of the previously defined options to the specified router.
344
+ *
345
+ * @see {@link https://orpc.dev/docs/router#extending-router Extending Router Docs}
346
+ */
298
347
  lazy(loader) {
299
- if (this.middlewares.length) {
300
- const originalLoader = loader;
301
- loader = async () => {
302
- const { default: router } = await originalLoader();
303
- return {
304
- default: augmentImplementedRouter(router, {
305
- ...this.config,
306
- middlewares: this.middlewares
307
- })
308
- };
309
- };
310
- }
311
- return new Lazy({ loader, meta: {} });
348
+ return enhanceRouter(lazy(loader), this["~orpc"]);
312
349
  }
313
350
  }
314
- function createRouterImplementer(contract, config) {
315
- return createRouterImplementerInternal(contract, config, []);
316
- }
317
- function createRouterImplementerInternal(contract, config, middlewares) {
318
- if (contract instanceof ProcedureContract) {
319
- return new ProcedureImplementer({
320
- ...config,
351
+ const os = new Builder({
352
+ config: {},
353
+ route: {},
354
+ meta: {},
355
+ errorMap: {},
356
+ inputValidationIndex: fallbackConfig("initialInputValidationIndex"),
357
+ outputValidationIndex: fallbackConfig("initialOutputValidationIndex"),
358
+ middlewares: [],
359
+ dedupeLeadingMiddlewares: true
360
+ });
361
+
362
+ function implementerInternal(contract, config, middlewares) {
363
+ if (isContractProcedure(contract)) {
364
+ const impl2 = new Builder({
321
365
  ...contract["~orpc"],
322
- orderedMiddlewares: middlewares.map((middleware) => ({ middleware }))
366
+ config,
367
+ middlewares,
368
+ inputValidationIndex: fallbackConfig("initialInputValidationIndex", config?.initialInputValidationIndex) + middlewares.length,
369
+ outputValidationIndex: fallbackConfig("initialOutputValidationIndex", config?.initialOutputValidationIndex) + middlewares.length,
370
+ dedupeLeadingMiddlewares: fallbackConfig("dedupeLeadingMiddlewares", config.dedupeLeadingMiddlewares)
323
371
  });
372
+ return impl2;
324
373
  }
325
- const implementer = {};
326
- for (const key in contract) {
327
- const child = contract[key];
328
- implementer[key] = createRouterImplementerInternal(child, config, middlewares);
329
- }
330
- const shared = bindMethods(SharedRouterImplementer.create(contract, config, middlewares));
331
- for (const key in shared) {
332
- const method = shared[key];
333
- if (key in implementer) {
334
- const child = implementer[key];
335
- implementer[key] = new Proxy(method, {
336
- get(_, p) {
337
- return getOrBind(child, p);
338
- }
339
- });
340
- } else {
341
- implementer[key] = method;
342
- }
343
- }
344
- return implementer;
345
- }
346
-
347
- function implement(contract, config = {}) {
348
- const routerImplementer = createRouterImplementer(contract, config);
349
- const implementer = new Proxy(routerImplementer, {
350
- get(_, p) {
374
+ const impl = new Proxy(contract, {
375
+ get: (target, key) => {
376
+ if (typeof key !== "string") {
377
+ return Reflect.get(target, key);
378
+ }
351
379
  let method;
352
- if (p === "$context") {
353
- method = () => implementer;
354
- } else if (p === "$config") {
355
- method = (incoming) => implement(contract, { ...config, ...incoming });
380
+ if (key === "middleware") {
381
+ method = (mid) => decorateMiddleware(mid);
382
+ } else if (key === "use") {
383
+ method = (mid) => {
384
+ return implementerInternal(
385
+ contract,
386
+ config,
387
+ addMiddleware(middlewares, mid)
388
+ );
389
+ };
390
+ } else if (key === "router") {
391
+ method = (router) => {
392
+ const adapted = enhanceRouter(router, {
393
+ middlewares,
394
+ errorMap: {},
395
+ prefix: void 0,
396
+ tags: void 0,
397
+ dedupeLeadingMiddlewares: fallbackConfig("dedupeLeadingMiddlewares", config.dedupeLeadingMiddlewares)
398
+ });
399
+ return setHiddenRouterContract(adapted, contract);
400
+ };
401
+ } else if (key === "lazy") {
402
+ method = (loader) => {
403
+ const adapted = enhanceRouter(lazy(loader), {
404
+ middlewares,
405
+ errorMap: {},
406
+ prefix: void 0,
407
+ tags: void 0,
408
+ dedupeLeadingMiddlewares: fallbackConfig("dedupeLeadingMiddlewares", config.dedupeLeadingMiddlewares)
409
+ });
410
+ return setHiddenRouterContract(adapted, contract);
411
+ };
412
+ }
413
+ const next = getContractRouter(target, [key]);
414
+ if (!next) {
415
+ return method ?? next;
356
416
  }
357
- const value = getOrBind(routerImplementer, p);
417
+ const nextImpl = implementerInternal(next, config, middlewares);
358
418
  if (method) {
359
- if (!isTypescriptObject(value)) {
360
- return method;
361
- }
362
419
  return new Proxy(method, {
363
- get(_2, p2) {
364
- return getOrBind(value, p2);
420
+ get(_, key2) {
421
+ return Reflect.get(nextImpl, key2);
365
422
  }
366
423
  });
367
424
  }
368
- return value;
425
+ return nextImpl;
426
+ }
427
+ });
428
+ return impl;
429
+ }
430
+ function implement(contract, config = {}) {
431
+ const implInternal = implementerInternal(contract, config, []);
432
+ const impl = new Proxy(implInternal, {
433
+ get: (target, key) => {
434
+ let method;
435
+ if (key === "$context") {
436
+ method = () => impl;
437
+ } else if (key === "$config") {
438
+ method = (config2) => implement(contract, config2);
439
+ }
440
+ const next = Reflect.get(target, key);
441
+ if (!method || !next || typeof next !== "function" && typeof next !== "object") {
442
+ return method || next;
443
+ }
444
+ return new Proxy(method, {
445
+ get(_, key2) {
446
+ return Reflect.get(next, key2);
447
+ }
448
+ });
369
449
  }
370
450
  });
371
- return implementer;
451
+ return impl;
452
+ }
453
+
454
+ function inferRPCMethodFromRouter(router) {
455
+ return async (_, path) => {
456
+ const { default: procedure } = await unlazy(getRouter(router, path));
457
+ if (!isProcedure(procedure)) {
458
+ throw new Error(
459
+ `[inferRPCMethodFromRouter] No valid procedure found at path "${path.join(".")}". This may happen when the router is not properly configured.`
460
+ );
461
+ }
462
+ const method = fallbackContractConfig("defaultMethod", procedure["~orpc"].route.method);
463
+ return method === "HEAD" ? "GET" : method;
464
+ };
372
465
  }
373
466
 
374
467
  function createRouterClient(router, ...rest) {
375
468
  const options = resolveMaybeOptionalOptions(rest);
376
- if (router instanceof Procedure) {
377
- return createProcedureClient(router, options);
469
+ if (isProcedure(router)) {
470
+ const caller = createProcedureClient(router, options);
471
+ return caller;
378
472
  }
379
- const procedureCaller = router instanceof Lazy ? createProcedureClient(createGuardedProcedureLazy(router), options) : {};
473
+ const procedureCaller = isLazy(router) ? createProcedureClient(createAssertedLazyProcedure(router), options) : {};
380
474
  const recursive = new Proxy(procedureCaller, {
381
475
  get(target, key) {
382
- if (typeof key !== "string" || router instanceof Lazy && RECURSIVE_CLIENT_UNWRAP_KEYS.has(key)) {
383
- return getOrBind(target, key);
476
+ if (typeof key !== "string") {
477
+ return Reflect.get(target, key);
384
478
  }
385
479
  const next = getRouter(router, [key]);
386
480
  if (!next) {
387
- return getOrBind(target, key);
481
+ return Reflect.get(target, key);
388
482
  }
389
- const nextClient = createRouterClient(next, {
390
- ...options,
391
- path: [...toArray(options.path), key]
483
+ return createRouterClient(next, {
484
+ ...rest[0],
485
+ path: [...rest[0]?.path ?? [], key]
392
486
  });
393
- return nextClient;
394
487
  }
395
488
  });
396
489
  return recursive;
397
490
  }
398
491
 
399
- export { Builder, DecoratedProcedure, ImplementedProcedure, Lazy, Procedure, ProcedureImplementer, SharedRouterImplementer, augmentImplementedRouter, augmentRouter, createGuardedProcedureLazy, createProcedureClient, createRouterClient, createRouterImplementer, decorateMiddleware, getRouter, implement, os, withHiddenRouterContract };
492
+ export { Builder, DecoratedProcedure, Procedure, addMiddleware, createActionableClient, createAssertedLazyProcedure, createProcedureClient, createRouterClient, decorateMiddleware, enhanceRouter, fallbackConfig, getRouter, implement, implementerInternal, inferRPCMethodFromRouter, isLazy, isProcedure, lazy, os, setHiddenRouterContract, unlazy };