@trpc/server 10.0.0-proxy-beta.24 → 10.0.0-proxy-beta.25
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.ts.map +1 -1
- package/dist/adapters/aws-lambda/index.js +3 -2
- package/dist/adapters/aws-lambda/index.mjs +3 -2
- package/dist/adapters/express.js +4 -3
- package/dist/adapters/express.mjs +4 -3
- package/dist/adapters/fastify/index.js +3 -2
- package/dist/adapters/fastify/index.mjs +3 -2
- package/dist/adapters/fetch/index.js +3 -2
- package/dist/adapters/fetch/index.mjs +3 -2
- package/dist/adapters/next.js +4 -3
- package/dist/adapters/next.mjs +4 -3
- package/dist/adapters/node-http/index.js +4 -3
- package/dist/adapters/node-http/index.mjs +4 -3
- package/dist/adapters/standalone.js +4 -3
- package/dist/adapters/standalone.mjs +4 -3
- package/dist/adapters/ws.js +3 -2
- package/dist/adapters/ws.mjs +2 -1
- package/dist/{transformTRPCResponse-23e99f82.mjs → config-287b8ea5.mjs} +28 -52
- package/dist/{transformTRPCResponse-92c79c47.js → config-7bd017ac.js} +28 -52
- package/dist/http/{internals/getHTTPStatusCode.d.ts → getHTTPStatusCode.d.ts} +2 -2
- package/dist/http/getHTTPStatusCode.d.ts.map +1 -0
- package/dist/http/index.d.ts +1 -0
- package/dist/http/index.d.ts.map +1 -1
- package/dist/http/index.js +17 -0
- package/dist/http/index.mjs +6 -0
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +398 -400
- package/dist/index.mjs +389 -390
- package/dist/{nodeHTTPRequestHandler-bb607c2b.mjs → nodeHTTPRequestHandler-a3060966.mjs} +1 -1
- package/dist/{nodeHTTPRequestHandler-0e40a231.js → nodeHTTPRequestHandler-b1dc9f7c.js} +1 -1
- package/dist/{resolveHTTPResponse-9dff3dcc.mjs → resolveHTTPResponse-01a6f231.mjs} +2 -1
- package/dist/{resolveHTTPResponse-92daf326.js → resolveHTTPResponse-61271ba9.js} +4 -3
- package/dist/transformTRPCResponse-547a4702.mjs +25 -0
- package/dist/transformTRPCResponse-cc650f44.js +27 -0
- package/http/index.d.ts +1 -0
- package/http/index.js +1 -0
- package/package.json +12 -6
- package/src/adapters/aws-lambda/index.ts +2 -1
- package/src/core/router.ts +1 -1
- package/src/deprecated/router.ts +1 -1
- package/src/http/{internals/getHTTPStatusCode.ts → getHTTPStatusCode.ts} +3 -3
- package/src/http/index.ts +1 -0
- package/src/http/resolveHTTPResponse.ts +1 -1
- package/src/index.ts +0 -1
- package/dist/http/internals/getHTTPStatusCode.d.ts.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,125 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export { e as callProcedure, a as defaultTransformer, g as getDataTransformer, p as procedureTypes } from './transformTRPCResponse-23e99f82.mjs';
|
|
1
|
+
import { c as createRouterFactory, d as defaultFormatter, g as getHTTPStatusCodeFromError, a as defaultTransformer, b as getDataTransformer$1, i as isServerDefault } from './config-287b8ea5.mjs';
|
|
2
|
+
export { e as callProcedure, a as defaultTransformer, b as getDataTransformer, p as procedureTypes } from './config-287b8ea5.mjs';
|
|
4
3
|
import { T as TRPCError, g as getCauseFromUnknown, a as getTRPCErrorFromUnknown } from './TRPCError-e99e7cbe.mjs';
|
|
5
4
|
export { T as TRPCError } from './TRPCError-e99e7cbe.mjs';
|
|
6
5
|
import { T as TRPC_ERROR_CODES_BY_KEY } from './codes-7d21f749.mjs';
|
|
7
6
|
import { c as createFlatProxy } from './index-0332d528.mjs';
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
|
-
* @
|
|
11
|
-
*/
|
|
12
|
-
function createMiddlewareFactory() {
|
|
13
|
-
return function createMiddleware(fn) {
|
|
14
|
-
return fn;
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
function isPlainObject(obj) {
|
|
18
|
-
return obj && typeof obj === 'object' && !Array.isArray(obj);
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* @internal
|
|
22
|
-
* Please note, `trpc-openapi` uses this function.
|
|
23
|
-
*/ function createInputMiddleware(parse) {
|
|
24
|
-
const inputMiddleware = async ({ next , rawInput , input , })=>{
|
|
25
|
-
let parsedInput;
|
|
26
|
-
try {
|
|
27
|
-
parsedInput = await parse(rawInput);
|
|
28
|
-
} catch (cause) {
|
|
29
|
-
throw new TRPCError({
|
|
30
|
-
code: 'BAD_REQUEST',
|
|
31
|
-
cause: getCauseFromUnknown(cause)
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
// Multiple input parsers
|
|
35
|
-
const combinedInput = isPlainObject(input) && isPlainObject(parsedInput) ? {
|
|
36
|
-
...input,
|
|
37
|
-
...parsedInput
|
|
38
|
-
} : parsedInput;
|
|
39
|
-
// TODO fix this typing?
|
|
40
|
-
return next({
|
|
41
|
-
input: combinedInput
|
|
42
|
-
});
|
|
43
|
-
};
|
|
44
|
-
inputMiddleware._type = 'input';
|
|
45
|
-
return inputMiddleware;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* @internal
|
|
49
|
-
*/ function createOutputMiddleware(parse) {
|
|
50
|
-
const outputMiddleware = async ({ next })=>{
|
|
51
|
-
const result = await next();
|
|
52
|
-
if (!result.ok) {
|
|
53
|
-
// pass through failures without validating
|
|
54
|
-
return result;
|
|
55
|
-
}
|
|
56
|
-
try {
|
|
57
|
-
const data = await parse(result.data);
|
|
58
|
-
return {
|
|
59
|
-
...result,
|
|
60
|
-
data
|
|
61
|
-
};
|
|
62
|
-
} catch (cause) {
|
|
63
|
-
throw new TRPCError({
|
|
64
|
-
message: 'Output validation failed',
|
|
65
|
-
code: 'INTERNAL_SERVER_ERROR',
|
|
66
|
-
cause: getCauseFromUnknown(cause)
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
outputMiddleware._type = 'output';
|
|
71
|
-
return outputMiddleware;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Ensures there are no duplicate keys when building a procedure.
|
|
76
|
-
*/ function mergeWithoutOverrides(obj1, ...objs) {
|
|
77
|
-
const newObj = Object.assign(Object.create(null), obj1);
|
|
78
|
-
for (const overrides of objs){
|
|
79
|
-
for(const key in overrides){
|
|
80
|
-
if (key in newObj && newObj[key] !== overrides[key]) {
|
|
81
|
-
throw new Error(`Duplicate key ${key}`);
|
|
82
|
-
}
|
|
83
|
-
newObj[key] = overrides[key];
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
return newObj;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function mergeRouters(...routerList) {
|
|
90
|
-
const record = mergeWithoutOverrides({}, ...routerList.map((r)=>r._def.record));
|
|
91
|
-
const errorFormatter = routerList.reduce((currentErrorFormatter, nextRouter)=>{
|
|
92
|
-
if (nextRouter._def._config.errorFormatter && nextRouter._def._config.errorFormatter !== defaultFormatter) {
|
|
93
|
-
if (currentErrorFormatter !== defaultFormatter && currentErrorFormatter !== nextRouter._def._config.errorFormatter) {
|
|
94
|
-
throw new Error('You seem to have several error formatters');
|
|
95
|
-
}
|
|
96
|
-
return nextRouter._def._config.errorFormatter;
|
|
97
|
-
}
|
|
98
|
-
return currentErrorFormatter;
|
|
99
|
-
}, defaultFormatter);
|
|
100
|
-
const transformer = routerList.reduce((prev, current)=>{
|
|
101
|
-
if (current._def._config.transformer && current._def._config.transformer !== defaultTransformer) {
|
|
102
|
-
if (prev !== defaultTransformer && prev !== current._def._config.transformer) {
|
|
103
|
-
throw new Error('You seem to have several transformers');
|
|
104
|
-
}
|
|
105
|
-
return current._def._config.transformer;
|
|
106
|
-
}
|
|
107
|
-
return prev;
|
|
108
|
-
}, defaultTransformer);
|
|
109
|
-
const router = createRouterFactory({
|
|
110
|
-
errorFormatter,
|
|
111
|
-
transformer,
|
|
112
|
-
isDev: routerList.some((r)=>r._def._config.isDev),
|
|
113
|
-
allowOutsideOfServer: routerList.some((r)=>r._def._config.allowOutsideOfServer),
|
|
114
|
-
isServer: routerList.some((r)=>r._def._config.isServer),
|
|
115
|
-
$types: routerList[0]?._def._config.$types
|
|
116
|
-
})(record);
|
|
117
|
-
return router;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
function mergeRoutersGeneric(...args) {
|
|
121
|
-
return mergeRouters(...args);
|
|
122
|
-
}
|
|
9
|
+
* @deprecated
|
|
10
|
+
*/ const middlewareMarker$1 = 'middlewareMarker';
|
|
123
11
|
|
|
124
12
|
function getParseFn$1(procedureParser) {
|
|
125
13
|
const parser = procedureParser;
|
|
@@ -146,129 +34,61 @@ function getParseFn$1(procedureParser) {
|
|
|
146
34
|
throw new Error('Could not find a validator fn');
|
|
147
35
|
}
|
|
148
36
|
/**
|
|
149
|
-
* @deprecated only for backwards compat
|
|
150
37
|
* @internal
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
38
|
+
* @deprecated
|
|
39
|
+
*/ class Procedure {
|
|
40
|
+
_def() {
|
|
41
|
+
return {
|
|
42
|
+
middlewares: this.middlewares,
|
|
43
|
+
resolver: this.resolver,
|
|
44
|
+
inputParser: this.inputParser,
|
|
45
|
+
outputParser: this.outputParser,
|
|
46
|
+
meta: this.meta
|
|
47
|
+
};
|
|
154
48
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
function createNewBuilder(def1, def2) {
|
|
163
|
-
const { middlewares =[] , inputs , ...rest } = def2;
|
|
164
|
-
// TODO: maybe have a fn here to warn about calls
|
|
165
|
-
return createBuilder({
|
|
166
|
-
...mergeWithoutOverrides(def1, rest),
|
|
167
|
-
inputs: [
|
|
168
|
-
...def1.inputs,
|
|
169
|
-
...inputs ?? []
|
|
170
|
-
],
|
|
171
|
-
middlewares: [
|
|
172
|
-
...def1.middlewares,
|
|
173
|
-
...middlewares
|
|
174
|
-
]
|
|
175
|
-
});
|
|
176
|
-
}
|
|
177
|
-
function createBuilder(initDef) {
|
|
178
|
-
const _def = initDef || {
|
|
179
|
-
inputs: [],
|
|
180
|
-
middlewares: []
|
|
181
|
-
};
|
|
182
|
-
return {
|
|
183
|
-
_def,
|
|
184
|
-
input (input) {
|
|
185
|
-
const parser = getParseFn$1(input);
|
|
186
|
-
return createNewBuilder(_def, {
|
|
187
|
-
inputs: [
|
|
188
|
-
input
|
|
189
|
-
],
|
|
190
|
-
middlewares: [
|
|
191
|
-
createInputMiddleware(parser)
|
|
192
|
-
]
|
|
193
|
-
});
|
|
194
|
-
},
|
|
195
|
-
output (output) {
|
|
196
|
-
const parseOutput = getParseFn$1(output);
|
|
197
|
-
return createNewBuilder(_def, {
|
|
198
|
-
output,
|
|
199
|
-
middlewares: [
|
|
200
|
-
createOutputMiddleware(parseOutput)
|
|
201
|
-
]
|
|
202
|
-
});
|
|
203
|
-
},
|
|
204
|
-
meta (meta) {
|
|
205
|
-
return createNewBuilder(_def, {
|
|
206
|
-
meta: meta
|
|
49
|
+
async parseInput(rawInput) {
|
|
50
|
+
try {
|
|
51
|
+
return await this.parseInputFn(rawInput);
|
|
52
|
+
} catch (cause) {
|
|
53
|
+
throw new TRPCError({
|
|
54
|
+
code: 'BAD_REQUEST',
|
|
55
|
+
cause: getCauseFromUnknown(cause)
|
|
207
56
|
});
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async parseOutput(rawOutput) {
|
|
60
|
+
try {
|
|
61
|
+
return await this.parseOutputFn(rawOutput);
|
|
62
|
+
} catch (cause) {
|
|
63
|
+
throw new TRPCError({
|
|
64
|
+
code: 'INTERNAL_SERVER_ERROR',
|
|
65
|
+
cause: getCauseFromUnknown(cause),
|
|
66
|
+
message: 'Output validation failed'
|
|
217
67
|
});
|
|
218
|
-
},
|
|
219
|
-
query (resolver) {
|
|
220
|
-
return createResolver({
|
|
221
|
-
..._def,
|
|
222
|
-
query: true
|
|
223
|
-
}, resolver);
|
|
224
|
-
},
|
|
225
|
-
mutation (resolver) {
|
|
226
|
-
return createResolver({
|
|
227
|
-
..._def,
|
|
228
|
-
mutation: true
|
|
229
|
-
}, resolver);
|
|
230
|
-
},
|
|
231
|
-
subscription (resolver) {
|
|
232
|
-
return createResolver({
|
|
233
|
-
..._def,
|
|
234
|
-
subscription: true
|
|
235
|
-
}, resolver);
|
|
236
68
|
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Trigger middlewares in order, parse raw input, call resolver & parse raw output
|
|
72
|
+
* @internal
|
|
73
|
+
*/ async call(opts) {
|
|
74
|
+
// wrap the actual resolver and treat as the last "middleware"
|
|
75
|
+
const middlewaresWithResolver = this.middlewares.concat([
|
|
76
|
+
async ({ ctx })=>{
|
|
77
|
+
const input = await this.parseInput(opts.rawInput);
|
|
78
|
+
const rawOutput = await this.resolver({
|
|
79
|
+
...opts,
|
|
80
|
+
ctx,
|
|
81
|
+
input
|
|
82
|
+
});
|
|
83
|
+
const data = await this.parseOutput(rawOutput);
|
|
245
84
|
return {
|
|
246
85
|
marker: middlewareMarker$1,
|
|
247
86
|
ok: true,
|
|
248
87
|
data,
|
|
249
|
-
ctx
|
|
88
|
+
ctx
|
|
250
89
|
};
|
|
251
90
|
}
|
|
252
|
-
]
|
|
253
|
-
});
|
|
254
|
-
return createProcedureCaller(finalBuilder._def);
|
|
255
|
-
}
|
|
256
|
-
const codeblock = `
|
|
257
|
-
If you want to call this function on the server, you do the following:
|
|
258
|
-
This is a client-only function.
|
|
259
|
-
|
|
260
|
-
const caller = appRouter.createCaller({
|
|
261
|
-
/* ... your context */
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
const result = await caller.call('myProcedure', input);
|
|
265
|
-
`.trim();
|
|
266
|
-
function createProcedureCaller(_def) {
|
|
267
|
-
const procedure = async function resolve(opts) {
|
|
268
|
-
// is direct server-side call
|
|
269
|
-
if (!opts || !('rawInput' in opts)) {
|
|
270
|
-
throw new Error(codeblock);
|
|
271
|
-
}
|
|
91
|
+
]);
|
|
272
92
|
// run the middlewares recursively with the resolver as the last one
|
|
273
93
|
const callRecursive = async (callOpts = {
|
|
274
94
|
index: 0,
|
|
@@ -276,28 +96,23 @@ function createProcedureCaller(_def) {
|
|
|
276
96
|
})=>{
|
|
277
97
|
try {
|
|
278
98
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
279
|
-
const
|
|
280
|
-
const result = await middleware({
|
|
99
|
+
const result = await middlewaresWithResolver[callOpts.index]({
|
|
281
100
|
ctx: callOpts.ctx,
|
|
282
101
|
type: opts.type,
|
|
283
102
|
path: opts.path,
|
|
284
103
|
rawInput: opts.rawInput,
|
|
285
|
-
meta:
|
|
286
|
-
input: callOpts.input,
|
|
104
|
+
meta: this.meta,
|
|
287
105
|
next: async (nextOpts)=>{
|
|
288
106
|
return await callRecursive({
|
|
289
107
|
index: callOpts.index + 1,
|
|
290
|
-
ctx: nextOpts
|
|
291
|
-
...callOpts.ctx,
|
|
292
|
-
...nextOpts.ctx
|
|
293
|
-
} : callOpts.ctx,
|
|
294
|
-
input: nextOpts && 'input' in nextOpts ? nextOpts.input : callOpts.input
|
|
108
|
+
ctx: nextOpts ? nextOpts.ctx : callOpts.ctx
|
|
295
109
|
});
|
|
296
110
|
}
|
|
297
111
|
});
|
|
298
112
|
return result;
|
|
299
113
|
} catch (cause) {
|
|
300
114
|
return {
|
|
115
|
+
ctx: callOpts.ctx,
|
|
301
116
|
ok: false,
|
|
302
117
|
error: getTRPCErrorFromUnknown(cause),
|
|
303
118
|
marker: middlewareMarker$1
|
|
@@ -317,79 +132,54 @@ function createProcedureCaller(_def) {
|
|
|
317
132
|
throw result.error;
|
|
318
133
|
}
|
|
319
134
|
return result.data;
|
|
320
|
-
};
|
|
321
|
-
procedure._def = _def;
|
|
322
|
-
procedure.meta = _def.meta;
|
|
323
|
-
return procedure;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
/**
|
|
327
|
-
* TODO: This can be improved:
|
|
328
|
-
* - We should be able to chain `.meta()`/`.context()` only once
|
|
329
|
-
* - Simplify typings
|
|
330
|
-
* - Doesn't need to be a class but it doesn't really hurt either
|
|
331
|
-
*/ class TRPCBuilder {
|
|
332
|
-
context() {
|
|
333
|
-
return new TRPCBuilder();
|
|
334
135
|
}
|
|
335
|
-
|
|
336
|
-
|
|
136
|
+
/**
|
|
137
|
+
* Create new procedure with passed middlewares
|
|
138
|
+
* @param middlewares
|
|
139
|
+
*/ inheritMiddlewares(middlewares) {
|
|
140
|
+
const Constructor = this.constructor;
|
|
141
|
+
const instance = new Constructor({
|
|
142
|
+
middlewares: [
|
|
143
|
+
...middlewares,
|
|
144
|
+
...this.middlewares
|
|
145
|
+
],
|
|
146
|
+
resolver: this.resolver,
|
|
147
|
+
inputParser: this.inputParser,
|
|
148
|
+
outputParser: this.outputParser,
|
|
149
|
+
meta: this.meta
|
|
150
|
+
});
|
|
151
|
+
return instance;
|
|
337
152
|
}
|
|
338
|
-
|
|
339
|
-
|
|
153
|
+
constructor(opts){
|
|
154
|
+
this.middlewares = opts.middlewares;
|
|
155
|
+
this.resolver = opts.resolver;
|
|
156
|
+
this.inputParser = opts.inputParser;
|
|
157
|
+
this.parseInputFn = getParseFn$1(this.inputParser);
|
|
158
|
+
this.outputParser = opts.outputParser;
|
|
159
|
+
this.parseOutputFn = getParseFn$1(this.outputParser);
|
|
160
|
+
this.meta = opts.meta;
|
|
340
161
|
}
|
|
341
162
|
}
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
const config = {
|
|
350
|
-
transformer,
|
|
351
|
-
isDev: runtime?.isDev ?? process.env.NODE_ENV !== 'production',
|
|
352
|
-
allowOutsideOfServer: runtime?.allowOutsideOfServer ?? false,
|
|
353
|
-
errorFormatter,
|
|
354
|
-
isServer: runtime?.isServer ?? isServerDefault,
|
|
355
|
-
/**
|
|
356
|
-
* @internal
|
|
357
|
-
*/ $types: createFlatProxy((key)=>{
|
|
358
|
-
throw new Error(`Tried to access "$types.${key}" which is not available at runtime`);
|
|
359
|
-
})
|
|
360
|
-
};
|
|
361
|
-
{
|
|
362
|
-
// Server check
|
|
363
|
-
const isServer = runtime?.isServer ?? isServerDefault;
|
|
364
|
-
if (!isServer && runtime?.allowOutsideOfServer !== true) {
|
|
365
|
-
throw new Error(`You're trying to use @trpc/server in a non-server environment. This is not supported by default.`);
|
|
366
|
-
}
|
|
163
|
+
function createProcedure(opts) {
|
|
164
|
+
const inputParser = 'input' in opts ? opts.input : (input)=>{
|
|
165
|
+
if (input != null) {
|
|
166
|
+
throw new TRPCError({
|
|
167
|
+
code: 'BAD_REQUEST',
|
|
168
|
+
message: 'No input expected'
|
|
169
|
+
});
|
|
367
170
|
}
|
|
368
|
-
return
|
|
369
|
-
/**
|
|
370
|
-
* These are just types, they can't be used
|
|
371
|
-
* @internal
|
|
372
|
-
*/ _config: config,
|
|
373
|
-
/**
|
|
374
|
-
* Builder object for creating procedures
|
|
375
|
-
*/ procedure: createBuilder(),
|
|
376
|
-
/**
|
|
377
|
-
* Create reusable middlewares
|
|
378
|
-
*/ middleware: createMiddlewareFactory(),
|
|
379
|
-
/**
|
|
380
|
-
* Create a router
|
|
381
|
-
*/ router: createRouterFactory(config),
|
|
382
|
-
/**
|
|
383
|
-
* Merge Routers
|
|
384
|
-
*/ mergeRouters: mergeRoutersGeneric
|
|
385
|
-
};
|
|
171
|
+
return undefined;
|
|
386
172
|
};
|
|
173
|
+
const outputParser = 'output' in opts && opts.output ? opts.output : (output)=>output;
|
|
174
|
+
return new Procedure({
|
|
175
|
+
inputParser: inputParser,
|
|
176
|
+
resolver: opts.resolve,
|
|
177
|
+
middlewares: [],
|
|
178
|
+
outputParser: outputParser,
|
|
179
|
+
meta: opts.meta
|
|
180
|
+
});
|
|
387
181
|
}
|
|
388
182
|
|
|
389
|
-
/**
|
|
390
|
-
* @deprecated
|
|
391
|
-
*/ const middlewareMarker = 'middlewareMarker';
|
|
392
|
-
|
|
393
183
|
function getParseFn(procedureParser) {
|
|
394
184
|
const parser = procedureParser;
|
|
395
185
|
if (typeof parser === 'function') {
|
|
@@ -415,61 +205,209 @@ function getParseFn(procedureParser) {
|
|
|
415
205
|
throw new Error('Could not find a validator fn');
|
|
416
206
|
}
|
|
417
207
|
/**
|
|
208
|
+
* @deprecated only for backwards compat
|
|
418
209
|
* @internal
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
return {
|
|
423
|
-
middlewares: this.middlewares,
|
|
424
|
-
resolver: this.resolver,
|
|
425
|
-
inputParser: this.inputParser,
|
|
426
|
-
outputParser: this.outputParser,
|
|
427
|
-
meta: this.meta
|
|
428
|
-
};
|
|
210
|
+
*/ function getParseFnOrPassThrough(procedureParser) {
|
|
211
|
+
if (!procedureParser) {
|
|
212
|
+
return (v)=>v;
|
|
429
213
|
}
|
|
430
|
-
|
|
214
|
+
return getParseFn(procedureParser);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Ensures there are no duplicate keys when building a procedure.
|
|
219
|
+
*/ function mergeWithoutOverrides(obj1, ...objs) {
|
|
220
|
+
const newObj = Object.assign(Object.create(null), obj1);
|
|
221
|
+
for (const overrides of objs){
|
|
222
|
+
for(const key in overrides){
|
|
223
|
+
if (key in newObj && newObj[key] !== overrides[key]) {
|
|
224
|
+
throw new Error(`Duplicate key ${key}`);
|
|
225
|
+
}
|
|
226
|
+
newObj[key] = overrides[key];
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return newObj;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* @internal
|
|
234
|
+
*/ // FIXME this should use RootConfig
|
|
235
|
+
function createMiddlewareFactory() {
|
|
236
|
+
return function createMiddleware(fn) {
|
|
237
|
+
return fn;
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
function isPlainObject(obj) {
|
|
241
|
+
return obj && typeof obj === 'object' && !Array.isArray(obj);
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* @internal
|
|
245
|
+
* Please note, `trpc-openapi` uses this function.
|
|
246
|
+
*/ function createInputMiddleware(parse) {
|
|
247
|
+
const inputMiddleware = async ({ next , rawInput , input , })=>{
|
|
248
|
+
let parsedInput;
|
|
431
249
|
try {
|
|
432
|
-
|
|
250
|
+
parsedInput = await parse(rawInput);
|
|
433
251
|
} catch (cause) {
|
|
434
252
|
throw new TRPCError({
|
|
435
253
|
code: 'BAD_REQUEST',
|
|
436
254
|
cause: getCauseFromUnknown(cause)
|
|
437
255
|
});
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
256
|
+
}
|
|
257
|
+
// Multiple input parsers
|
|
258
|
+
const combinedInput = isPlainObject(input) && isPlainObject(parsedInput) ? {
|
|
259
|
+
...input,
|
|
260
|
+
...parsedInput
|
|
261
|
+
} : parsedInput;
|
|
262
|
+
// TODO fix this typing?
|
|
263
|
+
return next({
|
|
264
|
+
input: combinedInput
|
|
265
|
+
});
|
|
266
|
+
};
|
|
267
|
+
inputMiddleware._type = 'input';
|
|
268
|
+
return inputMiddleware;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* @internal
|
|
272
|
+
*/ function createOutputMiddleware(parse) {
|
|
273
|
+
const outputMiddleware = async ({ next })=>{
|
|
274
|
+
const result = await next();
|
|
275
|
+
if (!result.ok) {
|
|
276
|
+
// pass through failures without validating
|
|
277
|
+
return result;
|
|
278
|
+
}
|
|
279
|
+
try {
|
|
280
|
+
const data = await parse(result.data);
|
|
281
|
+
return {
|
|
282
|
+
...result,
|
|
283
|
+
data
|
|
284
|
+
};
|
|
285
|
+
} catch (cause) {
|
|
286
|
+
throw new TRPCError({
|
|
287
|
+
message: 'Output validation failed',
|
|
288
|
+
code: 'INTERNAL_SERVER_ERROR',
|
|
289
|
+
cause: getCauseFromUnknown(cause)
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
outputMiddleware._type = 'output';
|
|
294
|
+
return outputMiddleware;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* @internal
|
|
299
|
+
*/ const middlewareMarker = 'middlewareMarker';
|
|
300
|
+
|
|
301
|
+
function createNewBuilder(def1, def2) {
|
|
302
|
+
const { middlewares =[] , inputs , ...rest } = def2;
|
|
303
|
+
// TODO: maybe have a fn here to warn about calls
|
|
304
|
+
return createBuilder({
|
|
305
|
+
...mergeWithoutOverrides(def1, rest),
|
|
306
|
+
inputs: [
|
|
307
|
+
...def1.inputs,
|
|
308
|
+
...inputs ?? []
|
|
309
|
+
],
|
|
310
|
+
middlewares: [
|
|
311
|
+
...def1.middlewares,
|
|
312
|
+
...middlewares
|
|
313
|
+
]
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
function createBuilder(initDef) {
|
|
317
|
+
const _def = initDef || {
|
|
318
|
+
inputs: [],
|
|
319
|
+
middlewares: []
|
|
320
|
+
};
|
|
321
|
+
return {
|
|
322
|
+
_def,
|
|
323
|
+
input (input) {
|
|
324
|
+
const parser = getParseFn(input);
|
|
325
|
+
return createNewBuilder(_def, {
|
|
326
|
+
inputs: [
|
|
327
|
+
input
|
|
328
|
+
],
|
|
329
|
+
middlewares: [
|
|
330
|
+
createInputMiddleware(parser)
|
|
331
|
+
]
|
|
332
|
+
});
|
|
333
|
+
},
|
|
334
|
+
output (output) {
|
|
335
|
+
const parseOutput = getParseFn(output);
|
|
336
|
+
return createNewBuilder(_def, {
|
|
337
|
+
output,
|
|
338
|
+
middlewares: [
|
|
339
|
+
createOutputMiddleware(parseOutput)
|
|
340
|
+
]
|
|
341
|
+
});
|
|
342
|
+
},
|
|
343
|
+
meta (meta) {
|
|
344
|
+
return createNewBuilder(_def, {
|
|
345
|
+
meta: meta
|
|
346
|
+
});
|
|
347
|
+
},
|
|
348
|
+
unstable_concat (builder) {
|
|
349
|
+
return createNewBuilder(_def, builder._def);
|
|
350
|
+
},
|
|
351
|
+
use (middleware) {
|
|
352
|
+
return createNewBuilder(_def, {
|
|
353
|
+
middlewares: [
|
|
354
|
+
middleware
|
|
355
|
+
]
|
|
448
356
|
});
|
|
357
|
+
},
|
|
358
|
+
query (resolver) {
|
|
359
|
+
return createResolver({
|
|
360
|
+
..._def,
|
|
361
|
+
query: true
|
|
362
|
+
}, resolver);
|
|
363
|
+
},
|
|
364
|
+
mutation (resolver) {
|
|
365
|
+
return createResolver({
|
|
366
|
+
..._def,
|
|
367
|
+
mutation: true
|
|
368
|
+
}, resolver);
|
|
369
|
+
},
|
|
370
|
+
subscription (resolver) {
|
|
371
|
+
return createResolver({
|
|
372
|
+
..._def,
|
|
373
|
+
subscription: true
|
|
374
|
+
}, resolver);
|
|
449
375
|
}
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
const input = await this.parseInput(opts.rawInput);
|
|
459
|
-
const rawOutput = await this.resolver({
|
|
460
|
-
...opts,
|
|
461
|
-
ctx,
|
|
462
|
-
input
|
|
463
|
-
});
|
|
464
|
-
const data = await this.parseOutput(rawOutput);
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
function createResolver(_def, resolver) {
|
|
379
|
+
const finalBuilder = createNewBuilder(_def, {
|
|
380
|
+
resolver,
|
|
381
|
+
middlewares: [
|
|
382
|
+
async function resolveMiddleware(opts) {
|
|
383
|
+
const data = await resolver(opts);
|
|
465
384
|
return {
|
|
466
385
|
marker: middlewareMarker,
|
|
467
386
|
ok: true,
|
|
468
387
|
data,
|
|
469
|
-
ctx
|
|
388
|
+
ctx: opts.ctx
|
|
470
389
|
};
|
|
471
390
|
}
|
|
472
|
-
]
|
|
391
|
+
]
|
|
392
|
+
});
|
|
393
|
+
return createProcedureCaller(finalBuilder._def);
|
|
394
|
+
}
|
|
395
|
+
const codeblock = `
|
|
396
|
+
If you want to call this function on the server, you do the following:
|
|
397
|
+
This is a client-only function.
|
|
398
|
+
|
|
399
|
+
const caller = appRouter.createCaller({
|
|
400
|
+
/* ... your context */
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
const result = await caller.call('myProcedure', input);
|
|
404
|
+
`.trim();
|
|
405
|
+
function createProcedureCaller(_def) {
|
|
406
|
+
const procedure = async function resolve(opts) {
|
|
407
|
+
// is direct server-side call
|
|
408
|
+
if (!opts || !('rawInput' in opts)) {
|
|
409
|
+
throw new Error(codeblock);
|
|
410
|
+
}
|
|
473
411
|
// run the middlewares recursively with the resolver as the last one
|
|
474
412
|
const callRecursive = async (callOpts = {
|
|
475
413
|
index: 0,
|
|
@@ -477,23 +415,28 @@ function getParseFn(procedureParser) {
|
|
|
477
415
|
})=>{
|
|
478
416
|
try {
|
|
479
417
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
480
|
-
const
|
|
418
|
+
const middleware = _def.middlewares[callOpts.index];
|
|
419
|
+
const result = await middleware({
|
|
481
420
|
ctx: callOpts.ctx,
|
|
482
421
|
type: opts.type,
|
|
483
422
|
path: opts.path,
|
|
484
423
|
rawInput: opts.rawInput,
|
|
485
|
-
meta:
|
|
424
|
+
meta: _def.meta,
|
|
425
|
+
input: callOpts.input,
|
|
486
426
|
next: async (nextOpts)=>{
|
|
487
427
|
return await callRecursive({
|
|
488
428
|
index: callOpts.index + 1,
|
|
489
|
-
ctx: nextOpts
|
|
429
|
+
ctx: nextOpts && 'ctx' in nextOpts ? {
|
|
430
|
+
...callOpts.ctx,
|
|
431
|
+
...nextOpts.ctx
|
|
432
|
+
} : callOpts.ctx,
|
|
433
|
+
input: nextOpts && 'input' in nextOpts ? nextOpts.input : callOpts.input
|
|
490
434
|
});
|
|
491
435
|
}
|
|
492
436
|
});
|
|
493
437
|
return result;
|
|
494
438
|
} catch (cause) {
|
|
495
439
|
return {
|
|
496
|
-
ctx: callOpts.ctx,
|
|
497
440
|
ok: false,
|
|
498
441
|
error: getTRPCErrorFromUnknown(cause),
|
|
499
442
|
marker: middlewareMarker
|
|
@@ -513,52 +456,10 @@ function getParseFn(procedureParser) {
|
|
|
513
456
|
throw result.error;
|
|
514
457
|
}
|
|
515
458
|
return result.data;
|
|
516
|
-
}
|
|
517
|
-
/**
|
|
518
|
-
* Create new procedure with passed middlewares
|
|
519
|
-
* @param middlewares
|
|
520
|
-
*/ inheritMiddlewares(middlewares) {
|
|
521
|
-
const Constructor = this.constructor;
|
|
522
|
-
const instance = new Constructor({
|
|
523
|
-
middlewares: [
|
|
524
|
-
...middlewares,
|
|
525
|
-
...this.middlewares
|
|
526
|
-
],
|
|
527
|
-
resolver: this.resolver,
|
|
528
|
-
inputParser: this.inputParser,
|
|
529
|
-
outputParser: this.outputParser,
|
|
530
|
-
meta: this.meta
|
|
531
|
-
});
|
|
532
|
-
return instance;
|
|
533
|
-
}
|
|
534
|
-
constructor(opts){
|
|
535
|
-
this.middlewares = opts.middlewares;
|
|
536
|
-
this.resolver = opts.resolver;
|
|
537
|
-
this.inputParser = opts.inputParser;
|
|
538
|
-
this.parseInputFn = getParseFn(this.inputParser);
|
|
539
|
-
this.outputParser = opts.outputParser;
|
|
540
|
-
this.parseOutputFn = getParseFn(this.outputParser);
|
|
541
|
-
this.meta = opts.meta;
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
function createProcedure(opts) {
|
|
545
|
-
const inputParser = 'input' in opts ? opts.input : (input)=>{
|
|
546
|
-
if (input != null) {
|
|
547
|
-
throw new TRPCError({
|
|
548
|
-
code: 'BAD_REQUEST',
|
|
549
|
-
message: 'No input expected'
|
|
550
|
-
});
|
|
551
|
-
}
|
|
552
|
-
return undefined;
|
|
553
459
|
};
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
resolver: opts.resolve,
|
|
558
|
-
middlewares: [],
|
|
559
|
-
outputParser: outputParser,
|
|
560
|
-
meta: opts.meta
|
|
561
|
-
});
|
|
460
|
+
procedure._def = _def;
|
|
461
|
+
procedure.meta = _def.meta;
|
|
462
|
+
return procedure;
|
|
562
463
|
}
|
|
563
464
|
|
|
564
465
|
function migrateProcedure(oldProc, type) {
|
|
@@ -829,4 +730,102 @@ function safeObject(...args) {
|
|
|
829
730
|
return new Router();
|
|
830
731
|
}
|
|
831
732
|
|
|
733
|
+
function mergeRouters(...routerList) {
|
|
734
|
+
const record = mergeWithoutOverrides({}, ...routerList.map((r)=>r._def.record));
|
|
735
|
+
const errorFormatter = routerList.reduce((currentErrorFormatter, nextRouter)=>{
|
|
736
|
+
if (nextRouter._def._config.errorFormatter && nextRouter._def._config.errorFormatter !== defaultFormatter) {
|
|
737
|
+
if (currentErrorFormatter !== defaultFormatter && currentErrorFormatter !== nextRouter._def._config.errorFormatter) {
|
|
738
|
+
throw new Error('You seem to have several error formatters');
|
|
739
|
+
}
|
|
740
|
+
return nextRouter._def._config.errorFormatter;
|
|
741
|
+
}
|
|
742
|
+
return currentErrorFormatter;
|
|
743
|
+
}, defaultFormatter);
|
|
744
|
+
const transformer = routerList.reduce((prev, current)=>{
|
|
745
|
+
if (current._def._config.transformer && current._def._config.transformer !== defaultTransformer) {
|
|
746
|
+
if (prev !== defaultTransformer && prev !== current._def._config.transformer) {
|
|
747
|
+
throw new Error('You seem to have several transformers');
|
|
748
|
+
}
|
|
749
|
+
return current._def._config.transformer;
|
|
750
|
+
}
|
|
751
|
+
return prev;
|
|
752
|
+
}, defaultTransformer);
|
|
753
|
+
const router = createRouterFactory({
|
|
754
|
+
errorFormatter,
|
|
755
|
+
transformer,
|
|
756
|
+
isDev: routerList.some((r)=>r._def._config.isDev),
|
|
757
|
+
allowOutsideOfServer: routerList.some((r)=>r._def._config.allowOutsideOfServer),
|
|
758
|
+
isServer: routerList.some((r)=>r._def._config.isServer),
|
|
759
|
+
$types: routerList[0]?._def._config.$types
|
|
760
|
+
})(record);
|
|
761
|
+
return router;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
function mergeRoutersGeneric(...args) {
|
|
765
|
+
return mergeRouters(...args);
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
/**
|
|
769
|
+
* TODO: This can be improved:
|
|
770
|
+
* - We should be able to chain `.meta()`/`.context()` only once
|
|
771
|
+
* - Simplify typings
|
|
772
|
+
* - Doesn't need to be a class but it doesn't really hurt either
|
|
773
|
+
*/ class TRPCBuilder {
|
|
774
|
+
context() {
|
|
775
|
+
return new TRPCBuilder();
|
|
776
|
+
}
|
|
777
|
+
meta() {
|
|
778
|
+
return new TRPCBuilder();
|
|
779
|
+
}
|
|
780
|
+
create(options) {
|
|
781
|
+
return createTRPCInner()(options);
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
/**
|
|
785
|
+
* Initialize tRPC - be done exactly once per backend
|
|
786
|
+
*/ const initTRPC = new TRPCBuilder();
|
|
787
|
+
function createTRPCInner() {
|
|
788
|
+
return function initTRPCInner(runtime) {
|
|
789
|
+
const errorFormatter = runtime?.errorFormatter ?? defaultFormatter;
|
|
790
|
+
const transformer = getDataTransformer$1(runtime?.transformer ?? defaultTransformer);
|
|
791
|
+
const config = {
|
|
792
|
+
transformer,
|
|
793
|
+
isDev: runtime?.isDev ?? process.env.NODE_ENV !== 'production',
|
|
794
|
+
allowOutsideOfServer: runtime?.allowOutsideOfServer ?? false,
|
|
795
|
+
errorFormatter,
|
|
796
|
+
isServer: runtime?.isServer ?? isServerDefault,
|
|
797
|
+
/**
|
|
798
|
+
* @internal
|
|
799
|
+
*/ $types: createFlatProxy((key)=>{
|
|
800
|
+
throw new Error(`Tried to access "$types.${key}" which is not available at runtime`);
|
|
801
|
+
})
|
|
802
|
+
};
|
|
803
|
+
{
|
|
804
|
+
// Server check
|
|
805
|
+
const isServer = runtime?.isServer ?? isServerDefault;
|
|
806
|
+
if (!isServer && runtime?.allowOutsideOfServer !== true) {
|
|
807
|
+
throw new Error(`You're trying to use @trpc/server in a non-server environment. This is not supported by default.`);
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
return {
|
|
811
|
+
/**
|
|
812
|
+
* These are just types, they can't be used
|
|
813
|
+
* @internal
|
|
814
|
+
*/ _config: config,
|
|
815
|
+
/**
|
|
816
|
+
* Builder object for creating procedures
|
|
817
|
+
*/ procedure: createBuilder(),
|
|
818
|
+
/**
|
|
819
|
+
* Create reusable middlewares
|
|
820
|
+
*/ middleware: createMiddlewareFactory(),
|
|
821
|
+
/**
|
|
822
|
+
* Create a router
|
|
823
|
+
*/ router: createRouterFactory(config),
|
|
824
|
+
/**
|
|
825
|
+
* Merge Routers
|
|
826
|
+
*/ mergeRouters: mergeRoutersGeneric
|
|
827
|
+
};
|
|
828
|
+
};
|
|
829
|
+
}
|
|
830
|
+
|
|
832
831
|
export { createInputMiddleware, createOutputMiddleware, initTRPC, router };
|