@trpc/server 10.0.0-alpha.20 → 10.0.0-alpha.23
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/adapters/aws-lambda/dist/trpc-server-adapters-aws-lambda.cjs.d.ts +1 -0
- package/adapters/aws-lambda/dist/trpc-server-adapters-aws-lambda.cjs.dev.js +90 -0
- package/adapters/aws-lambda/dist/trpc-server-adapters-aws-lambda.cjs.js +7 -0
- package/adapters/aws-lambda/dist/trpc-server-adapters-aws-lambda.cjs.prod.js +90 -0
- package/adapters/aws-lambda/dist/trpc-server-adapters-aws-lambda.esm.js +86 -0
- package/adapters/express/dist/trpc-server-adapters-express.cjs.dev.js +4 -4
- package/adapters/express/dist/trpc-server-adapters-express.cjs.prod.js +4 -4
- package/adapters/express/dist/trpc-server-adapters-express.esm.js +4 -4
- package/adapters/fastify/dist/trpc-server-adapters-fastify.cjs.dev.js +5 -5
- package/adapters/fastify/dist/trpc-server-adapters-fastify.cjs.prod.js +5 -5
- package/adapters/fastify/dist/trpc-server-adapters-fastify.esm.js +5 -5
- package/adapters/fastify/index.js +1 -1
- package/adapters/fetch/index.d.ts +1 -0
- package/adapters/fetch/index.js +1 -0
- package/adapters/next/dist/trpc-server-adapters-next.cjs.dev.js +4 -4
- package/adapters/next/dist/trpc-server-adapters-next.cjs.prod.js +4 -4
- package/adapters/next/dist/trpc-server-adapters-next.esm.js +4 -4
- package/adapters/node-http/dist/trpc-server-adapters-node-http.cjs.dev.js +4 -4
- package/adapters/node-http/dist/trpc-server-adapters-node-http.cjs.prod.js +4 -4
- package/adapters/node-http/dist/trpc-server-adapters-node-http.esm.js +4 -4
- package/adapters/standalone/dist/trpc-server-adapters-standalone.cjs.dev.js +4 -4
- package/adapters/standalone/dist/trpc-server-adapters-standalone.cjs.prod.js +4 -4
- package/adapters/standalone/dist/trpc-server-adapters-standalone.esm.js +4 -4
- package/adapters/ws/dist/trpc-server-adapters-ws.cjs.dev.js +2 -2
- package/adapters/ws/dist/trpc-server-adapters-ws.cjs.prod.js +2 -2
- package/adapters/ws/dist/trpc-server-adapters-ws.esm.js +2 -2
- package/dist/TRPCError-7971540a.mjs +65 -0
- package/dist/{transformTRPCResponse-43a869de.js → TRPCError-ddec3395.js} +18 -59
- package/dist/TRPCError.d.ts +3 -3
- package/dist/TRPCError.d.ts.map +1 -1
- package/dist/adapters/express.js +5 -5
- package/dist/adapters/express.mjs +5 -5
- package/dist/adapters/fastify/fastifyRequestHandler.d.ts.map +1 -1
- package/dist/adapters/fastify/index.js +7 -8
- package/dist/adapters/fastify/index.mjs +6 -7
- package/dist/adapters/fetch/fetchRequestHandler.d.ts +8 -0
- package/dist/adapters/fetch/fetchRequestHandler.d.ts.map +1 -0
- package/dist/adapters/fetch/index.d.ts +3 -0
- package/dist/adapters/fetch/index.d.ts.map +1 -0
- package/dist/adapters/fetch/index.js +69 -0
- package/dist/adapters/fetch/index.mjs +65 -0
- package/dist/adapters/fetch/index.ts.js +1 -0
- package/dist/adapters/fetch/types.d.ts +21 -0
- package/dist/adapters/fetch/types.d.ts.map +1 -0
- package/dist/adapters/next.d.ts.map +1 -1
- package/dist/adapters/next.js +9 -10
- package/dist/adapters/next.mjs +8 -9
- package/dist/adapters/node-http/index.js +5 -5
- package/dist/adapters/node-http/index.mjs +5 -5
- package/dist/adapters/node-http/nodeHTTPRequestHandler.d.ts.map +1 -1
- package/dist/adapters/node-http/types.d.ts +9 -7
- package/dist/adapters/node-http/types.d.ts.map +1 -1
- package/dist/adapters/standalone.d.ts.map +1 -1
- package/dist/adapters/standalone.js +11 -8
- package/dist/adapters/standalone.mjs +11 -7
- package/dist/adapters/ws.d.ts +4 -4
- package/dist/adapters/ws.d.ts.map +1 -1
- package/dist/adapters/ws.js +117 -80
- package/dist/adapters/ws.mjs +112 -75
- package/dist/assertNotBrowser.d.ts.map +1 -1
- package/dist/{codes-7a3d4f65.mjs → envelopes-1deb2fa7.mjs} +19 -1
- package/dist/{codes-7f46544e.js → envelopes-a953b930.js} +18 -0
- package/dist/http/index.d.ts +1 -1
- package/dist/http/internals/getHTTPStatusCode.d.ts +1 -0
- package/dist/http/internals/getHTTPStatusCode.d.ts.map +1 -1
- package/dist/http/internals/types.d.ts +5 -4
- package/dist/http/internals/types.d.ts.map +1 -1
- package/dist/http/resolveHTTPResponse.d.ts +1 -1
- package/dist/http/resolveHTTPResponse.d.ts.map +1 -1
- package/dist/http/{ResponseMeta.d.ts → responseMeta.d.ts} +1 -1
- package/dist/http/responseMeta.d.ts.map +1 -0
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +45 -54
- package/dist/index.mjs +40 -47
- package/dist/internals/{BaseHandlerOptions.d.ts → baseHandlerOptions.d.ts} +2 -2
- package/dist/internals/{BaseHandlerOptions.d.ts.map → baseHandlerOptions.d.ts.map} +1 -1
- package/dist/internals/callProcedure.d.ts +2 -2
- package/dist/internals/callProcedure.d.ts.map +1 -1
- package/dist/internals/errors.d.ts +1 -0
- package/dist/internals/errors.d.ts.map +1 -1
- package/dist/internals/middlewares.d.ts +5 -2
- package/dist/internals/middlewares.d.ts.map +1 -1
- package/dist/internals/{OnErrorFunction.d.ts → onErrorFunction.d.ts} +1 -1
- package/dist/internals/{OnErrorFunction.d.ts.map → onErrorFunction.d.ts.map} +1 -1
- package/dist/internals/procedure.d.ts +20 -14
- package/dist/internals/procedure.d.ts.map +1 -1
- package/dist/internals/transformTRPCResponse.d.ts +4 -2
- package/dist/internals/transformTRPCResponse.d.ts.map +1 -1
- package/dist/{nodeHTTPRequestHandler-5fccb3bb.mjs → nodeHTTPRequestHandler-1cdb6383.mjs} +2 -3
- package/dist/{nodeHTTPRequestHandler-7d71ac09.js → nodeHTTPRequestHandler-848f07b5.js} +4 -5
- package/dist/observable/index.d.ts +5 -0
- package/dist/observable/index.d.ts.map +1 -0
- package/dist/observable/index.js +204 -0
- package/dist/observable/index.mjs +195 -0
- package/dist/observable/index.ts.js +1 -0
- package/dist/observable/internals/identity.d.ts +2 -0
- package/dist/observable/internals/identity.d.ts.map +1 -0
- package/dist/observable/internals/observableToPromise.d.ts +10 -0
- package/dist/observable/internals/observableToPromise.d.ts.map +1 -0
- package/dist/observable/internals/pipe.d.ts +4 -0
- package/dist/observable/internals/pipe.d.ts.map +1 -0
- package/dist/observable/observable.d.ts +5 -0
- package/dist/observable/observable.d.ts.map +1 -0
- package/dist/observable/operators/index.d.ts +4 -0
- package/dist/observable/operators/index.d.ts.map +1 -0
- package/dist/observable/operators/map.d.ts +3 -0
- package/dist/observable/operators/map.d.ts.map +1 -0
- package/dist/observable/operators/share.d.ts +6 -0
- package/dist/observable/operators/share.d.ts.map +1 -0
- package/dist/observable/operators/tap.d.ts +3 -0
- package/dist/observable/operators/tap.d.ts.map +1 -0
- package/dist/observable/types.d.ts +29 -0
- package/dist/observable/types.d.ts.map +1 -0
- package/dist/observable-137ea1bd.mjs +105 -0
- package/dist/observable-3aa4d911.js +108 -0
- package/dist/{resolveHTTPResponse-3292a84a.mjs → resolveHTTPResponse-54a79e6c.mjs} +18 -23
- package/dist/{resolveHTTPResponse-c3777a47.js → resolveHTTPResponse-ec3dccaa.js} +24 -29
- package/dist/router.d.ts +31 -27
- package/dist/router.d.ts.map +1 -1
- package/dist/rpc/codes.d.ts +2 -0
- package/dist/rpc/codes.d.ts.map +1 -1
- package/dist/rpc/envelopes.d.ts +61 -39
- package/dist/rpc/envelopes.d.ts.map +1 -1
- package/dist/rpc/index.js +7 -3
- package/dist/rpc/index.mjs +1 -1
- package/dist/subscription.d.ts +3 -52
- package/dist/subscription.d.ts.map +1 -1
- package/dist/subscription.js +44 -0
- package/dist/subscription.mjs +40 -0
- package/dist/subscription.ts.js +1 -0
- package/dist/transformTRPCResponse-333bed6c.js +56 -0
- package/dist/transformTRPCResponse-e0cba527.mjs +53 -0
- package/dist/types.d.ts +8 -0
- package/dist/types.d.ts.map +1 -1
- package/observable/index.d.ts +1 -0
- package/observable/index.js +1 -0
- package/package.json +30 -8
- package/rpc/dist/trpc-server-rpc.cjs.dev.js +1 -1
- package/rpc/dist/trpc-server-rpc.cjs.prod.js +1 -1
- package/rpc/dist/trpc-server-rpc.esm.js +1 -1
- package/src/TRPCError.ts +2 -2
- package/src/adapters/fastify/fastifyRequestHandler.ts +0 -1
- package/src/adapters/fastify/fastifyTRPCPlugin.ts +1 -1
- package/src/adapters/fetch/fetchRequestHandler.ts +61 -0
- package/src/adapters/fetch/index.ts +2 -0
- package/src/adapters/fetch/types.ts +28 -0
- package/src/adapters/next.ts +3 -5
- package/src/adapters/node-http/nodeHTTPRequestHandler.ts +0 -1
- package/src/adapters/node-http/types.ts +9 -7
- package/src/adapters/standalone.ts +10 -3
- package/src/adapters/ws.ts +115 -77
- package/src/assertNotBrowser.ts +1 -0
- package/src/http/index.ts +1 -1
- package/src/http/internals/getHTTPStatusCode.ts +1 -0
- package/src/http/internals/types.ts +5 -6
- package/src/http/resolveHTTPResponse.ts +20 -24
- package/src/http/{ResponseMeta.ts → responseMeta.ts} +0 -0
- package/src/index.ts +0 -1
- package/src/internals/{BaseHandlerOptions.ts → baseHandlerOptions.ts} +1 -1
- package/src/internals/callProcedure.ts +6 -3
- package/src/internals/errors.ts +20 -4
- package/src/internals/middlewares.ts +6 -2
- package/src/internals/{OnErrorFunction.ts → onErrorFunction.ts} +0 -0
- package/src/internals/procedure.ts +102 -42
- package/src/internals/transformTRPCResponse.ts +20 -15
- package/src/observable/index.ts +4 -0
- package/src/observable/internals/identity.ts +3 -0
- package/src/observable/internals/observableToPromise.ts +49 -0
- package/src/observable/internals/pipe.ts +22 -0
- package/src/observable/observable.test.ts +101 -0
- package/src/observable/observable.ts +75 -0
- package/src/observable/operators/index.ts +3 -0
- package/src/observable/operators/map.test.ts +92 -0
- package/src/observable/operators/map.ts +25 -0
- package/src/observable/operators/share.test.ts +60 -0
- package/src/observable/operators/share.ts +67 -0
- package/src/observable/operators/tap.ts +26 -0
- package/src/observable/types.ts +69 -0
- package/src/router.ts +96 -37
- package/src/rpc/codes.ts +1 -0
- package/src/rpc/envelopes.ts +87 -68
- package/src/subscription.ts +5 -123
- package/src/types.ts +7 -0
- package/dist/http/ResponseMeta.d.ts.map +0 -1
- package/dist/internals/wrapCallSafe.d.ts +0 -16
- package/dist/internals/wrapCallSafe.d.ts.map +0 -1
- package/dist/subscription-0d8a48ec.mjs +0 -133
- package/dist/subscription-41611bc2.js +0 -136
- package/dist/transformTRPCResponse-ff424ff4.mjs +0 -105
- package/src/internals/wrapCallSafe.ts +0 -19
- package/ws/dist/trpc-server-ws.cjs.d.ts +0 -1
- package/ws/dist/trpc-server-ws.cjs.dev.js +0 -15
- package/ws/dist/trpc-server-ws.cjs.js +0 -7
- package/ws/dist/trpc-server-ws.cjs.prod.js +0 -15
- package/ws/dist/trpc-server-ws.esm.js +0 -11
- package/ws/index.d.ts +0 -1
- package/ws/index.js +0 -1
|
@@ -2,9 +2,13 @@
|
|
|
2
2
|
import { TRPCError } from '../TRPCError';
|
|
3
3
|
import { assertNotBrowser } from '../assertNotBrowser';
|
|
4
4
|
import { ProcedureType } from '../router';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
5
|
+
import { InferLast } from '../types';
|
|
6
|
+
import { getCauseFromUnknown, getErrorFromUnknown } from './errors';
|
|
7
|
+
import {
|
|
8
|
+
MiddlewareFunction,
|
|
9
|
+
MiddlewareResult,
|
|
10
|
+
middlewareMarker,
|
|
11
|
+
} from './middlewares';
|
|
8
12
|
|
|
9
13
|
assertNotBrowser();
|
|
10
14
|
|
|
@@ -44,11 +48,12 @@ export type ProcedureResolver<TContext, TInput, TOutput> = (opts: {
|
|
|
44
48
|
type: ProcedureType;
|
|
45
49
|
}) => Promise<TOutput> | TOutput;
|
|
46
50
|
|
|
47
|
-
interface ProcedureOptions<TContext, TInput, TOutput, TParsedOutput> {
|
|
48
|
-
middlewares: Array<MiddlewareFunction<any, any>>;
|
|
51
|
+
interface ProcedureOptions<TContext, TMeta, TInput, TOutput, TParsedOutput> {
|
|
52
|
+
middlewares: Array<MiddlewareFunction<any, any, any>>;
|
|
49
53
|
resolver: ProcedureResolver<TContext, TInput, TOutput>;
|
|
50
54
|
inputParser: ProcedureParser<TInput>;
|
|
51
55
|
outputParser: ProcedureParser<TParsedOutput>;
|
|
56
|
+
meta: TMeta;
|
|
52
57
|
}
|
|
53
58
|
|
|
54
59
|
/**
|
|
@@ -100,21 +105,29 @@ function getParseFn<T>(procedureParser: ProcedureParser<T>): ParseFn<T> {
|
|
|
100
105
|
export class Procedure<
|
|
101
106
|
TInputContext,
|
|
102
107
|
TContext,
|
|
108
|
+
TMeta,
|
|
103
109
|
TInput,
|
|
104
110
|
TParsedInput,
|
|
105
111
|
TOutput,
|
|
106
112
|
TParsedOutput,
|
|
107
113
|
TFinalOutput = unknown extends TParsedOutput ? TOutput : TParsedOutput,
|
|
108
114
|
> {
|
|
109
|
-
private middlewares: Readonly<Array<MiddlewareFunction<any, any>>>;
|
|
115
|
+
private middlewares: Readonly<Array<MiddlewareFunction<any, any, any>>>;
|
|
110
116
|
private resolver: ProcedureResolver<TContext, TParsedInput, TOutput>;
|
|
111
117
|
private readonly inputParser: ProcedureParser<TParsedInput>;
|
|
112
118
|
private parseInputFn: ParseFn<TParsedInput>;
|
|
113
119
|
private readonly outputParser: ProcedureParser<TFinalOutput>;
|
|
114
120
|
private parseOutputFn: ParseFn<TFinalOutput>;
|
|
121
|
+
public readonly meta: TMeta;
|
|
115
122
|
|
|
116
123
|
constructor(
|
|
117
|
-
opts: ProcedureOptions<
|
|
124
|
+
opts: ProcedureOptions<
|
|
125
|
+
TContext,
|
|
126
|
+
TMeta,
|
|
127
|
+
TParsedInput,
|
|
128
|
+
TOutput,
|
|
129
|
+
TFinalOutput
|
|
130
|
+
>,
|
|
118
131
|
) {
|
|
119
132
|
this.middlewares = opts.middlewares;
|
|
120
133
|
this.resolver = opts.resolver;
|
|
@@ -122,6 +135,7 @@ export class Procedure<
|
|
|
122
135
|
this.parseInputFn = getParseFn(this.inputParser);
|
|
123
136
|
this.outputParser = opts.outputParser;
|
|
124
137
|
this.parseOutputFn = getParseFn(this.outputParser);
|
|
138
|
+
this.meta = opts.meta;
|
|
125
139
|
}
|
|
126
140
|
|
|
127
141
|
private async parseInput(rawInput: unknown): Promise<TParsedInput> {
|
|
@@ -130,7 +144,7 @@ export class Procedure<
|
|
|
130
144
|
} catch (cause) {
|
|
131
145
|
throw new TRPCError({
|
|
132
146
|
code: 'BAD_REQUEST',
|
|
133
|
-
cause,
|
|
147
|
+
cause: getCauseFromUnknown(cause),
|
|
134
148
|
});
|
|
135
149
|
}
|
|
136
150
|
}
|
|
@@ -141,7 +155,7 @@ export class Procedure<
|
|
|
141
155
|
} catch (cause) {
|
|
142
156
|
throw new TRPCError({
|
|
143
157
|
code: 'INTERNAL_SERVER_ERROR',
|
|
144
|
-
cause,
|
|
158
|
+
cause: getCauseFromUnknown(cause),
|
|
145
159
|
message: 'Output validation failed',
|
|
146
160
|
});
|
|
147
161
|
}
|
|
@@ -156,9 +170,13 @@ export class Procedure<
|
|
|
156
170
|
): Promise<TFinalOutput> {
|
|
157
171
|
// wrap the actual resolver and treat as the last "middleware"
|
|
158
172
|
const middlewaresWithResolver = this.middlewares.concat([
|
|
159
|
-
async ({ ctx }: { ctx:
|
|
173
|
+
async ({ ctx }: { ctx: any }) => {
|
|
160
174
|
const input = await this.parseInput(opts.rawInput);
|
|
161
|
-
const rawOutput = await this.resolver({
|
|
175
|
+
const rawOutput = await this.resolver({
|
|
176
|
+
...opts,
|
|
177
|
+
ctx,
|
|
178
|
+
input,
|
|
179
|
+
});
|
|
162
180
|
const data = await this.parseOutput(rawOutput);
|
|
163
181
|
return {
|
|
164
182
|
marker: middlewareMarker,
|
|
@@ -169,30 +187,40 @@ export class Procedure<
|
|
|
169
187
|
},
|
|
170
188
|
]);
|
|
171
189
|
|
|
172
|
-
//
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
190
|
+
// run the middlewares recursively with the resolver as the last one
|
|
191
|
+
const callRecursive = async (
|
|
192
|
+
callOpts: { ctx: any; index: number } = {
|
|
193
|
+
index: 0,
|
|
194
|
+
ctx: opts.ctx,
|
|
195
|
+
},
|
|
196
|
+
): Promise<MiddlewareResult<any>> => {
|
|
197
|
+
try {
|
|
198
|
+
const result = await middlewaresWithResolver[callOpts.index]({
|
|
199
|
+
ctx: callOpts.ctx,
|
|
200
|
+
type: opts.type,
|
|
201
|
+
path: opts.path,
|
|
202
|
+
rawInput: opts.rawInput,
|
|
203
|
+
meta: this.meta,
|
|
204
|
+
next: async (nextOpts?: { ctx: any }) => {
|
|
205
|
+
return await callRecursive({
|
|
206
|
+
index: callOpts.index + 1,
|
|
207
|
+
ctx: nextOpts ? nextOpts.ctx : callOpts.ctx,
|
|
208
|
+
});
|
|
209
|
+
},
|
|
210
|
+
});
|
|
211
|
+
return result;
|
|
212
|
+
} catch (cause) {
|
|
187
213
|
return {
|
|
188
|
-
|
|
189
|
-
|
|
214
|
+
ctx: callOpts.ctx,
|
|
215
|
+
ok: false,
|
|
216
|
+
error: getErrorFromUnknown(cause),
|
|
217
|
+
marker: middlewareMarker,
|
|
190
218
|
};
|
|
191
|
-
}
|
|
192
|
-
}
|
|
219
|
+
}
|
|
220
|
+
};
|
|
193
221
|
|
|
194
222
|
// there's always at least one "next" since we wrap this.resolver in a middleware
|
|
195
|
-
const result = await
|
|
223
|
+
const result = await callRecursive();
|
|
196
224
|
if (!result) {
|
|
197
225
|
throw new TRPCError({
|
|
198
226
|
code: 'INTERNAL_SERVER_ERROR',
|
|
@@ -213,14 +241,21 @@ export class Procedure<
|
|
|
213
241
|
* @param middlewares
|
|
214
242
|
*/
|
|
215
243
|
public inheritMiddlewares(
|
|
216
|
-
middlewares: MiddlewareFunction<TInputContext, TContext>[],
|
|
244
|
+
middlewares: MiddlewareFunction<TInputContext, TContext, TMeta>[],
|
|
217
245
|
): this {
|
|
218
246
|
const Constructor: {
|
|
219
247
|
new (
|
|
220
|
-
opts: ProcedureOptions<
|
|
248
|
+
opts: ProcedureOptions<
|
|
249
|
+
TContext,
|
|
250
|
+
TMeta,
|
|
251
|
+
TParsedInput,
|
|
252
|
+
TOutput,
|
|
253
|
+
TFinalOutput
|
|
254
|
+
>,
|
|
221
255
|
): Procedure<
|
|
222
256
|
TInputContext,
|
|
223
257
|
TContext,
|
|
258
|
+
TMeta,
|
|
224
259
|
TInput,
|
|
225
260
|
TParsedInput,
|
|
226
261
|
TOutput,
|
|
@@ -233,20 +268,23 @@ export class Procedure<
|
|
|
233
268
|
resolver: this.resolver,
|
|
234
269
|
inputParser: this.inputParser,
|
|
235
270
|
outputParser: this.outputParser,
|
|
271
|
+
meta: this.meta,
|
|
236
272
|
});
|
|
237
273
|
|
|
238
274
|
return instance as any;
|
|
239
275
|
}
|
|
240
276
|
}
|
|
241
277
|
|
|
242
|
-
export type CreateProcedureWithInput<TContext, TInput, TOutput> = {
|
|
278
|
+
export type CreateProcedureWithInput<TContext, TMeta, TInput, TOutput> = {
|
|
243
279
|
input: ProcedureParser<TInput>;
|
|
244
280
|
output?: ProcedureParser<TOutput>;
|
|
245
|
-
|
|
281
|
+
meta?: TMeta;
|
|
282
|
+
resolve: ProcedureResolver<TContext, TInput, InferLast<TOutput>>;
|
|
246
283
|
};
|
|
247
284
|
|
|
248
285
|
export type CreateProcedureWithInputOutputParser<
|
|
249
286
|
TContext,
|
|
287
|
+
TMeta,
|
|
250
288
|
TInput,
|
|
251
289
|
TParsedInput,
|
|
252
290
|
TOutput,
|
|
@@ -254,18 +292,26 @@ export type CreateProcedureWithInputOutputParser<
|
|
|
254
292
|
> = {
|
|
255
293
|
input: ProcedureParserWithInputOutput<TInput, TParsedInput>;
|
|
256
294
|
output?: ProcedureParserWithInputOutput<TOutput, TParsedOutput>;
|
|
257
|
-
|
|
295
|
+
meta?: TMeta;
|
|
296
|
+
resolve: ProcedureResolver<TContext, TParsedInput, InferLast<TOutput>>;
|
|
258
297
|
};
|
|
259
298
|
|
|
260
|
-
export type CreateProcedureWithoutInput<
|
|
299
|
+
export type CreateProcedureWithoutInput<
|
|
300
|
+
TContext,
|
|
301
|
+
TMeta,
|
|
302
|
+
TOutput,
|
|
303
|
+
TParsedOutput,
|
|
304
|
+
> = {
|
|
261
305
|
output?:
|
|
262
306
|
| ProcedureParserWithInputOutput<TOutput, TParsedOutput>
|
|
263
307
|
| ProcedureParser<TOutput>;
|
|
264
|
-
|
|
308
|
+
meta?: TMeta;
|
|
309
|
+
resolve: ProcedureResolver<TContext, undefined, InferLast<TOutput>>;
|
|
265
310
|
};
|
|
266
311
|
|
|
267
312
|
export type CreateProcedureOptions<
|
|
268
313
|
TContext,
|
|
314
|
+
TMeta = undefined,
|
|
269
315
|
TInput = undefined,
|
|
270
316
|
TParsedInput = undefined,
|
|
271
317
|
TOutput = undefined,
|
|
@@ -273,16 +319,18 @@ export type CreateProcedureOptions<
|
|
|
273
319
|
> =
|
|
274
320
|
| CreateProcedureWithInputOutputParser<
|
|
275
321
|
TContext,
|
|
322
|
+
TMeta,
|
|
276
323
|
TInput,
|
|
277
324
|
TParsedInput,
|
|
278
325
|
TOutput,
|
|
279
326
|
TParsedOutput
|
|
280
327
|
>
|
|
281
|
-
| CreateProcedureWithInput<TContext, TInput, TOutput>
|
|
282
|
-
| CreateProcedureWithoutInput<TContext, TOutput, TParsedOutput>;
|
|
328
|
+
| CreateProcedureWithInput<TContext, TMeta, TInput, TOutput>
|
|
329
|
+
| CreateProcedureWithoutInput<TContext, TMeta, TOutput, TParsedOutput>;
|
|
283
330
|
|
|
284
331
|
export function createProcedure<
|
|
285
332
|
TContext,
|
|
333
|
+
TMeta,
|
|
286
334
|
TInput,
|
|
287
335
|
TParsedInput,
|
|
288
336
|
TOutput,
|
|
@@ -290,12 +338,21 @@ export function createProcedure<
|
|
|
290
338
|
>(
|
|
291
339
|
opts: CreateProcedureOptions<
|
|
292
340
|
TContext,
|
|
341
|
+
TMeta,
|
|
293
342
|
TInput,
|
|
294
343
|
TParsedInput,
|
|
295
344
|
TOutput,
|
|
296
345
|
TParsedOutput
|
|
297
346
|
>,
|
|
298
|
-
): Procedure<
|
|
347
|
+
): Procedure<
|
|
348
|
+
unknown,
|
|
349
|
+
TContext,
|
|
350
|
+
TMeta,
|
|
351
|
+
TInput,
|
|
352
|
+
TParsedInput,
|
|
353
|
+
TOutput,
|
|
354
|
+
TParsedOutput
|
|
355
|
+
> {
|
|
299
356
|
const inputParser =
|
|
300
357
|
'input' in opts
|
|
301
358
|
? opts.input
|
|
@@ -319,14 +376,16 @@ export function createProcedure<
|
|
|
319
376
|
resolver: opts.resolve as any,
|
|
320
377
|
middlewares: [],
|
|
321
378
|
outputParser: outputParser as any,
|
|
379
|
+
meta: opts.meta as any,
|
|
322
380
|
});
|
|
323
381
|
}
|
|
324
382
|
|
|
325
383
|
export type inferProcedureFromOptions<
|
|
326
384
|
TInputContext,
|
|
327
|
-
TOptions extends CreateProcedureOptions<any, any, any, any, any>,
|
|
385
|
+
TOptions extends CreateProcedureOptions<any, any, any, any, any, any>,
|
|
328
386
|
> = TOptions extends CreateProcedureOptions<
|
|
329
387
|
infer TContext,
|
|
388
|
+
infer TMeta,
|
|
330
389
|
infer TInput,
|
|
331
390
|
infer TParsedInput,
|
|
332
391
|
infer TOutput,
|
|
@@ -335,6 +394,7 @@ export type inferProcedureFromOptions<
|
|
|
335
394
|
? Procedure<
|
|
336
395
|
TInputContext,
|
|
337
396
|
TContext,
|
|
397
|
+
TMeta,
|
|
338
398
|
unknown extends TInput ? undefined : TInput,
|
|
339
399
|
unknown extends TParsedInput ? undefined : TParsedInput,
|
|
340
400
|
TOutput,
|
|
@@ -1,33 +1,38 @@
|
|
|
1
1
|
import { AnyRouter } from '../router';
|
|
2
|
-
import { TRPCResponse } from '../rpc';
|
|
2
|
+
import { TRPCResponse, TRPCResponseMessage } from '../rpc';
|
|
3
3
|
|
|
4
|
-
function transformTRPCResponseItem
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
): TRPCResponse {
|
|
4
|
+
function transformTRPCResponseItem<
|
|
5
|
+
TResponseItem extends TRPCResponse | TRPCResponseMessage,
|
|
6
|
+
>(router: AnyRouter, item: TResponseItem): TResponseItem {
|
|
8
7
|
if ('error' in item) {
|
|
9
8
|
return {
|
|
10
9
|
...item,
|
|
11
10
|
error: router._def.transformer.output.serialize(item.error),
|
|
12
11
|
};
|
|
13
12
|
}
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
|
|
14
|
+
if ('data' in item.result) {
|
|
15
|
+
return {
|
|
16
|
+
...item,
|
|
17
|
+
result: {
|
|
18
|
+
...item.result,
|
|
19
|
+
data: router._def.transformer.output.serialize(item.result.data),
|
|
20
|
+
},
|
|
21
|
+
};
|
|
16
22
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
result: {
|
|
20
|
-
...item.result,
|
|
21
|
-
data: router._def.transformer.output.serialize(item.result.data),
|
|
22
|
-
},
|
|
23
|
-
};
|
|
23
|
+
|
|
24
|
+
return item;
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
/**
|
|
27
28
|
* Takes a unserialized `TRPCResponse` and serializes it with the router's transformers
|
|
28
29
|
**/
|
|
29
30
|
export function transformTRPCResponse<
|
|
30
|
-
TResponse extends
|
|
31
|
+
TResponse extends
|
|
32
|
+
| TRPCResponse
|
|
33
|
+
| TRPCResponse[]
|
|
34
|
+
| TRPCResponseMessage
|
|
35
|
+
| TRPCResponseMessage[],
|
|
31
36
|
>(router: AnyRouter, itemOrItems: TResponse) {
|
|
32
37
|
return Array.isArray(itemOrItems)
|
|
33
38
|
? itemOrItems.map((item) => transformTRPCResponseItem(router, item))
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Observable } from '../types';
|
|
2
|
+
|
|
3
|
+
export class ObservableAbortError extends Error {
|
|
4
|
+
constructor(message: string) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.name = 'ObservableAbortError';
|
|
7
|
+
Object.setPrototypeOf(this, ObservableAbortError.prototype);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** @internal */
|
|
12
|
+
export function observableToPromise<TValue>(
|
|
13
|
+
observable: Observable<TValue, unknown>,
|
|
14
|
+
) {
|
|
15
|
+
let abort: () => void;
|
|
16
|
+
const promise = new Promise<TValue>((resolve, reject) => {
|
|
17
|
+
let isDone = false;
|
|
18
|
+
function onDone() {
|
|
19
|
+
if (isDone) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
isDone = true;
|
|
23
|
+
reject(new ObservableAbortError('This operation was cancelled.'));
|
|
24
|
+
obs$.unsubscribe();
|
|
25
|
+
}
|
|
26
|
+
const obs$ = observable.subscribe({
|
|
27
|
+
next(data) {
|
|
28
|
+
isDone = true;
|
|
29
|
+
resolve(data);
|
|
30
|
+
onDone();
|
|
31
|
+
},
|
|
32
|
+
error(data) {
|
|
33
|
+
isDone = true;
|
|
34
|
+
reject(data);
|
|
35
|
+
onDone();
|
|
36
|
+
},
|
|
37
|
+
complete() {
|
|
38
|
+
isDone = true;
|
|
39
|
+
onDone();
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
abort = onDone;
|
|
43
|
+
});
|
|
44
|
+
return {
|
|
45
|
+
promise,
|
|
46
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
47
|
+
abort: abort!,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { UnaryFunction } from '../types';
|
|
2
|
+
import { identity } from './identity';
|
|
3
|
+
|
|
4
|
+
/** @internal */
|
|
5
|
+
export function pipeFromArray<T, R>(
|
|
6
|
+
fns: Array<UnaryFunction<T, R>>,
|
|
7
|
+
): UnaryFunction<T, R> {
|
|
8
|
+
if (fns.length === 0) {
|
|
9
|
+
return identity as UnaryFunction<any, any>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
if (fns.length === 1) {
|
|
13
|
+
return fns[0];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return function piped(input: T): R {
|
|
17
|
+
return fns.reduce(
|
|
18
|
+
(prev: any, fn: UnaryFunction<T, R>) => fn(prev),
|
|
19
|
+
input as any,
|
|
20
|
+
);
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-empty-function */
|
|
2
|
+
import { observable, share, tap } from '.';
|
|
3
|
+
|
|
4
|
+
test('vanilla observable - complete()', () => {
|
|
5
|
+
const obs = observable<number, Error>((observer) => {
|
|
6
|
+
observer.next(1);
|
|
7
|
+
observer.complete();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const next = jest.fn();
|
|
11
|
+
const error = jest.fn();
|
|
12
|
+
const complete = jest.fn();
|
|
13
|
+
obs.subscribe({
|
|
14
|
+
next,
|
|
15
|
+
error,
|
|
16
|
+
complete,
|
|
17
|
+
});
|
|
18
|
+
expect(next.mock.calls).toHaveLength(1);
|
|
19
|
+
expect(complete.mock.calls).toHaveLength(1);
|
|
20
|
+
expect(error.mock.calls).toHaveLength(0);
|
|
21
|
+
expect(next.mock.calls[0][0]).toBe(1);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('vanilla observable - unsubscribe()', () => {
|
|
25
|
+
const obs$ = observable<number, Error>((observer) => {
|
|
26
|
+
observer.next(1);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const next = jest.fn();
|
|
30
|
+
const error = jest.fn();
|
|
31
|
+
const complete = jest.fn();
|
|
32
|
+
const sub = obs$.subscribe({
|
|
33
|
+
next,
|
|
34
|
+
error,
|
|
35
|
+
complete,
|
|
36
|
+
});
|
|
37
|
+
sub.unsubscribe();
|
|
38
|
+
expect(next.mock.calls).toHaveLength(1);
|
|
39
|
+
expect(complete.mock.calls).toHaveLength(0);
|
|
40
|
+
expect(error.mock.calls).toHaveLength(0);
|
|
41
|
+
expect(next.mock.calls[0][0]).toBe(1);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test('pipe - combine operators', () => {
|
|
45
|
+
const taps = {
|
|
46
|
+
next: jest.fn(),
|
|
47
|
+
complete: jest.fn(),
|
|
48
|
+
error: jest.fn(),
|
|
49
|
+
};
|
|
50
|
+
const obs = observable<number, Error>((observer) => {
|
|
51
|
+
observer.next(1);
|
|
52
|
+
}).pipe(
|
|
53
|
+
// operators:
|
|
54
|
+
share(),
|
|
55
|
+
tap(taps),
|
|
56
|
+
);
|
|
57
|
+
{
|
|
58
|
+
const next = jest.fn();
|
|
59
|
+
const error = jest.fn();
|
|
60
|
+
const complete = jest.fn();
|
|
61
|
+
obs.subscribe({
|
|
62
|
+
next,
|
|
63
|
+
error,
|
|
64
|
+
complete,
|
|
65
|
+
});
|
|
66
|
+
expect(next.mock.calls).toHaveLength(1);
|
|
67
|
+
expect(complete.mock.calls).toHaveLength(0);
|
|
68
|
+
expect(error.mock.calls).toHaveLength(0);
|
|
69
|
+
expect(next.mock.calls[0][0]).toBe(1);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
{
|
|
73
|
+
const next = jest.fn();
|
|
74
|
+
const error = jest.fn();
|
|
75
|
+
const complete = jest.fn();
|
|
76
|
+
obs.subscribe({
|
|
77
|
+
next,
|
|
78
|
+
error,
|
|
79
|
+
complete,
|
|
80
|
+
});
|
|
81
|
+
expect(next.mock.calls).toHaveLength(0);
|
|
82
|
+
expect(complete.mock.calls).toHaveLength(0);
|
|
83
|
+
expect(error.mock.calls).toHaveLength(0);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
expect({
|
|
87
|
+
next: taps.next.mock.calls,
|
|
88
|
+
error: taps.error.mock.calls,
|
|
89
|
+
complete: taps.complete.mock.calls,
|
|
90
|
+
}).toMatchInlineSnapshot(`
|
|
91
|
+
Object {
|
|
92
|
+
"complete": Array [],
|
|
93
|
+
"error": Array [],
|
|
94
|
+
"next": Array [
|
|
95
|
+
Array [
|
|
96
|
+
1,
|
|
97
|
+
],
|
|
98
|
+
],
|
|
99
|
+
}
|
|
100
|
+
`);
|
|
101
|
+
});
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { pipeFromArray } from './internals/pipe';
|
|
2
|
+
import { Observable, Observer, OperatorFunction, TeardownLogic } from './types';
|
|
3
|
+
|
|
4
|
+
export type inferObservableValue<
|
|
5
|
+
TObservable extends Observable<unknown, unknown>,
|
|
6
|
+
> = TObservable extends Observable<infer TValue, unknown> ? TValue : never;
|
|
7
|
+
|
|
8
|
+
export function isObservable(x: unknown): x is Observable<unknown, unknown> {
|
|
9
|
+
return typeof x === 'object' && x !== null && 'subscribe' in x;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function observable<TValue, TError = unknown>(
|
|
13
|
+
subscribe: (observer: Observer<TValue, TError>) => TeardownLogic,
|
|
14
|
+
): Observable<TValue, TError> {
|
|
15
|
+
const self: Observable<TValue, TError> = {
|
|
16
|
+
subscribe(observer) {
|
|
17
|
+
let teardownRef: TeardownLogic | null = null;
|
|
18
|
+
let isDone = false;
|
|
19
|
+
let unsubscribed = false;
|
|
20
|
+
let teardownImmediately = false;
|
|
21
|
+
function unsubscribe() {
|
|
22
|
+
if (teardownRef === null) {
|
|
23
|
+
teardownImmediately = true;
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (unsubscribed) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
unsubscribed = true;
|
|
30
|
+
|
|
31
|
+
if (typeof teardownRef === 'function') {
|
|
32
|
+
teardownRef();
|
|
33
|
+
} else if (teardownRef) {
|
|
34
|
+
teardownRef.unsubscribe();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
teardownRef = subscribe({
|
|
38
|
+
next(value) {
|
|
39
|
+
if (isDone) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
observer.next?.(value);
|
|
43
|
+
},
|
|
44
|
+
error(err) {
|
|
45
|
+
if (isDone) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
isDone = true;
|
|
49
|
+
observer.error?.(err);
|
|
50
|
+
unsubscribe();
|
|
51
|
+
},
|
|
52
|
+
complete() {
|
|
53
|
+
if (isDone) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
isDone = true;
|
|
57
|
+
observer.complete?.();
|
|
58
|
+
unsubscribe();
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
if (teardownImmediately) {
|
|
62
|
+
unsubscribe();
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
unsubscribe,
|
|
66
|
+
};
|
|
67
|
+
},
|
|
68
|
+
pipe(
|
|
69
|
+
...operations: OperatorFunction<any, any, any, any>[]
|
|
70
|
+
): Observable<any, any> {
|
|
71
|
+
return pipeFromArray(operations)(self) as any;
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
return self;
|
|
75
|
+
}
|