@temporary-name/server 1.9.3-alpha.592ae1e02e18c5274906b132313b083116248636 → 1.9.3-alpha.5dc8b200530586870ac736830d4584e0333cfd05
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/adapters/aws-lambda/index.d.mts +3 -4
- package/dist/adapters/aws-lambda/index.d.ts +3 -4
- package/dist/adapters/aws-lambda/index.mjs +4 -6
- package/dist/adapters/fetch/index.d.mts +3 -4
- package/dist/adapters/fetch/index.d.ts +3 -4
- package/dist/adapters/fetch/index.mjs +4 -6
- package/dist/adapters/node/index.d.mts +3 -4
- package/dist/adapters/node/index.d.ts +3 -4
- package/dist/adapters/node/index.mjs +4 -6
- package/dist/adapters/standard/index.d.mts +20 -32
- package/dist/adapters/standard/index.d.ts +20 -32
- package/dist/adapters/standard/index.mjs +5 -7
- package/dist/helpers/index.mjs +3 -29
- package/dist/index.d.mts +71 -339
- package/dist/index.d.ts +71 -339
- package/dist/index.mjs +218 -355
- package/dist/openapi/index.d.mts +1 -1
- package/dist/openapi/index.d.ts +1 -1
- package/dist/openapi/index.mjs +60 -77
- package/dist/plugins/index.d.mts +4 -80
- package/dist/plugins/index.d.ts +4 -80
- package/dist/plugins/index.mjs +17 -189
- package/dist/shared/{server.CQyYNJ1H.d.ts → server.B-meye9-.d.ts} +2 -4
- package/dist/shared/{server.DLsti1Pv.mjs → server.Ba0Z2fNc.mjs} +58 -97
- package/dist/shared/server.C1RJffw4.mjs +30 -0
- package/dist/shared/server.DkYpsO6W.d.mts +251 -0
- package/dist/shared/server.DkYpsO6W.d.ts +251 -0
- package/dist/shared/{server.SLLuK6_v.d.ts → server.DwNnHUZP.d.ts} +2 -2
- package/dist/shared/{server.BeuTpcmO.d.mts → server.I-tTl_ce.d.mts} +2 -2
- package/dist/shared/{server.BEHw7Eyx.mjs → server.JtIZ8YG7.mjs} +1 -11
- package/dist/shared/server.miXh-9wo.mjs +416 -0
- package/dist/shared/{server.C1fnTLq0.d.mts → server.vLcMd_kA.d.mts} +2 -4
- package/package.json +10 -21
- package/dist/shared/server.BKSOrA6h.d.mts +0 -192
- package/dist/shared/server.BKSOrA6h.d.ts +0 -192
- package/dist/shared/server.BKh8I1Ny.mjs +0 -239
package/dist/index.mjs
CHANGED
|
@@ -1,334 +1,175 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { ValidationError, eventIterator,
|
|
3
|
-
import { onError, resolveMaybeOptionalOptions } from '@temporary-name/shared';
|
|
1
|
+
import { mergePrefix, mergeTags, ContractProcedure, mergeErrorMap, mergeMeta, parseEndpointDefinition, mergeRoute, prefixRoute, initialSchemas, isContractProcedure, getContractRouter } from '@temporary-name/contract';
|
|
2
|
+
export { ValidationError, eventIterator, validateORPCError } from '@temporary-name/contract';
|
|
3
|
+
import { assertNever, splitFirst, ORPCError, onError, resolveMaybeOptionalOptions } from '@temporary-name/shared';
|
|
4
4
|
export { AsyncIteratorClass, EventPublisher, ORPCError, asyncIteratorToStream as eventIteratorToStream, isDefinedError, onError, onFinish, onStart, onSuccess, safe, streamToAsyncIteratorClass as streamToEventIterator } from '@temporary-name/shared';
|
|
5
|
-
import {
|
|
6
|
-
|
|
5
|
+
import { SchemaClass, object, core, gatingContext } from '@temporary-name/zod';
|
|
6
|
+
import { g as getCookie } from './shared/server.C1RJffw4.mjs';
|
|
7
|
+
import { P as Procedure, c as createProcedureClient, e as enhanceRouter, a as addMiddleware, s as setHiddenRouterContract, l as lazyInternal, g as getLazyMeta, u as unlazy, i as isProcedure, b as isLazy, d as getRouter } from './shared/server.miXh-9wo.mjs';
|
|
8
|
+
export { L as LAZY_SYMBOL, p as createAccessibleLazyRouter, f as createORPCErrorConstructorMap, o as getHiddenRouterContract, k as isStartWithMiddlewares, h as lazy, m as mergeCurrentContext, n as mergeMiddlewares, j as middlewareOutputFn, r as resolveContractProcedures, t as traverseContractProcedures, q as unlazyRouter } from './shared/server.miXh-9wo.mjs';
|
|
7
9
|
export { getEventMeta, withEventMeta } from '@temporary-name/standard-server';
|
|
8
|
-
import '
|
|
9
|
-
import 'zod';
|
|
10
|
-
import 'zod/v4/core';
|
|
10
|
+
import 'cookie';
|
|
11
11
|
|
|
12
|
-
function
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const mapped = decorateMiddleware(
|
|
16
|
-
(options, input, ...rest) => middleware(options, mapInput(input), ...rest)
|
|
17
|
-
);
|
|
18
|
-
return mapped;
|
|
19
|
-
};
|
|
20
|
-
decorated.concat = (concatMiddleware, mapInput) => {
|
|
21
|
-
const mapped = mapInput ? decorateMiddleware(concatMiddleware).mapInput(mapInput) : concatMiddleware;
|
|
22
|
-
const concatted = decorateMiddleware((options, input, output, ...rest) => {
|
|
23
|
-
const merged = middleware(
|
|
24
|
-
{
|
|
25
|
-
...options,
|
|
26
|
-
next: (...[nextOptions1]) => mapped(
|
|
27
|
-
{
|
|
28
|
-
...options,
|
|
29
|
-
context: { ...options.context, ...nextOptions1?.context },
|
|
30
|
-
next: (...[nextOptions2]) => options.next({ context: { ...nextOptions1?.context, ...nextOptions2?.context } })
|
|
31
|
-
},
|
|
32
|
-
input,
|
|
33
|
-
output,
|
|
34
|
-
...rest
|
|
35
|
-
)
|
|
36
|
-
},
|
|
37
|
-
input,
|
|
38
|
-
output,
|
|
39
|
-
...rest
|
|
40
|
-
);
|
|
41
|
-
return merged;
|
|
42
|
-
});
|
|
43
|
-
return concatted;
|
|
44
|
-
};
|
|
45
|
-
return decorated;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function isStartWithMiddlewares(middlewares, compare) {
|
|
49
|
-
if (compare.length > middlewares.length) {
|
|
50
|
-
return false;
|
|
51
|
-
}
|
|
52
|
-
for (let i = 0; i < middlewares.length; i++) {
|
|
53
|
-
if (compare[i] === void 0) {
|
|
54
|
-
return true;
|
|
55
|
-
}
|
|
56
|
-
if (middlewares[i] !== compare[i]) {
|
|
57
|
-
return false;
|
|
58
|
-
}
|
|
12
|
+
function validateTokenPrefix(prefix, token) {
|
|
13
|
+
if (prefix && !token.startsWith(prefix)) {
|
|
14
|
+
throw new ORPCError("UNAUTHORIZED", { message: `Invalid auth token. It must start with "${prefix}"` });
|
|
59
15
|
}
|
|
60
|
-
return true;
|
|
61
16
|
}
|
|
62
|
-
function
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
17
|
+
function validateTokenAuth(config, token, options) {
|
|
18
|
+
const { tokenPrefix, validate } = config;
|
|
19
|
+
validateTokenPrefix(tokenPrefix, token);
|
|
20
|
+
return validate(token, options);
|
|
21
|
+
}
|
|
22
|
+
function authByQuery(config, options) {
|
|
23
|
+
const { name, tokenPrefix, validate } = config;
|
|
24
|
+
const query = options.request.url.searchParams;
|
|
25
|
+
const token = query.get(name);
|
|
26
|
+
if (!token) return void 0;
|
|
27
|
+
validateTokenPrefix(tokenPrefix, token);
|
|
28
|
+
return validate(token, options);
|
|
29
|
+
}
|
|
30
|
+
function authByHeader(config, options) {
|
|
31
|
+
const authHeader = options.request.headers.get(config.name);
|
|
32
|
+
return authHeader ? validateTokenAuth(config, authHeader, options) : void 0;
|
|
33
|
+
}
|
|
34
|
+
function authByCookie(config, options) {
|
|
35
|
+
const cookie = getCookie(options.request.headers, config.name);
|
|
36
|
+
return cookie ? validateTokenAuth(config, cookie, options) : void 0;
|
|
67
37
|
}
|
|
68
|
-
function
|
|
69
|
-
|
|
38
|
+
function authByBearer(config, options) {
|
|
39
|
+
const authHeader = options.request.headers.get("Authorization");
|
|
40
|
+
if (!authHeader) return void 0;
|
|
41
|
+
const [authType, bearer] = splitFirst(authHeader, " ");
|
|
42
|
+
return authType === "Bearer" ? validateTokenAuth(config, bearer, options) : void 0;
|
|
43
|
+
}
|
|
44
|
+
function authByBasic(config, options) {
|
|
45
|
+
const authHeader = options.request.headers.get("Authorization");
|
|
46
|
+
if (!authHeader) return void 0;
|
|
47
|
+
const [authType, encoded] = splitFirst(authHeader, " ");
|
|
48
|
+
if (authType !== "Basic") return void 0;
|
|
49
|
+
const decoded = Buffer.from(encoded, "base64").toString("utf-8");
|
|
50
|
+
const [username, password] = splitFirst(decoded, ":");
|
|
51
|
+
validateTokenPrefix(config.tokenPrefix, password);
|
|
52
|
+
return config.validate(username, password, options);
|
|
53
|
+
}
|
|
54
|
+
function authByType(config, options) {
|
|
55
|
+
const { type } = config;
|
|
56
|
+
return type === "header" ? authByHeader(config, options) : type === "query" ? authByQuery(config, options) : type === "cookie" ? authByCookie(config, options) : type === "bearer" ? authByBearer(config, options) : type === "basic" ? authByBasic(config, options) : type === "none" ? false : assertNever(type);
|
|
57
|
+
}
|
|
58
|
+
function authDescription(config) {
|
|
59
|
+
const { type } = config;
|
|
60
|
+
return type === "basic" ? "a Basic Authentication header" : type === "bearer" ? "a Bearer Authentication header" : type === "header" ? `a header named "${config.name}"` : type === "query" ? `a query parameter named "${config.name}"` : type === "cookie" ? `a cookie named "${config.name}"` : type === "none" ? "no authentication" : assertNever(type);
|
|
70
61
|
}
|
|
71
62
|
|
|
72
|
-
class Procedure {
|
|
63
|
+
class DecoratedProcedure extends Procedure {
|
|
73
64
|
/**
|
|
74
|
-
*
|
|
65
|
+
* Make this procedure callable (works like a function while still being a procedure).
|
|
66
|
+
*
|
|
67
|
+
* @see {@link https://orpc.unnoq.com/docs/client/server-side Server-side Client Docs}
|
|
75
68
|
*/
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
69
|
+
callable(...rest) {
|
|
70
|
+
const client = createProcedureClient(this, ...rest);
|
|
71
|
+
return new Proxy(client, {
|
|
72
|
+
get: (target, key) => {
|
|
73
|
+
return Reflect.has(this, key) ? Reflect.get(this, key) : Reflect.get(target, key);
|
|
74
|
+
},
|
|
75
|
+
has: (target, key) => {
|
|
76
|
+
return Reflect.has(this, key) || Reflect.has(target, key);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
84
79
|
}
|
|
85
|
-
return isContractProcedure(item) && "middlewares" in item["~orpc"] && "inputValidationIndex" in item["~orpc"] && "outputValidationIndex" in item["~orpc"] && "handler" in item["~orpc"];
|
|
86
80
|
}
|
|
87
81
|
|
|
88
|
-
class
|
|
82
|
+
class ProcedureBuilder extends ContractProcedure {
|
|
83
|
+
z;
|
|
84
|
+
constructor(def) {
|
|
85
|
+
super(def);
|
|
86
|
+
this.z = new SchemaClass();
|
|
87
|
+
}
|
|
89
88
|
/**
|
|
90
|
-
* Adds type-safe custom errors.
|
|
91
|
-
* The provided errors are spared-merged with any existing errors.
|
|
89
|
+
* Adds type-safe custom errors to the contract.
|
|
90
|
+
* The provided errors are spared-merged with any existing errors in the contract.
|
|
92
91
|
*
|
|
93
92
|
* @see {@link https://orpc.unnoq.com/docs/error-handling#type%E2%80%90safe-error-handling Type-Safe Error Handling Docs}
|
|
94
93
|
*/
|
|
95
94
|
errors(errors) {
|
|
96
|
-
return new
|
|
95
|
+
return new ProcedureBuilder({
|
|
97
96
|
...this["~orpc"],
|
|
98
97
|
errorMap: mergeErrorMap(this["~orpc"].errorMap, errors)
|
|
99
98
|
});
|
|
100
99
|
}
|
|
101
100
|
/**
|
|
102
|
-
* Sets or updates the metadata.
|
|
103
|
-
* The provided metadata is spared-merged with any existing metadata.
|
|
101
|
+
* Sets or updates the metadata for the contract.
|
|
102
|
+
* The provided metadata is spared-merged with any existing metadata in the contract.
|
|
104
103
|
*
|
|
105
104
|
* @see {@link https://orpc.unnoq.com/docs/metadata Metadata Docs}
|
|
106
105
|
*/
|
|
107
106
|
meta(meta) {
|
|
108
|
-
return new
|
|
107
|
+
return new ProcedureBuilder({
|
|
109
108
|
...this["~orpc"],
|
|
110
109
|
meta: mergeMeta(this["~orpc"].meta, meta)
|
|
111
110
|
});
|
|
112
111
|
}
|
|
112
|
+
endpoint(stringsOrEndpoint, ...values) {
|
|
113
|
+
const { method, path, pathSchema } = parseEndpointDefinition(stringsOrEndpoint, values);
|
|
114
|
+
const { prefix } = this["~orpc"];
|
|
115
|
+
const route = { method, path };
|
|
116
|
+
return new ProcedureBuilder({
|
|
117
|
+
...this["~orpc"],
|
|
118
|
+
route: mergeRoute(this["~orpc"].route, prefix ? prefixRoute(route, prefix) : route),
|
|
119
|
+
schemas: {
|
|
120
|
+
...this["~orpc"].schemas,
|
|
121
|
+
pathSchema
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
113
125
|
/**
|
|
114
|
-
* Sets or updates the route definition.
|
|
115
|
-
* The provided route is spared-merged with any existing route.
|
|
126
|
+
* Sets or updates the route definition for the contract.
|
|
127
|
+
* The provided route is spared-merged with any existing route in the contract.
|
|
116
128
|
* This option is typically relevant when integrating with OpenAPI.
|
|
117
129
|
*
|
|
118
130
|
* @see {@link https://orpc.unnoq.com/docs/openapi/routing OpenAPI Routing Docs}
|
|
119
131
|
* @see {@link https://orpc.unnoq.com/docs/openapi/input-output-structure OpenAPI Input/Output Structure Docs}
|
|
120
132
|
*/
|
|
121
|
-
|
|
122
|
-
|
|
133
|
+
endpointOpts(route) {
|
|
134
|
+
const { prefix } = this["~orpc"];
|
|
135
|
+
return new ProcedureBuilder({
|
|
123
136
|
...this["~orpc"],
|
|
124
|
-
route: mergeRoute(this["~orpc"].route, route)
|
|
137
|
+
route: mergeRoute(this["~orpc"].route, prefix ? prefixRoute(route, prefix) : route)
|
|
125
138
|
});
|
|
126
139
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
return new DecoratedProcedure({
|
|
140
|
+
query(schema) {
|
|
141
|
+
return new ProcedureBuilder({
|
|
130
142
|
...this["~orpc"],
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Make this procedure callable (works like a function while still being a procedure).
|
|
136
|
-
*
|
|
137
|
-
* @see {@link https://orpc.unnoq.com/docs/client/server-side Server-side Client Docs}
|
|
138
|
-
*/
|
|
139
|
-
callable(...rest) {
|
|
140
|
-
const client = createProcedureClient(this, ...rest);
|
|
141
|
-
return new Proxy(client, {
|
|
142
|
-
get: (target, key) => {
|
|
143
|
-
return Reflect.has(this, key) ? Reflect.get(this, key) : Reflect.get(target, key);
|
|
143
|
+
schemas: {
|
|
144
|
+
...this["~orpc"].schemas,
|
|
145
|
+
querySchema: schema instanceof core.$ZodType ? schema : object(schema)
|
|
144
146
|
},
|
|
145
|
-
|
|
146
|
-
return Reflect.has(this, key) || Reflect.has(target, key);
|
|
147
|
-
}
|
|
147
|
+
inputValidationIndex: this["~orpc"].middlewares.length
|
|
148
148
|
});
|
|
149
149
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
if (key === HIDDEN_ROUTER_CONTRACT_SYMBOL) {
|
|
157
|
-
return contract;
|
|
158
|
-
}
|
|
159
|
-
return Reflect.get(target, key);
|
|
160
|
-
}
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
function getHiddenRouterContract(router) {
|
|
164
|
-
return router[HIDDEN_ROUTER_CONTRACT_SYMBOL];
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
function getRouter(router, path) {
|
|
168
|
-
let current = router;
|
|
169
|
-
for (let i = 0; i < path.length; i++) {
|
|
170
|
-
const segment = path[i];
|
|
171
|
-
if (!current) {
|
|
172
|
-
return void 0;
|
|
173
|
-
}
|
|
174
|
-
if (isProcedure(current)) {
|
|
175
|
-
return void 0;
|
|
176
|
-
}
|
|
177
|
-
if (!isLazy(current)) {
|
|
178
|
-
current = current[segment];
|
|
179
|
-
continue;
|
|
180
|
-
}
|
|
181
|
-
const lazied = current;
|
|
182
|
-
const rest = path.slice(i);
|
|
183
|
-
return lazy(async () => {
|
|
184
|
-
const unwrapped = await unlazy(lazied);
|
|
185
|
-
const next = getRouter(unwrapped.default, rest);
|
|
186
|
-
return unlazy(next);
|
|
187
|
-
}, getLazyMeta(lazied));
|
|
188
|
-
}
|
|
189
|
-
return current;
|
|
190
|
-
}
|
|
191
|
-
function createAccessibleLazyRouter(lazied) {
|
|
192
|
-
const recursive = new Proxy(lazied, {
|
|
193
|
-
get(target, key) {
|
|
194
|
-
if (typeof key !== "string") {
|
|
195
|
-
return Reflect.get(target, key);
|
|
196
|
-
}
|
|
197
|
-
const next = getRouter(lazied, [key]);
|
|
198
|
-
return createAccessibleLazyRouter(next);
|
|
199
|
-
}
|
|
200
|
-
});
|
|
201
|
-
return recursive;
|
|
202
|
-
}
|
|
203
|
-
function enhanceRouter(router, options) {
|
|
204
|
-
if (isLazy(router)) {
|
|
205
|
-
const laziedMeta = getLazyMeta(router);
|
|
206
|
-
const enhancedPrefix = laziedMeta?.prefix ? mergePrefix(options.prefix, laziedMeta?.prefix) : options.prefix;
|
|
207
|
-
const enhanced2 = lazy(
|
|
208
|
-
async () => {
|
|
209
|
-
const { default: unlaziedRouter } = await unlazy(router);
|
|
210
|
-
const enhanced3 = enhanceRouter(unlaziedRouter, options);
|
|
211
|
-
return unlazy(enhanced3);
|
|
150
|
+
body(schema) {
|
|
151
|
+
return new ProcedureBuilder({
|
|
152
|
+
...this["~orpc"],
|
|
153
|
+
schemas: {
|
|
154
|
+
...this["~orpc"].schemas,
|
|
155
|
+
bodySchema: schema instanceof core.$ZodType ? schema : object(schema)
|
|
212
156
|
},
|
|
213
|
-
|
|
214
|
-
...laziedMeta,
|
|
215
|
-
prefix: enhancedPrefix
|
|
216
|
-
}
|
|
217
|
-
);
|
|
218
|
-
const accessible = createAccessibleLazyRouter(enhanced2);
|
|
219
|
-
return accessible;
|
|
220
|
-
}
|
|
221
|
-
if (isProcedure(router)) {
|
|
222
|
-
const newMiddlewares = mergeMiddlewares(options.middlewares, router["~orpc"].middlewares, {
|
|
223
|
-
dedupeLeading: options.dedupeLeadingMiddlewares
|
|
224
|
-
});
|
|
225
|
-
const newMiddlewareAdded = newMiddlewares.length - router["~orpc"].middlewares.length;
|
|
226
|
-
const enhanced2 = new Procedure({
|
|
227
|
-
...router["~orpc"],
|
|
228
|
-
route: enhanceRoute(router["~orpc"].route, options),
|
|
229
|
-
errorMap: mergeErrorMap(options.errorMap, router["~orpc"].errorMap),
|
|
230
|
-
middlewares: newMiddlewares,
|
|
231
|
-
inputValidationIndex: router["~orpc"].inputValidationIndex + newMiddlewareAdded,
|
|
232
|
-
outputValidationIndex: router["~orpc"].outputValidationIndex + newMiddlewareAdded
|
|
233
|
-
});
|
|
234
|
-
return enhanced2;
|
|
235
|
-
}
|
|
236
|
-
const enhanced = {};
|
|
237
|
-
for (const key in router) {
|
|
238
|
-
enhanced[key] = enhanceRouter(router[key], options);
|
|
239
|
-
}
|
|
240
|
-
return enhanced;
|
|
241
|
-
}
|
|
242
|
-
function traverseContractProcedures(options, callback, lazyOptions = []) {
|
|
243
|
-
let currentRouter = options.router;
|
|
244
|
-
const hiddenContract = getHiddenRouterContract(options.router);
|
|
245
|
-
if (hiddenContract !== void 0) {
|
|
246
|
-
currentRouter = hiddenContract;
|
|
247
|
-
}
|
|
248
|
-
if (isLazy(currentRouter)) {
|
|
249
|
-
lazyOptions.push({
|
|
250
|
-
router: currentRouter,
|
|
251
|
-
path: options.path
|
|
252
|
-
});
|
|
253
|
-
} else if (isContractProcedure(currentRouter)) {
|
|
254
|
-
callback({
|
|
255
|
-
contract: currentRouter,
|
|
256
|
-
path: options.path
|
|
157
|
+
inputValidationIndex: this["~orpc"].middlewares.length
|
|
257
158
|
});
|
|
258
|
-
} else {
|
|
259
|
-
for (const key in currentRouter) {
|
|
260
|
-
traverseContractProcedures(
|
|
261
|
-
{
|
|
262
|
-
router: currentRouter[key],
|
|
263
|
-
path: [...options.path, key]
|
|
264
|
-
},
|
|
265
|
-
callback,
|
|
266
|
-
lazyOptions
|
|
267
|
-
);
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
return lazyOptions;
|
|
271
|
-
}
|
|
272
|
-
async function resolveContractProcedures(options, callback) {
|
|
273
|
-
const pending = [options];
|
|
274
|
-
for (const options2 of pending) {
|
|
275
|
-
const lazyOptions = traverseContractProcedures(options2, callback);
|
|
276
|
-
for (const options3 of lazyOptions) {
|
|
277
|
-
const { default: router } = await unlazy(options3.router);
|
|
278
|
-
pending.push({
|
|
279
|
-
router,
|
|
280
|
-
path: options3.path
|
|
281
|
-
});
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
async function unlazyRouter(router) {
|
|
286
|
-
if (isProcedure(router)) {
|
|
287
|
-
return router;
|
|
288
|
-
}
|
|
289
|
-
const unlazied = {};
|
|
290
|
-
for (const key in router) {
|
|
291
|
-
const item = router[key];
|
|
292
|
-
const { default: unlaziedRouter } = await unlazy(item);
|
|
293
|
-
unlazied[key] = await unlazyRouter(unlaziedRouter);
|
|
294
|
-
}
|
|
295
|
-
return unlazied;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
class Builder {
|
|
299
|
-
/**
|
|
300
|
-
* This property holds the defined options.
|
|
301
|
-
*/
|
|
302
|
-
"~orpc";
|
|
303
|
-
constructor(def) {
|
|
304
|
-
this["~orpc"] = def;
|
|
305
|
-
}
|
|
306
|
-
/**
|
|
307
|
-
* Set or override the initial context.
|
|
308
|
-
*
|
|
309
|
-
* @see {@link https://orpc.unnoq.com/docs/context Context Docs}
|
|
310
|
-
*/
|
|
311
|
-
$context() {
|
|
312
|
-
return this;
|
|
313
|
-
}
|
|
314
|
-
/**
|
|
315
|
-
* Creates a middleware.
|
|
316
|
-
*
|
|
317
|
-
* @see {@link https://orpc.unnoq.com/docs/middleware Middleware Docs}
|
|
318
|
-
*/
|
|
319
|
-
middleware(middleware) {
|
|
320
|
-
return decorateMiddleware(middleware);
|
|
321
159
|
}
|
|
322
160
|
/**
|
|
323
|
-
*
|
|
324
|
-
* The provided errors are spared-merged with any existing errors.
|
|
161
|
+
* Defines the output validation schema.
|
|
325
162
|
*
|
|
326
|
-
* @see {@link https://orpc.unnoq.com/docs/
|
|
163
|
+
* @see {@link https://orpc.unnoq.com/docs/procedure#input-output-validation Output Validation Docs}
|
|
327
164
|
*/
|
|
328
|
-
|
|
329
|
-
return new
|
|
165
|
+
output(schema) {
|
|
166
|
+
return new ProcedureBuilder({
|
|
330
167
|
...this["~orpc"],
|
|
331
|
-
|
|
168
|
+
schemas: {
|
|
169
|
+
...this["~orpc"].schemas,
|
|
170
|
+
outputSchema: schema instanceof core.$ZodType ? schema : object(schema)
|
|
171
|
+
},
|
|
172
|
+
outputValidationIndex: this["~orpc"].middlewares.length
|
|
332
173
|
});
|
|
333
174
|
}
|
|
334
175
|
/**
|
|
@@ -339,8 +180,38 @@ class Builder {
|
|
|
339
180
|
* @see {@link https://orpc.unnoq.com/docs/middleware Middleware Docs}
|
|
340
181
|
*/
|
|
341
182
|
use(middleware) {
|
|
342
|
-
return new
|
|
183
|
+
return new this.constructor({
|
|
184
|
+
...this["~orpc"],
|
|
185
|
+
middlewares: addMiddleware(this["~orpc"].middlewares, middleware)
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
// `& {}` is so AuthType will be expanded in parameter info tooltips.
|
|
189
|
+
// The default of false for ValidatedAuthContext is used when you pass in the type 'none'. We use false
|
|
190
|
+
// because we can't use null or undefined (see ValidatedAuthContext) but we still want it to be falsy.
|
|
191
|
+
useAuth(type, ...rest) {
|
|
192
|
+
const config = { type, ...rest[0] };
|
|
193
|
+
const middleware = os.$context().middleware(async (options) => {
|
|
194
|
+
const { next, context } = options;
|
|
195
|
+
if (context.auth) return next();
|
|
196
|
+
const auth = await authByType(config, options);
|
|
197
|
+
if (auth === void 0) {
|
|
198
|
+
const { authConfigs } = options.procedure["~orpc"];
|
|
199
|
+
if (context.auth !== false && config === authConfigs.at(-1)) {
|
|
200
|
+
let authDescriptions = authConfigs.map(authDescription).join(", ");
|
|
201
|
+
if (authConfigs.length > 1) {
|
|
202
|
+
authDescriptions = `one of: ${authDescriptions}`;
|
|
203
|
+
}
|
|
204
|
+
throw new ORPCError("UNAUTHORIZED", {
|
|
205
|
+
message: `Authentication required. You must provide ${authDescriptions}`
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
return next();
|
|
209
|
+
}
|
|
210
|
+
return next({ context: { auth } });
|
|
211
|
+
});
|
|
212
|
+
return new this.constructor({
|
|
343
213
|
...this["~orpc"],
|
|
214
|
+
authConfigs: [...this["~orpc"].authConfigs, config],
|
|
344
215
|
middlewares: addMiddleware(this["~orpc"].middlewares, middleware)
|
|
345
216
|
});
|
|
346
217
|
}
|
|
@@ -352,67 +223,22 @@ class Builder {
|
|
|
352
223
|
);
|
|
353
224
|
});
|
|
354
225
|
}
|
|
355
|
-
/**
|
|
356
|
-
* Sets or updates the metadata.
|
|
357
|
-
* The provided metadata is spared-merged with any existing metadata.
|
|
358
|
-
*
|
|
359
|
-
* @see {@link https://orpc.unnoq.com/docs/metadata Metadata Docs}
|
|
360
|
-
*/
|
|
361
|
-
meta(meta) {
|
|
362
|
-
return new Builder({
|
|
363
|
-
...this["~orpc"],
|
|
364
|
-
meta: mergeMeta(this["~orpc"].meta, meta)
|
|
365
|
-
});
|
|
366
|
-
}
|
|
367
|
-
/**
|
|
368
|
-
* Sets or updates the route definition.
|
|
369
|
-
* The provided route is spared-merged with any existing route.
|
|
370
|
-
* This option is typically relevant when integrating with OpenAPI.
|
|
371
|
-
*
|
|
372
|
-
* @see {@link https://orpc.unnoq.com/docs/openapi/routing OpenAPI Routing Docs}
|
|
373
|
-
* @see {@link https://orpc.unnoq.com/docs/openapi/input-output-structure OpenAPI Input/Output Structure Docs}
|
|
374
|
-
*/
|
|
375
|
-
route(route) {
|
|
376
|
-
return new Builder({
|
|
377
|
-
...this["~orpc"],
|
|
378
|
-
route: mergeRoute(this["~orpc"].route, route)
|
|
379
|
-
});
|
|
380
|
-
}
|
|
381
|
-
/**
|
|
382
|
-
* Defines the input validation schema.
|
|
383
|
-
*
|
|
384
|
-
* @see {@link https://orpc.unnoq.com/docs/procedure#input-output-validation Input Validation Docs}
|
|
385
|
-
*/
|
|
386
|
-
input(schema) {
|
|
387
|
-
return new Builder({
|
|
388
|
-
...this["~orpc"],
|
|
389
|
-
inputSchema: schema,
|
|
390
|
-
inputValidationIndex: this["~orpc"].middlewares.length
|
|
391
|
-
});
|
|
392
|
-
}
|
|
393
|
-
/**
|
|
394
|
-
* Defines the output validation schema.
|
|
395
|
-
*
|
|
396
|
-
* @see {@link https://orpc.unnoq.com/docs/procedure#input-output-validation Output Validation Docs}
|
|
397
|
-
*/
|
|
398
|
-
output(schema) {
|
|
399
|
-
return new Builder({
|
|
400
|
-
...this["~orpc"],
|
|
401
|
-
outputSchema: schema,
|
|
402
|
-
outputValidationIndex: this["~orpc"].middlewares.length
|
|
403
|
-
});
|
|
404
|
-
}
|
|
405
226
|
/**
|
|
406
227
|
* Defines the handler of the procedure.
|
|
407
228
|
*
|
|
408
229
|
* @see {@link https://orpc.unnoq.com/docs/procedure Procedure Docs}
|
|
409
230
|
*/
|
|
410
231
|
handler(handler) {
|
|
232
|
+
if (this["~orpc"].schemas.outputSchema === initialSchemas.outputSchema) {
|
|
233
|
+
throw new Error("You must call .output() before calling .handler()");
|
|
234
|
+
}
|
|
411
235
|
return new DecoratedProcedure({
|
|
412
236
|
...this["~orpc"],
|
|
413
237
|
handler
|
|
414
238
|
});
|
|
415
239
|
}
|
|
240
|
+
}
|
|
241
|
+
class BuilderWithMiddlewares extends ProcedureBuilder {
|
|
416
242
|
/**
|
|
417
243
|
* Prefixes all procedures in the router.
|
|
418
244
|
* The provided prefix is post-appended to any existing router prefix.
|
|
@@ -422,7 +248,7 @@ class Builder {
|
|
|
422
248
|
* @see {@link https://orpc.unnoq.com/docs/openapi/routing#route-prefixes OpenAPI Route Prefixes Docs}
|
|
423
249
|
*/
|
|
424
250
|
prefix(prefix) {
|
|
425
|
-
return new
|
|
251
|
+
return new this.constructor({
|
|
426
252
|
...this["~orpc"],
|
|
427
253
|
prefix: mergePrefix(this["~orpc"].prefix, prefix)
|
|
428
254
|
});
|
|
@@ -434,7 +260,7 @@ class Builder {
|
|
|
434
260
|
* @see {@link https://orpc.unnoq.com/docs/openapi/openapi-specification#operation-metadata OpenAPI Operation Metadata Docs}
|
|
435
261
|
*/
|
|
436
262
|
tag(...tags) {
|
|
437
|
-
return new
|
|
263
|
+
return new this.constructor({
|
|
438
264
|
...this["~orpc"],
|
|
439
265
|
tags: mergeTags(this["~orpc"].tags, tags)
|
|
440
266
|
});
|
|
@@ -447,33 +273,80 @@ class Builder {
|
|
|
447
273
|
router(router) {
|
|
448
274
|
return enhanceRouter(router, this["~orpc"]);
|
|
449
275
|
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
function decorateMiddleware(middleware) {
|
|
279
|
+
const decorated = ((...args) => middleware(...args));
|
|
280
|
+
decorated.mapInput = (mapInput) => {
|
|
281
|
+
const mapped = decorateMiddleware(
|
|
282
|
+
(options, input, ...rest) => middleware(options, mapInput(input), ...rest)
|
|
283
|
+
);
|
|
284
|
+
return mapped;
|
|
285
|
+
};
|
|
286
|
+
decorated.concat = (concatMiddleware, mapInput) => {
|
|
287
|
+
const mapped = mapInput ? decorateMiddleware(concatMiddleware).mapInput(mapInput) : concatMiddleware;
|
|
288
|
+
const concatted = decorateMiddleware((options, input, output, ...rest) => {
|
|
289
|
+
const merged = middleware(
|
|
290
|
+
{
|
|
291
|
+
...options,
|
|
292
|
+
next: (...[nextOptions1]) => mapped(
|
|
293
|
+
{
|
|
294
|
+
...options,
|
|
295
|
+
context: { ...options.context, ...nextOptions1?.context },
|
|
296
|
+
next: (...[nextOptions2]) => options.next({ context: { ...nextOptions1?.context, ...nextOptions2?.context } })
|
|
297
|
+
},
|
|
298
|
+
input,
|
|
299
|
+
output,
|
|
300
|
+
...rest
|
|
301
|
+
)
|
|
302
|
+
},
|
|
303
|
+
input,
|
|
304
|
+
output,
|
|
305
|
+
...rest
|
|
306
|
+
);
|
|
307
|
+
return merged;
|
|
308
|
+
});
|
|
309
|
+
return concatted;
|
|
310
|
+
};
|
|
311
|
+
return decorated;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
class Builder extends BuilderWithMiddlewares {
|
|
315
|
+
/**
|
|
316
|
+
* Set or override the initial context.
|
|
317
|
+
*
|
|
318
|
+
* @see {@link https://orpc.unnoq.com/docs/context Context Docs}
|
|
319
|
+
*/
|
|
320
|
+
$context() {
|
|
321
|
+
return this;
|
|
322
|
+
}
|
|
450
323
|
/**
|
|
451
|
-
*
|
|
452
|
-
* And applies all of the previously defined options to the specified router.
|
|
324
|
+
* Creates a middleware.
|
|
453
325
|
*
|
|
454
|
-
* @see {@link https://orpc.unnoq.com/docs/
|
|
326
|
+
* @see {@link https://orpc.unnoq.com/docs/middleware Middleware Docs}
|
|
455
327
|
*/
|
|
456
|
-
|
|
457
|
-
return
|
|
328
|
+
middleware(middleware) {
|
|
329
|
+
return decorateMiddleware(middleware);
|
|
458
330
|
}
|
|
459
331
|
}
|
|
460
332
|
function createApiBuilder(opts = {}) {
|
|
461
|
-
|
|
333
|
+
return new Builder({
|
|
462
334
|
route: {},
|
|
463
335
|
meta: opts.meta ?? {},
|
|
464
336
|
errorMap: {},
|
|
465
337
|
inputValidationIndex: 0,
|
|
466
338
|
outputValidationIndex: 0,
|
|
467
339
|
middlewares: [
|
|
468
|
-
onError((error,
|
|
340
|
+
onError((error, _options) => {
|
|
469
341
|
console.dir(error, { depth: null });
|
|
470
342
|
})
|
|
471
343
|
],
|
|
344
|
+
schemas: initialSchemas,
|
|
472
345
|
// NB: this is a relic from orpc -- I'm not convinced there's a need for this (or if there is, that it's
|
|
473
346
|
// the best solution). For now I've removed the interface to configure it externally.
|
|
474
|
-
dedupeLeadingMiddlewares: true
|
|
347
|
+
dedupeLeadingMiddlewares: true,
|
|
348
|
+
authConfigs: []
|
|
475
349
|
});
|
|
476
|
-
return base;
|
|
477
350
|
}
|
|
478
351
|
const os = createApiBuilder();
|
|
479
352
|
|
|
@@ -482,6 +355,7 @@ function implementerInternal(contract, middlewares) {
|
|
|
482
355
|
const impl2 = new Builder({
|
|
483
356
|
...contract["~orpc"],
|
|
484
357
|
middlewares,
|
|
358
|
+
authConfigs: [],
|
|
485
359
|
inputValidationIndex: middlewares.length,
|
|
486
360
|
outputValidationIndex: middlewares.length,
|
|
487
361
|
dedupeLeadingMiddlewares: true
|
|
@@ -511,17 +385,6 @@ function implementerInternal(contract, middlewares) {
|
|
|
511
385
|
});
|
|
512
386
|
return setHiddenRouterContract(adapted, contract);
|
|
513
387
|
};
|
|
514
|
-
} else if (key === "lazyRoute") {
|
|
515
|
-
method = (loader) => {
|
|
516
|
-
const adapted = enhanceRouter(lazy(loader), {
|
|
517
|
-
middlewares,
|
|
518
|
-
errorMap: {},
|
|
519
|
-
prefix: void 0,
|
|
520
|
-
tags: void 0,
|
|
521
|
-
dedupeLeadingMiddlewares: true
|
|
522
|
-
});
|
|
523
|
-
return setHiddenRouterContract(adapted, contract);
|
|
524
|
-
};
|
|
525
388
|
}
|
|
526
389
|
const next = getContractRouter(target, [key]);
|
|
527
390
|
if (!next) {
|
|
@@ -563,7 +426,7 @@ function implement(contract) {
|
|
|
563
426
|
}
|
|
564
427
|
|
|
565
428
|
function createAssertedLazyProcedure(lazied) {
|
|
566
|
-
const lazyProcedure =
|
|
429
|
+
const lazyProcedure = lazyInternal(async () => {
|
|
567
430
|
const { default: maybeProcedure } = await unlazy(lazied);
|
|
568
431
|
if (!isProcedure(maybeProcedure)) {
|
|
569
432
|
throw new Error(`
|
|
@@ -614,4 +477,4 @@ function createRouterClient(router, ...rest) {
|
|
|
614
477
|
return recursive;
|
|
615
478
|
}
|
|
616
479
|
|
|
617
|
-
export { Builder, DecoratedProcedure, Procedure, addMiddleware, call,
|
|
480
|
+
export { Builder, BuilderWithMiddlewares, DecoratedProcedure, Procedure, ProcedureBuilder, addMiddleware, call, createApiBuilder, createAssertedLazyProcedure, createContractedProcedure, createProcedureClient, createRouterClient, decorateMiddleware, enhanceRouter, getLazyMeta, getRouter, implement, implementerInternal, isLazy, isProcedure, lazyInternal, os, setHiddenRouterContract, unlazy };
|