@trpc/server 10.0.0-alpha.23 → 10.0.0-alpha.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (196) hide show
  1. package/adapters/aws-lambda/dist/trpc-server-adapters-aws-lambda.cjs.d.ts +1 -1
  2. package/adapters/aws-lambda/dist/trpc-server-adapters-aws-lambda.cjs.dev.js +100 -20
  3. package/adapters/aws-lambda/dist/trpc-server-adapters-aws-lambda.cjs.prod.js +100 -20
  4. package/adapters/aws-lambda/dist/trpc-server-adapters-aws-lambda.esm.js +99 -19
  5. package/adapters/aws-lambda/index.d.ts +1 -0
  6. package/adapters/aws-lambda/index.js +1 -0
  7. package/adapters/lambda/dist/trpc-server-adapters-lambda.cjs.d.ts +1 -0
  8. package/adapters/lambda/dist/trpc-server-adapters-lambda.cjs.dev.js +25 -0
  9. package/adapters/lambda/dist/trpc-server-adapters-lambda.cjs.js +7 -0
  10. package/adapters/lambda/dist/trpc-server-adapters-lambda.cjs.prod.js +25 -0
  11. package/adapters/lambda/dist/trpc-server-adapters-lambda.esm.js +21 -0
  12. package/dist/TRPCError.d.ts.map +1 -1
  13. package/dist/adapters/aws-lambda/index.d.ts +14 -0
  14. package/dist/adapters/aws-lambda/index.d.ts.map +1 -0
  15. package/dist/adapters/aws-lambda/utils.d.ts +34 -0
  16. package/dist/adapters/aws-lambda/utils.d.ts.map +1 -0
  17. package/dist/adapters/express.d.ts +1 -1
  18. package/dist/adapters/express.d.ts.map +1 -1
  19. package/dist/adapters/express.js +4 -4
  20. package/dist/adapters/express.mjs +4 -4
  21. package/dist/adapters/fastify/fastifyRequestHandler.d.ts +1 -1
  22. package/dist/adapters/fastify/fastifyRequestHandler.d.ts.map +1 -1
  23. package/dist/adapters/fastify/fastifyTRPCPlugin.d.ts +1 -1
  24. package/dist/adapters/fastify/fastifyTRPCPlugin.d.ts.map +1 -1
  25. package/dist/adapters/fastify/index.js +3 -3
  26. package/dist/adapters/fastify/index.mjs +3 -3
  27. package/dist/adapters/fetch/fetchRequestHandler.d.ts +1 -1
  28. package/dist/adapters/fetch/fetchRequestHandler.d.ts.map +1 -1
  29. package/dist/adapters/fetch/index.js +3 -3
  30. package/dist/adapters/fetch/index.mjs +3 -3
  31. package/dist/adapters/fetch/types.d.ts +1 -1
  32. package/dist/adapters/fetch/types.d.ts.map +1 -1
  33. package/dist/adapters/lambda/index.d.ts +12 -0
  34. package/dist/adapters/lambda/index.d.ts.map +1 -0
  35. package/dist/adapters/next.d.ts +1 -1
  36. package/dist/adapters/next.d.ts.map +1 -1
  37. package/dist/adapters/next.js +4 -4
  38. package/dist/adapters/next.mjs +4 -4
  39. package/dist/adapters/node-http/index.js +4 -4
  40. package/dist/adapters/node-http/index.mjs +4 -4
  41. package/dist/adapters/node-http/nodeHTTPRequestHandler.d.ts +1 -1
  42. package/dist/adapters/node-http/nodeHTTPRequestHandler.d.ts.map +1 -1
  43. package/dist/adapters/node-http/types.d.ts +3 -3
  44. package/dist/adapters/node-http/types.d.ts.map +1 -1
  45. package/dist/adapters/standalone.d.ts +2 -2
  46. package/dist/adapters/standalone.d.ts.map +1 -1
  47. package/dist/adapters/standalone.js +4 -4
  48. package/dist/adapters/standalone.mjs +4 -4
  49. package/dist/adapters/ws.d.ts +3 -2
  50. package/dist/adapters/ws.d.ts.map +1 -1
  51. package/dist/adapters/ws.js +3 -8
  52. package/dist/adapters/ws.mjs +3 -8
  53. package/dist/core/index.d.ts +5 -0
  54. package/dist/core/index.d.ts.map +1 -0
  55. package/dist/core/initTRPC.d.ts +82 -0
  56. package/dist/core/initTRPC.d.ts.map +1 -0
  57. package/dist/core/internals/__generated__/mergeRoutersGeneric.d.ts +202 -0
  58. package/dist/core/internals/__generated__/mergeRoutersGeneric.d.ts.map +1 -0
  59. package/dist/core/internals/config.d.ts +38 -0
  60. package/dist/core/internals/config.d.ts.map +1 -0
  61. package/dist/core/internals/getParseFn.d.ts +9 -0
  62. package/dist/core/internals/getParseFn.d.ts.map +1 -0
  63. package/dist/core/internals/internalProcedure.d.ts +61 -0
  64. package/dist/core/internals/internalProcedure.d.ts.map +1 -0
  65. package/dist/core/internals/mergeRouters.d.ts +3 -0
  66. package/dist/core/internals/mergeRouters.d.ts.map +1 -0
  67. package/dist/core/internals/mergeWithoutOverrides.d.ts +5 -0
  68. package/dist/core/internals/mergeWithoutOverrides.d.ts.map +1 -0
  69. package/dist/core/internals/omitPrototype.d.ts +6 -0
  70. package/dist/core/internals/omitPrototype.d.ts.map +1 -0
  71. package/dist/core/internals/procedureBuilder.d.ts +71 -0
  72. package/dist/core/internals/procedureBuilder.d.ts.map +1 -0
  73. package/dist/core/internals/utils.d.ts +44 -0
  74. package/dist/core/internals/utils.d.ts.map +1 -0
  75. package/dist/core/middleware.d.ts +78 -0
  76. package/dist/core/middleware.d.ts.map +1 -0
  77. package/dist/core/parser.d.ts +25 -0
  78. package/dist/core/parser.d.ts.map +1 -0
  79. package/dist/core/procedure.d.ts +57 -0
  80. package/dist/core/procedure.d.ts.map +1 -0
  81. package/dist/core/router.d.ts +110 -0
  82. package/dist/core/router.d.ts.map +1 -0
  83. package/dist/core/types.d.ts +17 -0
  84. package/dist/core/types.d.ts.map +1 -0
  85. package/dist/{internals → deprecated/internals}/callProcedure.d.ts +4 -1
  86. package/dist/deprecated/internals/callProcedure.d.ts.map +1 -0
  87. package/dist/{internals → deprecated/internals}/middlewares.d.ts +16 -1
  88. package/dist/deprecated/internals/middlewares.d.ts.map +1 -0
  89. package/dist/{internals → deprecated/internals}/procedure.d.ts +10 -1
  90. package/dist/deprecated/internals/procedure.d.ts.map +1 -0
  91. package/dist/deprecated/interop.d.ts +34 -0
  92. package/dist/deprecated/interop.d.ts.map +1 -0
  93. package/dist/{router.d.ts → deprecated/router.d.ts} +27 -6
  94. package/dist/deprecated/router.d.ts.map +1 -0
  95. package/dist/{envelopes-1deb2fa7.mjs → envelopes-af8c2959.mjs} +12 -1
  96. package/dist/{envelopes-a953b930.js → envelopes-b6dd0367.js} +11 -1
  97. package/dist/error/TRPCError.d.ts +11 -0
  98. package/dist/error/TRPCError.d.ts.map +1 -0
  99. package/dist/error/formatter.d.ts +33 -0
  100. package/dist/error/formatter.d.ts.map +1 -0
  101. package/dist/error/utils.d.ts +5 -0
  102. package/dist/error/utils.d.ts.map +1 -0
  103. package/dist/http/index.d.ts +1 -1
  104. package/dist/http/index.d.ts.map +1 -1
  105. package/dist/http/internals/types.d.ts +9 -7
  106. package/dist/http/internals/types.d.ts.map +1 -1
  107. package/dist/http/resolveHTTPResponse.d.ts +1 -1
  108. package/dist/http/resolveHTTPResponse.d.ts.map +1 -1
  109. package/dist/http/{responseMeta.d.ts → types.d.ts} +1 -1
  110. package/dist/http/types.d.ts.map +1 -0
  111. package/dist/index.d.ts +2 -1
  112. package/dist/index.d.ts.map +1 -1
  113. package/dist/index.js +686 -12
  114. package/dist/index.mjs +688 -16
  115. package/dist/internals/transformTRPCResponse.d.ts +1 -1
  116. package/dist/internals/transformTRPCResponse.d.ts.map +1 -1
  117. package/dist/internals/types.d.ts +23 -0
  118. package/dist/internals/types.d.ts.map +1 -0
  119. package/dist/{nodeHTTPRequestHandler-1cdb6383.mjs → nodeHTTPRequestHandler-5ad62229.mjs} +1 -1
  120. package/dist/{nodeHTTPRequestHandler-848f07b5.js → nodeHTTPRequestHandler-9ddd18f2.js} +1 -1
  121. package/dist/{resolveHTTPResponse-ec3dccaa.js → resolveHTTPResponse-5932d785.js} +16 -10
  122. package/dist/{resolveHTTPResponse-54a79e6c.mjs → resolveHTTPResponse-ccb9cfa1.mjs} +15 -9
  123. package/dist/rpc/envelopes.d.ts +1 -1
  124. package/dist/rpc/envelopes.d.ts.map +1 -1
  125. package/dist/rpc/index.js +1 -1
  126. package/dist/rpc/index.mjs +1 -1
  127. package/dist/rpc/internals/invert.d.ts +18 -0
  128. package/dist/rpc/internals/invert.d.ts.map +1 -0
  129. package/dist/{transformTRPCResponse-333bed6c.js → transformTRPCResponse-0c261655.js} +0 -27
  130. package/dist/{transformTRPCResponse-e0cba527.mjs → transformTRPCResponse-747b9a68.mjs} +1 -27
  131. package/dist/transformer.d.ts +14 -0
  132. package/dist/transformer.d.ts.map +1 -1
  133. package/dist/types.d.ts +9 -0
  134. package/dist/types.d.ts.map +1 -1
  135. package/package.json +11 -4
  136. package/src/TRPCError.ts +1 -1
  137. package/src/adapters/aws-lambda/index.ts +156 -0
  138. package/src/adapters/aws-lambda/utils.ts +91 -0
  139. package/src/adapters/express.ts +1 -1
  140. package/src/adapters/fastify/fastifyRequestHandler.ts +1 -1
  141. package/src/adapters/fastify/fastifyTRPCPlugin.ts +2 -2
  142. package/src/adapters/fetch/fetchRequestHandler.ts +1 -1
  143. package/src/adapters/fetch/types.ts +1 -1
  144. package/src/adapters/lambda/index.ts +18 -0
  145. package/src/adapters/next.ts +1 -1
  146. package/src/adapters/node-http/nodeHTTPRequestHandler.ts +3 -2
  147. package/src/adapters/node-http/types.ts +5 -3
  148. package/src/adapters/standalone.ts +1 -1
  149. package/src/adapters/ws.ts +5 -10
  150. package/src/core/index.ts +5 -0
  151. package/src/core/initTRPC.ts +90 -0
  152. package/src/core/internals/__generated__/mergeRoutersGeneric.ts +306 -0
  153. package/src/core/internals/config.ts +44 -0
  154. package/src/core/internals/getParseFn.ts +47 -0
  155. package/src/core/internals/internalProcedure.ts +265 -0
  156. package/src/core/internals/mergeRouters.ts +57 -0
  157. package/src/core/internals/mergeWithoutOverrides.ts +19 -0
  158. package/src/core/internals/omitPrototype.ts +9 -0
  159. package/src/core/internals/procedureBuilder.ts +100 -0
  160. package/src/core/internals/utils.ts +64 -0
  161. package/src/core/middleware.ts +93 -0
  162. package/src/core/parser.ts +45 -0
  163. package/src/core/procedure.ts +72 -0
  164. package/src/core/router.ts +313 -0
  165. package/src/core/types.ts +37 -0
  166. package/src/{internals → deprecated/internals}/callProcedure.ts +4 -1
  167. package/src/{internals → deprecated/internals}/middlewares.ts +17 -1
  168. package/src/{internals → deprecated/internals}/procedure.ts +19 -4
  169. package/src/deprecated/interop.ts +169 -0
  170. package/src/{router.ts → deprecated/router.ts} +49 -12
  171. package/src/error/TRPCError.ts +27 -0
  172. package/src/error/formatter.ts +51 -0
  173. package/src/error/utils.ts +49 -0
  174. package/src/http/index.ts +1 -1
  175. package/src/http/internals/types.ts +9 -11
  176. package/src/http/resolveHTTPResponse.ts +6 -11
  177. package/src/http/{responseMeta.ts → types.ts} +0 -0
  178. package/src/index.ts +2 -1
  179. package/src/internals/transformTRPCResponse.ts +1 -1
  180. package/src/internals/types.ts +24 -0
  181. package/src/rpc/codes.ts +1 -1
  182. package/src/rpc/envelopes.ts +1 -1
  183. package/src/rpc/internals/invert.ts +27 -0
  184. package/src/transformer.ts +28 -0
  185. package/src/types.ts +12 -0
  186. package/dist/http/responseMeta.d.ts.map +0 -1
  187. package/dist/internals/baseHandlerOptions.d.ts +0 -13
  188. package/dist/internals/baseHandlerOptions.d.ts.map +0 -1
  189. package/dist/internals/callProcedure.d.ts.map +0 -1
  190. package/dist/internals/middlewares.d.ts.map +0 -1
  191. package/dist/internals/onErrorFunction.d.ts +0 -11
  192. package/dist/internals/onErrorFunction.d.ts.map +0 -1
  193. package/dist/internals/procedure.d.ts.map +0 -1
  194. package/dist/router.d.ts.map +0 -1
  195. package/src/internals/baseHandlerOptions.ts +0 -13
  196. package/src/internals/onErrorFunction.ts +0 -11
@@ -0,0 +1,44 @@
1
+ import { DefaultErrorShape, ErrorFormatter } from '../../error/formatter';
2
+ import {
3
+ CombinedDataTransformer,
4
+ DataTransformerOptions,
5
+ } from '../../transformer';
6
+
7
+ /**
8
+ * The initial generics that are used in the init function
9
+ * @internal
10
+ */
11
+ export interface InitGenerics {
12
+ ctx: Record<string, unknown>;
13
+ meta: Record<string, unknown>;
14
+ }
15
+ /**
16
+ * The initial params that are used and actually represents real values underneath
17
+ * @internal
18
+ */
19
+ export interface InitOptions<T extends InitGenerics> {
20
+ transformer: DataTransformerOptions;
21
+ errorFormatter: ErrorFormatter<T['ctx'], any>;
22
+ }
23
+
24
+ /**
25
+ * @internal
26
+ */
27
+ export type CreateInitGenerics<T extends InitGenerics> = T;
28
+
29
+ /**
30
+ * The config that is resolved after both calls of `initTRPC()` has been called
31
+ * Combination of `InitTOptions` + `InitGenerics`
32
+ * @internal
33
+ */
34
+ export interface RootConfig {
35
+ ctx: Record<string, unknown>;
36
+ meta: Record<string, unknown>;
37
+ transformer: CombinedDataTransformer;
38
+ errorShape: DefaultErrorShape;
39
+ }
40
+
41
+ /**
42
+ * @internal
43
+ */
44
+ export type CreateRootConfig<T extends RootConfig> = T;
@@ -0,0 +1,47 @@
1
+ import { Parser } from '../parser';
2
+
3
+ export type ParseFn<T> = (value: unknown) => T | Promise<T>;
4
+
5
+ export function getParseFn<T>(procedureParser: Parser): ParseFn<T> {
6
+ const parser = procedureParser as any;
7
+
8
+ if (typeof parser === 'function') {
9
+ // ProcedureParserCustomValidatorEsque
10
+ return parser;
11
+ }
12
+
13
+ if (typeof parser.parseAsync === 'function') {
14
+ // ProcedureParserZodEsque
15
+ return parser.parseAsync.bind(parser);
16
+ }
17
+
18
+ if (typeof parser.parse === 'function') {
19
+ // ProcedureParserZodEsque
20
+ return parser.parse.bind(parser);
21
+ }
22
+
23
+ if (typeof parser.validateSync === 'function') {
24
+ // ProcedureParserYupEsque
25
+ return parser.validateSync.bind(parser);
26
+ }
27
+
28
+ if (typeof parser.create === 'function') {
29
+ // ProcedureParserSuperstructEsque
30
+ return parser.create.bind(parser);
31
+ }
32
+
33
+ throw new Error('Could not find a validator fn');
34
+ }
35
+
36
+ /**
37
+ * @deprecated only for backwards compat
38
+ * @internal
39
+ */
40
+ export function getParseFnOrPassThrough<T>(
41
+ procedureParser: Parser | undefined,
42
+ ): ParseFn<T> {
43
+ if (!procedureParser) {
44
+ return (v) => v as T;
45
+ }
46
+ return getParseFn(procedureParser);
47
+ }
@@ -0,0 +1,265 @@
1
+ /**
2
+ * This is the actual internal representation of a builder
3
+ * FIXME - I want to get rid of this and use the public API instead
4
+ */
5
+ import { TRPCError } from '../../TRPCError';
6
+ import { getCauseFromUnknown } from '../../error/utils';
7
+ import { getErrorFromUnknown } from '../../internals/errors';
8
+ import { MaybePromise } from '../../types';
9
+ import { MiddlewareFunction, MiddlewareResult } from '../middleware';
10
+ import { Parser } from '../parser';
11
+ import { ProcedureType } from '../types';
12
+ import { ParseFn, getParseFn } from './getParseFn';
13
+ import { mergeWithoutOverrides } from './mergeWithoutOverrides';
14
+ import { ResolveOptions, middlewareMarker } from './utils';
15
+
16
+ export interface InternalProcedureCallOptions {
17
+ ctx: unknown;
18
+ rawInput: unknown;
19
+ input?: unknown;
20
+ path: string;
21
+ type: ProcedureType;
22
+ }
23
+ export interface InternalProcedure {
24
+ _def: ProcedureBuilderInternal['_def'];
25
+ /**
26
+ * @deprecated use `._def.meta` instead
27
+ */
28
+ meta: ProcedureBuilderInternal['_def']['meta'];
29
+ (opts: InternalProcedureCallOptions): Promise<unknown>;
30
+ }
31
+
32
+ type ProcedureBuilderInternalResolver = (
33
+ opts: ResolveOptions<any>,
34
+ ) => Promise<unknown>;
35
+
36
+ export type ProcedureBuilderInternalMiddleware = MiddlewareFunction<any, any>;
37
+ interface ProcedureBuilderInternal {
38
+ _def: {
39
+ input?: Parser;
40
+ output?: Parser;
41
+ meta?: Record<string, unknown>;
42
+ resolver?: ProcedureBuilderInternalResolver;
43
+ middlewares: ProcedureBuilderInternalMiddleware[];
44
+ };
45
+ // FIXME
46
+ // _call: (opts: ResolveOptions<any>) => Promise<unknown>;
47
+ /**
48
+ * @internal
49
+ */
50
+ input: (parser: Parser) => ProcedureBuilderInternal;
51
+ /**
52
+ * @internal
53
+ */
54
+ output: (parser: Parser) => ProcedureBuilderInternal;
55
+ /**
56
+ * @internal
57
+ */
58
+ concat: (proc: ProcedureBuilderInternal) => ProcedureBuilderInternal;
59
+ /**
60
+ * @internal
61
+ */
62
+ use: (fn: MiddlewareFunction<any, any>) => ProcedureBuilderInternal;
63
+ /**
64
+ * @internal
65
+ */
66
+ meta: (meta: Record<string, unknown>) => ProcedureBuilderInternal;
67
+ /**
68
+ * @internal
69
+ */
70
+ resolve: (
71
+ resolver: (opts: ResolveOptions<any>) => MaybePromise<any>,
72
+ ) => InternalProcedure;
73
+ }
74
+ function createNewInternalBuilder(
75
+ def1: ProcedureBuilderInternal['_def'],
76
+ def2: Partial<ProcedureBuilderInternal['_def']>,
77
+ ): ProcedureBuilderInternal {
78
+ const { middlewares = [], ...rest } = def2;
79
+
80
+ // TODO: maybe have a fn here to warn about calls
81
+ return createInternalBuilder({
82
+ ...mergeWithoutOverrides(def1, rest),
83
+ middlewares: [...def1.middlewares, ...middlewares],
84
+ });
85
+ }
86
+
87
+ const codeblock = `
88
+ If you want to call this function on the server, you do the following:
89
+ This is a client-only function.
90
+
91
+ const caller = appRouter.createCaller({
92
+ /* ... your context */
93
+ });
94
+
95
+ const result = await caller.call('myProcedure', input);
96
+ `.trim();
97
+
98
+ function createProcedureCaller(
99
+ _def: InternalProcedure['_def'],
100
+ ): InternalProcedure {
101
+ const procedure = async function resolve(opts: InternalProcedureCallOptions) {
102
+ if (!opts || !('rawInput' in opts)) {
103
+ throw new Error(codeblock);
104
+ }
105
+
106
+ // run the middlewares recursively with the resolver as the last one
107
+ const callRecursive = async (
108
+ callOpts: { ctx: any; index: number; input?: unknown } = {
109
+ index: 0,
110
+ ctx: opts.ctx,
111
+ },
112
+ ): Promise<MiddlewareResult<any>> => {
113
+ try {
114
+ const middleware = _def.middlewares[callOpts.index];
115
+ const result = await middleware({
116
+ ctx: callOpts.ctx,
117
+ type: opts.type,
118
+ path: opts.path,
119
+ rawInput: opts.rawInput,
120
+ meta: _def.meta,
121
+ input: callOpts.input,
122
+ next: async (nextOpts?: { ctx: any; input?: any }) => {
123
+ return await callRecursive({
124
+ index: callOpts.index + 1,
125
+ ctx:
126
+ nextOpts && 'ctx' in nextOpts
127
+ ? { ...callOpts.ctx, ...nextOpts.ctx }
128
+ : callOpts.ctx,
129
+ input:
130
+ nextOpts && 'input' in nextOpts
131
+ ? nextOpts.input
132
+ : callOpts.input,
133
+ });
134
+ },
135
+ });
136
+ return result;
137
+ } catch (cause) {
138
+ return {
139
+ ok: false,
140
+ error: getErrorFromUnknown(cause),
141
+ marker: middlewareMarker,
142
+ };
143
+ }
144
+ };
145
+
146
+ // there's always at least one "next" since we wrap this.resolver in a middleware
147
+ const result = await callRecursive();
148
+
149
+ if (!result) {
150
+ throw new TRPCError({
151
+ code: 'INTERNAL_SERVER_ERROR',
152
+ message:
153
+ 'No result from middlewares - did you forget to `return next()`?',
154
+ });
155
+ }
156
+ if (!result.ok) {
157
+ // re-throw original error
158
+ throw result.error;
159
+ }
160
+ return result.data;
161
+ };
162
+ procedure._def = _def;
163
+ procedure.meta = _def.meta;
164
+
165
+ return procedure;
166
+ }
167
+
168
+ export function createInputMiddleware<T>(
169
+ parse: ParseFn<T>,
170
+ ): ProcedureBuilderInternalMiddleware {
171
+ return async function inputMiddleware({ next, rawInput }) {
172
+ let input: ReturnType<typeof parse>;
173
+ try {
174
+ input = await parse(rawInput);
175
+ } catch (cause) {
176
+ throw new TRPCError({
177
+ code: 'BAD_REQUEST',
178
+ cause: getCauseFromUnknown(cause),
179
+ });
180
+ }
181
+ // TODO fix this typing?
182
+ return next({ input } as any);
183
+ };
184
+ }
185
+
186
+ export function createOutputMiddleware<T>(
187
+ parse: ParseFn<T>,
188
+ ): ProcedureBuilderInternalMiddleware {
189
+ return async function outputMiddleware({ next }) {
190
+ const result = await next();
191
+ if (!result.ok) {
192
+ // pass through failures without validating
193
+ return result;
194
+ }
195
+ try {
196
+ const data = await parse(result.data);
197
+ return {
198
+ ...result,
199
+ data,
200
+ };
201
+ } catch (cause) {
202
+ throw new TRPCError({
203
+ message: 'Output validation failed',
204
+ code: 'INTERNAL_SERVER_ERROR',
205
+ cause: getCauseFromUnknown(cause),
206
+ });
207
+ }
208
+ };
209
+ }
210
+
211
+ export function createInternalBuilder(
212
+ initDef?: ProcedureBuilderInternal['_def'],
213
+ ): ProcedureBuilderInternal {
214
+ const _def: ProcedureBuilderInternal['_def'] = initDef || {
215
+ middlewares: [],
216
+ };
217
+
218
+ return {
219
+ _def,
220
+ // _call: createProcedureCaller(_def),
221
+ input(input: Parser) {
222
+ const parser = getParseFn(input);
223
+ return createNewInternalBuilder(_def, {
224
+ input,
225
+ middlewares: [createInputMiddleware(parser)],
226
+ });
227
+ },
228
+ output(output: Parser) {
229
+ const parseOutput = getParseFn(output);
230
+ return createNewInternalBuilder(_def, {
231
+ output,
232
+ middlewares: [createOutputMiddleware(parseOutput)],
233
+ });
234
+ },
235
+ meta(meta) {
236
+ return createNewInternalBuilder(_def, { meta });
237
+ },
238
+ resolve(resolver) {
239
+ const finalBuilder = createNewInternalBuilder(_def, {
240
+ resolver,
241
+ middlewares: [
242
+ async function resolveMiddleware(opts) {
243
+ const data = await resolver(opts);
244
+ return {
245
+ marker: middlewareMarker,
246
+ ok: true,
247
+ data,
248
+ ctx: opts.ctx,
249
+ } as const;
250
+ },
251
+ ],
252
+ });
253
+
254
+ return createProcedureCaller(finalBuilder._def);
255
+ },
256
+ concat(builder) {
257
+ return createNewInternalBuilder(_def, builder._def);
258
+ },
259
+ use(middleware) {
260
+ return createNewInternalBuilder(_def, {
261
+ middlewares: [middleware],
262
+ });
263
+ },
264
+ };
265
+ }
@@ -0,0 +1,57 @@
1
+ import { defaultFormatter } from '../../error/formatter';
2
+ import { CombinedDataTransformer, defaultTransformer } from '../../transformer';
3
+ import { AnyRouter, createRouterFactory } from '../router';
4
+ import { mergeWithoutOverrides } from './mergeWithoutOverrides';
5
+
6
+ export function mergeRouters(...routerList: AnyRouter[]): AnyRouter {
7
+ const queries = mergeWithoutOverrides(
8
+ {},
9
+ ...routerList.map((r) => r.queries),
10
+ );
11
+ const mutations = mergeWithoutOverrides(
12
+ {},
13
+ ...routerList.map((r) => r.mutations),
14
+ );
15
+ const subscriptions = mergeWithoutOverrides(
16
+ {},
17
+ ...routerList.map((r) => r.subscriptions),
18
+ );
19
+ const errorFormatter = routerList.reduce(
20
+ (currentErrorFormatter, nextRouter) => {
21
+ if (
22
+ nextRouter.errorFormatter &&
23
+ nextRouter.errorFormatter !== defaultFormatter
24
+ ) {
25
+ if (
26
+ currentErrorFormatter !== defaultFormatter &&
27
+ currentErrorFormatter !== nextRouter.errorFormatter
28
+ ) {
29
+ throw new Error('You seem to have several error formatters');
30
+ }
31
+ return nextRouter.errorFormatter;
32
+ }
33
+ return currentErrorFormatter;
34
+ },
35
+ defaultFormatter,
36
+ );
37
+
38
+ const transformer = routerList.reduce((prev, current) => {
39
+ if (current.transformer && current.transformer !== defaultTransformer) {
40
+ if (prev !== defaultTransformer && prev !== current.transformer) {
41
+ throw new Error('You seem to have several transformers');
42
+ }
43
+ return current.transformer;
44
+ }
45
+ return prev;
46
+ }, defaultTransformer as CombinedDataTransformer);
47
+
48
+ const router = createRouterFactory({
49
+ errorFormatter,
50
+ transformer,
51
+ })({
52
+ queries,
53
+ mutations,
54
+ subscriptions,
55
+ });
56
+ return router;
57
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Ensures there are no duplicate keys when building a procedure.
3
+ */
4
+ export function mergeWithoutOverrides<T extends Record<string, unknown>>(
5
+ obj1: T,
6
+ ...objs: Partial<T>[]
7
+ ): T {
8
+ const newObj: T = Object.assign(Object.create(null), obj1);
9
+
10
+ for (const overrides of objs) {
11
+ for (const key in overrides) {
12
+ if (key in newObj && newObj[key] !== overrides[key]) {
13
+ throw new Error(`Duplicate key ${key}`);
14
+ }
15
+ newObj[key as keyof T] = overrides[key] as T[keyof T];
16
+ }
17
+ }
18
+ return newObj;
19
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Create an object without inheriting anything from `Object.prototype`
3
+ * @internal
4
+ */
5
+ export function omitPrototype<TObj1 extends Record<string, unknown>>(
6
+ obj1: TObj1,
7
+ ): TObj1 {
8
+ return Object.assign(Object.create(null), obj1);
9
+ }
@@ -0,0 +1,100 @@
1
+ import { MaybePromise } from '../../types';
2
+ import { MiddlewareFunction } from '../middleware';
3
+ import { Parser, inferParser } from '../parser';
4
+ import { Procedure, ProcedureParams } from '../procedure';
5
+ import { createInternalBuilder } from './internalProcedure';
6
+ import { ResolveOptions } from './utils';
7
+ import { DefaultValue as FallbackValue, Overwrite, UnsetMarker } from './utils';
8
+
9
+ type CreateProcedureReturnInput<
10
+ TPrev extends ProcedureParams,
11
+ TNext extends ProcedureParams,
12
+ > = ProcedureBuilder<{
13
+ _meta: TPrev['_meta'];
14
+ _ctx_in: TPrev['_ctx_in'];
15
+ _ctx_out: Overwrite<TPrev['_ctx_out'], TNext['_ctx_out']>;
16
+ _input_out: FallbackValue<TNext['_input_out'], TPrev['_input_out']>;
17
+ _input_in: FallbackValue<TNext['_input_in'], TPrev['_input_in']>;
18
+ _output_in: FallbackValue<TNext['_output_in'], TPrev['_output_in']>;
19
+ _output_out: FallbackValue<TNext['_output_out'], TPrev['_output_out']>;
20
+ }>;
21
+
22
+ export interface ProcedureBuilder<TParams extends ProcedureParams> {
23
+ /**
24
+ * Add an input parser to the procedure.
25
+ */
26
+ input<$TParser extends Parser>(
27
+ schema: $TParser,
28
+ ): ProcedureBuilder<{
29
+ _meta: TParams['_meta'];
30
+ _ctx_in: TParams['_ctx_in'];
31
+ _ctx_out: TParams['_ctx_out'];
32
+ _output_in: TParams['_output_in'];
33
+ _output_out: TParams['_output_out'];
34
+ _input_in: inferParser<$TParser>['in'];
35
+ _input_out: inferParser<$TParser>['out'];
36
+ }>;
37
+ /**
38
+ * Add an output parser to the procedure.
39
+ */
40
+ output<$TParser extends Parser>(
41
+ schema: $TParser,
42
+ ): ProcedureBuilder<{
43
+ _meta: TParams['_meta'];
44
+ _ctx_in: TParams['_ctx_in'];
45
+ _ctx_out: TParams['_ctx_out'];
46
+ _input_in: TParams['_input_in'];
47
+ _input_out: TParams['_input_out'];
48
+ _output_in: inferParser<$TParser>['in'];
49
+ _output_out: inferParser<$TParser>['out'];
50
+ }>;
51
+ /**
52
+ * Add a meta data to the procedure.
53
+ */
54
+ meta(meta: TParams['_meta']): ProcedureBuilder<TParams>;
55
+ /**
56
+ * Add a middleware to the procedure.
57
+ */
58
+ use<$TParams extends ProcedureParams>(
59
+ fn: MiddlewareFunction<TParams, $TParams>,
60
+ ): CreateProcedureReturnInput<TParams, $TParams>;
61
+ /**
62
+ * Extend the procedure with another procedure
63
+ */
64
+ concat<$ProcedureReturnInput extends ProcedureBuilder<any>>(
65
+ proc: $ProcedureReturnInput,
66
+ ): $ProcedureReturnInput extends ProcedureBuilder<infer $TParams>
67
+ ? CreateProcedureReturnInput<TParams, $TParams>
68
+ : never;
69
+ /**
70
+ * Resolve the procedure
71
+ */
72
+ resolve<$TOutput>(
73
+ resolver: (
74
+ opts: ResolveOptions<TParams>,
75
+ ) => MaybePromise<FallbackValue<TParams['_output_in'], $TOutput>>,
76
+ ): UnsetMarker extends TParams['_output_out']
77
+ ? Procedure<
78
+ Overwrite<
79
+ TParams,
80
+ {
81
+ _output_in: $TOutput;
82
+ _output_out: $TOutput;
83
+ }
84
+ >
85
+ >
86
+ : Procedure<TParams>;
87
+ }
88
+
89
+ // TODO make this into a callbag?
90
+ export function createBuilder<TContext, TMeta>(): ProcedureBuilder<{
91
+ _ctx_in: TContext;
92
+ _ctx_out: TContext;
93
+ _input_out: UnsetMarker;
94
+ _input_in: UnsetMarker;
95
+ _output_in: UnsetMarker;
96
+ _output_out: UnsetMarker;
97
+ _meta: TMeta;
98
+ }> {
99
+ return createInternalBuilder() as any;
100
+ }
@@ -0,0 +1,64 @@
1
+ import { ProcedureParams } from '../procedure';
2
+
3
+ /**
4
+ * @internal
5
+ */
6
+ export type Overwrite<T, U> = Omit<T, keyof U> & U;
7
+ /**
8
+ * @internal
9
+ */
10
+ export type DefaultValue<TValue, TFallback> = UnsetMarker extends TValue
11
+ ? TFallback
12
+ : TValue;
13
+
14
+ /**
15
+ * @internal
16
+ */
17
+ export const middlewareMarker = 'middlewareMarker' as 'middlewareMarker' & {
18
+ __brand: 'middlewareMarker';
19
+ };
20
+
21
+ /**
22
+ * @internal
23
+ */
24
+ export type MiddlewareMarker = typeof middlewareMarker;
25
+
26
+ /**
27
+ * @internal
28
+ */
29
+ export const unsetMarker = Symbol('unsetMarker');
30
+ /**
31
+ * @internal
32
+ */
33
+ export type UnsetMarker = typeof unsetMarker;
34
+
35
+ /**
36
+ * @internal
37
+ */
38
+ export interface ResolveOptions<TParams extends ProcedureParams> {
39
+ ctx: TParams['_ctx_out'];
40
+ input: TParams['_input_out'];
41
+ }
42
+
43
+ /**
44
+ * @internal
45
+ */
46
+ export type ValidateShape<TActualShape, TExpectedShape> =
47
+ TActualShape extends TExpectedShape
48
+ ? Exclude<keyof TActualShape, keyof TExpectedShape> extends never
49
+ ? TActualShape
50
+ : TExpectedShape
51
+ : never;
52
+
53
+ /**
54
+ * @internal
55
+ */
56
+ export type PickFirstDefined<T, K> = undefined extends T
57
+ ? undefined extends K
58
+ ? never
59
+ : K
60
+ : T;
61
+
62
+ export type EnsureRecord<T> = T extends Record<string, any>
63
+ ? T
64
+ : Record<string, never>;
@@ -0,0 +1,93 @@
1
+ import { MiddlewareMarker } from './internals/utils';
2
+ import { ProcedureParams } from './procedure';
3
+ import { ProcedureType } from './types';
4
+
5
+ /**
6
+ * @internal
7
+ */
8
+ interface MiddlewareResultBase {
9
+ /**
10
+ * All middlewares should pass through their `next()`'s output.
11
+ * Requiring this marker makes sure that can't be forgotten at compile-time.
12
+ */
13
+ readonly marker: MiddlewareMarker;
14
+ }
15
+
16
+ /**
17
+ * @internal
18
+ */
19
+ interface MiddlewareOKResult<_TParams extends ProcedureParams>
20
+ extends MiddlewareResultBase {
21
+ ok: true;
22
+ data: unknown;
23
+ // this could be extended with `input`/`rawInput` later
24
+ }
25
+
26
+ /**
27
+ * @internal
28
+ */
29
+ interface MiddlewareErrorResult<_TParams extends ProcedureParams>
30
+ extends MiddlewareResultBase {
31
+ ok: false;
32
+ error: Error;
33
+ // we could guarantee it's always of this type
34
+ }
35
+
36
+ /**
37
+ * @internal
38
+ */
39
+ export type MiddlewareResult<TParams extends ProcedureParams> =
40
+ | MiddlewareOKResult<TParams>
41
+ | MiddlewareErrorResult<TParams>;
42
+
43
+ /**
44
+ * @internal
45
+ */
46
+ export type MiddlewareFunction<
47
+ TParams extends ProcedureParams,
48
+ TParamsAfter extends ProcedureParams,
49
+ > = (opts: {
50
+ ctx: TParams['_ctx_out'];
51
+ type: ProcedureType;
52
+ path: string;
53
+ input: TParams['_input_out'];
54
+ rawInput: unknown;
55
+ meta: TParams['_meta'];
56
+ next: {
57
+ (): Promise<MiddlewareResult<TParams>>;
58
+ <$TContext>(opts: { ctx: $TContext }): Promise<
59
+ MiddlewareResult<{
60
+ _ctx_in: TParams['_ctx_in'];
61
+ _ctx_out: $TContext;
62
+ _input_in: TParams['_input_in'];
63
+ _input_out: TParams['_input_out'];
64
+ _output_in: TParams['_output_in'];
65
+ _output_out: TParams['_output_out'];
66
+ _meta: TParams['_meta'];
67
+ }>
68
+ >;
69
+ };
70
+ }) => Promise<MiddlewareResult<TParamsAfter>>;
71
+
72
+ /**
73
+ * @internal
74
+ */
75
+ // FIXME this should use RootConfig
76
+ export function createMiddlewareFactory<TContext, TMeta>() {
77
+ return function createMiddleware<$TNewParams extends ProcedureParams>(
78
+ fn: MiddlewareFunction<
79
+ {
80
+ _ctx_in: TContext;
81
+ _ctx_out: TContext;
82
+ _input_out: unknown;
83
+ _input_in: unknown;
84
+ _output_in: unknown;
85
+ _output_out: unknown;
86
+ _meta: TMeta;
87
+ },
88
+ $TNewParams
89
+ >,
90
+ ) {
91
+ return fn;
92
+ };
93
+ }