From 24c1a96e49aebfef40b5e0ab86cacb11dcec6081 Mon Sep 17 00:00:00 2001 From: KATT Date: Thu, 29 Jul 2021 01:56:19 +0200 Subject: [PATCH 01/12] remove deprecated httpErrors --- packages/server/src/http/errors.ts | 28 ---------------------------- packages/server/src/http/index.ts | 1 - 2 files changed, 29 deletions(-) delete mode 100644 packages/server/src/http/errors.ts diff --git a/packages/server/src/http/errors.ts b/packages/server/src/http/errors.ts deleted file mode 100644 index 4581c6dd259..00000000000 --- a/packages/server/src/http/errors.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { TRPCError } from '../TRPCError'; - -/* istanbul ignore next */ -/** - * @deprecated - */ -export const httpError = { - /** - * @deprecated use `new TRPCError({ code: 'FORBIDDEN', message: '... })` - */ - forbidden: (message?: string) => - new TRPCError({ message, code: 'FORBIDDEN' }), - /** - * @deprecated use `new TRPCError({ code: 'UNAUTHORIZED', message: '... })` - */ - unauthorized: (message?: string) => - new TRPCError({ message, code: 'UNAUTHORIZED' }), - /** - * @deprecated use `new TRPCError({ code: 'BAD_REQUEST', message: '... })` - */ - badRequest: (message?: string) => - new TRPCError({ message, code: 'BAD_REQUEST' }), - /** - * @deprecated use `new TRPCError({ code: 'METHOD_NOT_FOUND', message: '... })` - */ - notFound: (message?: string) => - new TRPCError({ message, code: 'PATH_NOT_FOUND' }), -}; diff --git a/packages/server/src/http/index.ts b/packages/server/src/http/index.ts index 8d0e6e16bd0..e424f9cad79 100644 --- a/packages/server/src/http/index.ts +++ b/packages/server/src/http/index.ts @@ -1,6 +1,5 @@ /* eslint-disable @typescript-eslint/no-non-null-assertion */ /* eslint-disable @typescript-eslint/no-explicit-any */ import { assertNotBrowser } from '../assertNotBrowser'; -export * from './errors'; export * from './requestHandler'; assertNotBrowser(); From 85bcf60913401165c9065e911f547b8b62a420db Mon Sep 17 00:00:00 2001 From: KATT Date: Thu, 29 Jul 2021 01:58:40 +0200 Subject: [PATCH 02/12] remove deprecated stuff --- packages/server/src/http/requestHandler.ts | 21 +------ packages/server/test/rawFetch.test.tsx | 69 ---------------------- 2 files changed, 2 insertions(+), 88 deletions(-) diff --git a/packages/server/src/http/requestHandler.ts b/packages/server/src/http/requestHandler.ts index 712cc4cf9f8..4a5382e4a9a 100644 --- a/packages/server/src/http/requestHandler.ts +++ b/packages/server/src/http/requestHandler.ts @@ -55,18 +55,6 @@ async function getRequestParams({ } const body = await getPostBody({ req, maxBodySize }); - /** - * @deprecated TODO delete me for next major - * */ - if ( - body && - typeof body === 'object' && - 'input' in body && - Object.keys(body).length === 1 - ) { - // legacy format - return { input: body.input }; - } return { input: body }; } @@ -135,15 +123,10 @@ export async function requestHandler< return [input]; } - // TODO - next major, delete `Array.isArray()` - if ( - !Array.isArray(input) && - (typeof input !== 'object' || input == null) - ) { + if (input == null || typeof input !== 'object' || Array.isArray(input)) { throw new TRPCError({ code: 'BAD_REQUEST', - message: - '"input" needs to be an array or object when doing a batch call', + message: '"input" needs to be an object when doing a batch call', }); } return input as any; diff --git a/packages/server/test/rawFetch.test.tsx b/packages/server/test/rawFetch.test.tsx index c53c5a334e0..93f1f20eb1c 100644 --- a/packages/server/test/rawFetch.test.tsx +++ b/packages/server/test/rawFetch.test.tsx @@ -30,78 +30,9 @@ const factory = () => }), ); -/** - * @deprecated TODO delete in next major - **/ -test('call mutation with `input`-prop', async () => { - const { close, httpUrl } = factory(); - - const res = await fetch(`${httpUrl}/myMutation`, { - method: 'POST', - body: JSON.stringify({ - input: { - name: 'alexdotjs', - }, - }), - }); - const json = await res.json(); - - expect(json).toHaveProperty('result'); - expect(json.result).toMatchInlineSnapshot(` -Object { - "data": Object { - "input": Object { - "name": "alexdotjs", - }, - }, - "type": "data", -} -`); - - close(); -}); - test('batching with raw batch', async () => { const { close, httpUrl } = factory(); - { - /** - * @deprecated TODO delete in next major - **/ - const res = await fetch( - `${httpUrl}/myQuery?batch=1&input=${JSON.stringify([])}`, - ); - const json = await res.json(); - - expect(json[0]).toHaveProperty('result'); - expect(json[0].result).toMatchInlineSnapshot(` -Object { - "data": "default", - "type": "data", -} -`); - } - - { - /** - * @deprecated TODO - remove in next major - **/ - const res = await fetch( - `${httpUrl}/myQuery?batch=1&input=${JSON.stringify([ - { name: 'alexdotjs' }, - ])}`, - ); - const json = await res.json(); - - expect(json[0]).toHaveProperty('result'); - expect(json[0].result).toMatchInlineSnapshot(` -Object { - "data": "alexdotjs", - "type": "data", -} -`); - } - { const res = await fetch( `${httpUrl}/myQuery?batch=1&input=${JSON.stringify({ From b8c66686d2764010eb597735a0c5b6069d8f1efc Mon Sep 17 00:00:00 2001 From: KATT Date: Thu, 29 Jul 2021 10:19:23 +0200 Subject: [PATCH 03/12] wip --- packages/server/test/errors.test.ts | 2 +- packages/server/test/index.test.tsx | 4 ++-- packages/server/test/middleware.test.ts | 8 ++++---- www/docs/server/authorization.md | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/server/test/errors.test.ts b/packages/server/test/errors.test.ts index aee2ec4d05a..06b0f3a11cf 100644 --- a/packages/server/test/errors.test.ts +++ b/packages/server/test/errors.test.ts @@ -108,7 +108,7 @@ test('input error', async () => { close(); }); -test('httpError.unauthorized()', async () => { +test('unauthorized()', async () => { const onError = jest.fn(); const { client, close } = routerToServerAndClient( trpc.router().query('err', { diff --git a/packages/server/test/index.test.tsx b/packages/server/test/index.test.tsx index c95b70411c8..8b99ce0549f 100644 --- a/packages/server/test/index.test.tsx +++ b/packages/server/test/index.test.tsx @@ -7,7 +7,7 @@ import { createWSClient, wsLink } from '../../client/src/links/wsLink'; import { z } from 'zod'; import { TRPCClientError } from '../../client/src'; import * as trpc from '../src'; -import { CreateHttpContextOptions, Maybe } from '../src'; +import { CreateHttpContextOptions, Maybe, TRPCError } from '../src'; import { routerToServerAndClient } from './_testHelpers'; import WebSocket from 'ws'; import { waitFor } from '@testing-library/react'; @@ -270,7 +270,7 @@ describe('integration tests', () => { trpc.router().query('whoami', { async resolve({ ctx }) { if (!ctx.user) { - throw trpc.httpError.unauthorized(); + throw new TRPCError{ code: 'UNAUTHORIZED' }); } return ctx.user; }, diff --git a/packages/server/test/middleware.test.ts b/packages/server/test/middleware.test.ts index 686247d353c..ab6bf7d14f5 100644 --- a/packages/server/test/middleware.test.ts +++ b/packages/server/test/middleware.test.ts @@ -1,6 +1,6 @@ import { routerToServerAndClient } from './_testHelpers'; import * as trpc from '../src'; -import { httpError } from '../src'; +import { httpError, TRPCError } from '../src'; test('is called if def first', async () => { const middleware = jest.fn(); @@ -76,7 +76,7 @@ test('allows you to throw an error (e.g. auth)', async () => { .router() .middleware(({ ctx }) => { if (!ctx.user?.isAdmin) { - throw httpError.unauthorized(); + throw new TRPCError({ code: 'UNAUTHORIZED' }); } }) .query('secretPlace', { @@ -197,7 +197,7 @@ test('equiv', () => { .router() .middleware(({ ctx }) => { if (!ctx.user?.isAdmin) { - throw httpError.unauthorized(); + throw new TRPCError({ code: 'UNAUTHORIZED' }); } }) .query('secretPlace', { @@ -219,7 +219,7 @@ test('equiv', () => { .router() .middleware(({ ctx }) => { if (!ctx.user?.isAdmin) { - throw httpError.unauthorized(); + throw new TRPCError({ code: 'UNAUTHORIZED' }); } }) .query('admin.secretPlace', { diff --git a/www/docs/server/authorization.md b/www/docs/server/authorization.md index e7fb2b5a843..43bfb83df65 100644 --- a/www/docs/server/authorization.md +++ b/www/docs/server/authorization.md @@ -90,7 +90,7 @@ export const appRouter = createRouter() // this protectes all procedures defined after in this router .middleware(async ({ ctx }) => { if (!ctx.user?.isAdmin) { - throw httpError.unauthorized(); + throw new TRPCError({code: 'UNAUTHORIZED'}); } }) .query('secret', { From 7198eab47b4c847b793fa00a6bc56a897d409c73 Mon Sep 17 00:00:00 2001 From: KATT Date: Fri, 13 Aug 2021 15:21:49 +0200 Subject: [PATCH 04/12] remove httpError --- packages/server/src/http/errors.ts | 28 ------------------------- packages/server/test/index.test.tsx | 4 ++-- packages/server/test/middleware.test.ts | 10 ++++----- packages/server/test/react.test.tsx | 3 ++- www/docs/server/authorization.md | 3 ++- 5 files changed, 11 insertions(+), 37 deletions(-) delete mode 100644 packages/server/src/http/errors.ts diff --git a/packages/server/src/http/errors.ts b/packages/server/src/http/errors.ts deleted file mode 100644 index 4581c6dd259..00000000000 --- a/packages/server/src/http/errors.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { TRPCError } from '../TRPCError'; - -/* istanbul ignore next */ -/** - * @deprecated - */ -export const httpError = { - /** - * @deprecated use `new TRPCError({ code: 'FORBIDDEN', message: '... })` - */ - forbidden: (message?: string) => - new TRPCError({ message, code: 'FORBIDDEN' }), - /** - * @deprecated use `new TRPCError({ code: 'UNAUTHORIZED', message: '... })` - */ - unauthorized: (message?: string) => - new TRPCError({ message, code: 'UNAUTHORIZED' }), - /** - * @deprecated use `new TRPCError({ code: 'BAD_REQUEST', message: '... })` - */ - badRequest: (message?: string) => - new TRPCError({ message, code: 'BAD_REQUEST' }), - /** - * @deprecated use `new TRPCError({ code: 'METHOD_NOT_FOUND', message: '... })` - */ - notFound: (message?: string) => - new TRPCError({ message, code: 'PATH_NOT_FOUND' }), -}; diff --git a/packages/server/test/index.test.tsx b/packages/server/test/index.test.tsx index c95b70411c8..41be84a7d67 100644 --- a/packages/server/test/index.test.tsx +++ b/packages/server/test/index.test.tsx @@ -7,7 +7,7 @@ import { createWSClient, wsLink } from '../../client/src/links/wsLink'; import { z } from 'zod'; import { TRPCClientError } from '../../client/src'; import * as trpc from '../src'; -import { CreateHttpContextOptions, Maybe } from '../src'; +import { CreateHttpContextOptions, Maybe, TRPCError } from '../src'; import { routerToServerAndClient } from './_testHelpers'; import WebSocket from 'ws'; import { waitFor } from '@testing-library/react'; @@ -270,7 +270,7 @@ describe('integration tests', () => { trpc.router().query('whoami', { async resolve({ ctx }) { if (!ctx.user) { - throw trpc.httpError.unauthorized(); + throw new TRPCError({ code: 'UNAUTHORIZED' }); } return ctx.user; }, diff --git a/packages/server/test/middleware.test.ts b/packages/server/test/middleware.test.ts index 686247d353c..7bd21e8061e 100644 --- a/packages/server/test/middleware.test.ts +++ b/packages/server/test/middleware.test.ts @@ -1,6 +1,6 @@ -import { routerToServerAndClient } from './_testHelpers'; import * as trpc from '../src'; -import { httpError } from '../src'; +import { TRPCError } from '../src'; +import { routerToServerAndClient } from './_testHelpers'; test('is called if def first', async () => { const middleware = jest.fn(); @@ -76,7 +76,7 @@ test('allows you to throw an error (e.g. auth)', async () => { .router() .middleware(({ ctx }) => { if (!ctx.user?.isAdmin) { - throw httpError.unauthorized(); + throw new TRPCError({ code: 'UNAUTHORIZED' }); } }) .query('secretPlace', { @@ -197,7 +197,7 @@ test('equiv', () => { .router() .middleware(({ ctx }) => { if (!ctx.user?.isAdmin) { - throw httpError.unauthorized(); + throw new TRPCError({ code: 'UNAUTHORIZED' }); } }) .query('secretPlace', { @@ -219,7 +219,7 @@ test('equiv', () => { .router() .middleware(({ ctx }) => { if (!ctx.user?.isAdmin) { - throw httpError.unauthorized(); + throw new TRPCError({ code: 'UNAUTHORIZED' }); } }) .query('admin.secretPlace', { diff --git a/packages/server/test/react.test.tsx b/packages/server/test/react.test.tsx index 3393892ac6b..e130fcb6594 100644 --- a/packages/server/test/react.test.tsx +++ b/packages/server/test/react.test.tsx @@ -40,6 +40,7 @@ import { TRPCWebSocketClient, } from '../../client/src/links/wsLink'; import { splitLink } from '../../client/src/links/splitLink'; +import { TRPCError } from '../dist/declarations/src/TRPCError'; setLogger({ log() {}, @@ -92,7 +93,7 @@ function createAppRouter() { postById(input); const post = db.posts.find((p) => p.id === input); if (!post) { - throw trpcServer.httpError.notFound(); + throw new TRPCError({ code: 'PATH_NOT_FOUND' }); } return post; }, diff --git a/www/docs/server/authorization.md b/www/docs/server/authorization.md index e7fb2b5a843..f4ce14d6ac5 100644 --- a/www/docs/server/authorization.md +++ b/www/docs/server/authorization.md @@ -74,6 +74,7 @@ export const appRouter = createRouter() ```ts import * as trpc from '@trpc/server'; +import { TRPCError } from '@trpc/server'; import { createRouter } from './[trpc]'; export const appRouter = createRouter() @@ -90,7 +91,7 @@ export const appRouter = createRouter() // this protectes all procedures defined after in this router .middleware(async ({ ctx }) => { if (!ctx.user?.isAdmin) { - throw httpError.unauthorized(); + throw new TRPCError({ code: 'UNAUTHORIZED' }); } }) .query('secret', { From 743cac26e1ebbf93de95ec37c4a47480aa9aa0b5 Mon Sep 17 00:00:00 2001 From: KATT Date: Fri, 13 Aug 2021 15:22:10 +0200 Subject: [PATCH 05/12] tweak --- packages/server/src/http/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/server/src/http/index.ts b/packages/server/src/http/index.ts index 8d0e6e16bd0..e424f9cad79 100644 --- a/packages/server/src/http/index.ts +++ b/packages/server/src/http/index.ts @@ -1,6 +1,5 @@ /* eslint-disable @typescript-eslint/no-non-null-assertion */ /* eslint-disable @typescript-eslint/no-explicit-any */ import { assertNotBrowser } from '../assertNotBrowser'; -export * from './errors'; export * from './requestHandler'; assertNotBrowser(); From d08bd12d0189438ebf2edc047f914e089ec3dfae Mon Sep 17 00:00:00 2001 From: KATT Date: Fri, 13 Aug 2021 15:23:37 +0200 Subject: [PATCH 06/12] remove `METHOD_NOT_FOUND` --- packages/server/src/http/internals/getHTTPStatusCode.ts | 1 - packages/server/src/rpc/codes.ts | 4 ---- 2 files changed, 5 deletions(-) diff --git a/packages/server/src/http/internals/getHTTPStatusCode.ts b/packages/server/src/http/internals/getHTTPStatusCode.ts index a696f9f33f1..66e45f9d3f8 100644 --- a/packages/server/src/http/internals/getHTTPStatusCode.ts +++ b/packages/server/src/http/internals/getHTTPStatusCode.ts @@ -12,7 +12,6 @@ const JSONRPC2_TO_HTTP_CODE: Record< > = { PARSE_ERROR: 400, BAD_REQUEST: 400, - METHOD_NOT_FOUND: 405, PATH_NOT_FOUND: 404, INTERNAL_SERVER_ERROR: 500, UNAUTHORIZED: 401, diff --git a/packages/server/src/rpc/codes.ts b/packages/server/src/rpc/codes.ts index 7571dd8b74f..93603342ffa 100644 --- a/packages/server/src/rpc/codes.ts +++ b/packages/server/src/rpc/codes.ts @@ -18,10 +18,6 @@ export const TRPC_ERROR_CODES_BY_KEY = { * The JSON sent is not a valid Request object. */ BAD_REQUEST: -32600, - /** - * The method does not exist / is not available. - */ - METHOD_NOT_FOUND: -32601, /** * Internal JSON-RPC error. */ From ae7a779bfdb7f7fd38280436c34d69a10c1faae9 Mon Sep 17 00:00:00 2001 From: KATT Date: Fri, 13 Aug 2021 15:29:35 +0200 Subject: [PATCH 07/12] `PATH_NOT_FOUND` -> `NOT_FOUND` --- packages/server/src/http/internals/getHTTPStatusCode.ts | 2 +- packages/server/src/router.ts | 2 +- packages/server/src/rpc/codes.ts | 2 +- packages/server/test/errors.test.ts | 2 +- packages/server/test/react.test.tsx | 2 +- packages/server/test/websockets.test.ts | 2 +- www/docs/server/error-handling.md | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/server/src/http/internals/getHTTPStatusCode.ts b/packages/server/src/http/internals/getHTTPStatusCode.ts index 66e45f9d3f8..9219aca8d09 100644 --- a/packages/server/src/http/internals/getHTTPStatusCode.ts +++ b/packages/server/src/http/internals/getHTTPStatusCode.ts @@ -12,7 +12,7 @@ const JSONRPC2_TO_HTTP_CODE: Record< > = { PARSE_ERROR: 400, BAD_REQUEST: 400, - PATH_NOT_FOUND: 404, + NOT_FOUND: 404, INTERNAL_SERVER_ERROR: 500, UNAUTHORIZED: 401, FORBIDDEN: 403, diff --git a/packages/server/src/router.ts b/packages/server/src/router.ts index 483e8f7ff25..bde8a7140c8 100644 --- a/packages/server/src/router.ts +++ b/packages/server/src/router.ts @@ -453,7 +453,7 @@ export class Router< if (!procedure) { throw new TRPCError({ - code: 'PATH_NOT_FOUND', + code: 'NOT_FOUND', message: `No "${type}"-procedure on path "${path}"`, }); } diff --git a/packages/server/src/rpc/codes.ts b/packages/server/src/rpc/codes.ts index 93603342ffa..3330c4322f1 100644 --- a/packages/server/src/rpc/codes.ts +++ b/packages/server/src/rpc/codes.ts @@ -25,7 +25,7 @@ export const TRPC_ERROR_CODES_BY_KEY = { // Implementation specific errors UNAUTHORIZED: -32001, // 401 FORBIDDEN: -32003, // 403 - PATH_NOT_FOUND: -32004, // 404 + NOT_FOUND: -32004, // 404 METHOD_NOT_SUPPORTED: -32005, // 405 TIMEOUT: -32008, // 408 PAYLOAD_TOO_LARGE: -32013, // 413 diff --git a/packages/server/test/errors.test.ts b/packages/server/test/errors.test.ts index 14b791627ed..d702a3ef045 100644 --- a/packages/server/test/errors.test.ts +++ b/packages/server/test/errors.test.ts @@ -249,7 +249,7 @@ test('make sure object is ignoring prototype', async () => { expect(clientError.shape.code).toMatchInlineSnapshot(`-32004`); expect(onError).toHaveBeenCalledTimes(1); const serverError = onError.mock.calls[0][0].error; - expect(serverError.code).toMatchInlineSnapshot(`"PATH_NOT_FOUND"`); + expect(serverError.code).toMatchInlineSnapshot(`"NOT_FOUND"`); close(); }); diff --git a/packages/server/test/react.test.tsx b/packages/server/test/react.test.tsx index 86f57f24f65..719fb27fe9a 100644 --- a/packages/server/test/react.test.tsx +++ b/packages/server/test/react.test.tsx @@ -93,7 +93,7 @@ function createAppRouter() { postById(input); const post = db.posts.find((p) => p.id === input); if (!post) { - throw new TRPCError({ code: 'PATH_NOT_FOUND' }); + throw new TRPCError({ code: 'NOT_FOUND' }); } return post; }, diff --git a/packages/server/test/websockets.test.ts b/packages/server/test/websockets.test.ts index 3a67d61aaa8..8a0209f278c 100644 --- a/packages/server/test/websockets.test.ts +++ b/packages/server/test/websockets.test.ts @@ -443,7 +443,7 @@ test('not found error', async () => { ); expect(error.name).toBe('TRPCClientError'); - expect(error.shape?.data.code).toMatchInlineSnapshot(`"PATH_NOT_FOUND"`); + expect(error.shape?.data.code).toMatchInlineSnapshot(`"NOT_FOUND"`); close(); }); diff --git a/www/docs/server/error-handling.md b/www/docs/server/error-handling.md index a3a79cdba6a..af8b572c805 100644 --- a/www/docs/server/error-handling.md +++ b/www/docs/server/error-handling.md @@ -60,6 +60,6 @@ throw new TRPCError({ code: 'INTERNAL_SERVER_ERROR', message: 'Optional Message' // "FORBIDDEN" // "BAD_REQUEST" // "INTERNAL_SERVER_ERROR" -// "PATH_NOT_FOUND" +// "NOT_FOUND" // "TIMEOUT" ``` From 099a5c77654d51bb53f2b85dceebdc6087a47043 Mon Sep 17 00:00:00 2001 From: KATT Date: Sun, 15 Aug 2021 18:56:55 +0200 Subject: [PATCH 08/12] align serialization between input/output closes #746 --- packages/client/src/internals/httpRequest.ts | 13 +++++----- packages/server/src/http/requestHandler.ts | 27 +++++++++++++------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/packages/client/src/internals/httpRequest.ts b/packages/client/src/internals/httpRequest.ts index c457012cf83..bb3e994b4dc 100644 --- a/packages/client/src/internals/httpRequest.ts +++ b/packages/client/src/internals/httpRequest.ts @@ -27,7 +27,12 @@ export function httpRequest( mutation: 'POST', subscription: 'PATCH', }; - const input = 'input' in props ? props.input : arrayToDict(props.inputs); + const input = + 'input' in props + ? rt.transformer.serialize(props.input) + : arrayToDict( + props.inputs.map((_input) => rt.transformer.serialize(_input)), + ); function getUrl() { let url = props.url + '/' + path; const queryParts: string[] = []; @@ -35,11 +40,7 @@ export function httpRequest( queryParts.push('batch=1'); } if (type === 'query' && input !== undefined) { - queryParts.push( - `input=${encodeURIComponent( - JSON.stringify(rt.transformer.serialize(input)), - )}`, - ); + queryParts.push(`input=${encodeURIComponent(JSON.stringify(input))}`); } if (queryParts.length) { url += '?' + queryParts.join('&'); diff --git a/packages/server/src/http/requestHandler.ts b/packages/server/src/http/requestHandler.ts index 4a5382e4a9a..7611e4f5c7d 100644 --- a/packages/server/src/http/requestHandler.ts +++ b/packages/server/src/http/requestHandler.ts @@ -83,7 +83,7 @@ export async function requestHandler< } const type = HTTP_METHOD_PROCEDURE_TYPE_MAP[req.method!] ?? ('unknown' as const); - let input: unknown = undefined; + const input: unknown = undefined; let ctx: inferRouterContext | undefined = undefined; const reqQueryParams = req.query @@ -112,24 +112,33 @@ export async function requestHandler< type, }); - input = - rawInput !== undefined - ? router._def.transformer.input.deserialize(rawInput) - : undefined; ctx = await createContext?.({ req, res }); - const getInputs = (): unknown[] | Record => { + const getInputs = (): Record => { if (!isBatchCall) { - return [input]; + return { + 0: router._def.transformer.input.deserialize(rawInput), + }; } - if (input == null || typeof input !== 'object' || Array.isArray(input)) { + if ( + rawInput == null || + typeof rawInput !== 'object' || + Array.isArray(rawInput) + ) { throw new TRPCError({ code: 'BAD_REQUEST', message: '"input" needs to be an object when doing a batch call', }); } - return input as any; + const input: Record = {}; + for (const key in rawInput) { + const k = key as any as number; + input[k] = router._def.transformer.input.deserialize( + (rawInput as any)[k], + ); + } + return input; }; const inputs = getInputs(); const paths = isBatchCall ? opts.path.split(',') : [opts.path]; From dc68060b5f1521f4ffcd8e30008c0a4e512eba48 Mon Sep 17 00:00:00 2001 From: KATT Date: Sun, 15 Aug 2021 19:13:56 +0200 Subject: [PATCH 09/12] fix posting --- examples/next-prisma-todomvc/next-env.d.ts | 3 +++ packages/client/src/internals/httpRequest.ts | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/next-prisma-todomvc/next-env.d.ts b/examples/next-prisma-todomvc/next-env.d.ts index c6643fda12f..9bc3dd46b9d 100644 --- a/examples/next-prisma-todomvc/next-env.d.ts +++ b/examples/next-prisma-todomvc/next-env.d.ts @@ -1,3 +1,6 @@ /// /// /// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/packages/client/src/internals/httpRequest.ts b/packages/client/src/internals/httpRequest.ts index bb3e994b4dc..6053222da64 100644 --- a/packages/client/src/internals/httpRequest.ts +++ b/packages/client/src/internals/httpRequest.ts @@ -33,6 +33,7 @@ export function httpRequest( : arrayToDict( props.inputs.map((_input) => rt.transformer.serialize(_input)), ); + function getUrl() { let url = props.url + '/' + path; const queryParts: string[] = []; @@ -51,8 +52,7 @@ export function httpRequest( if (type === 'query') { return undefined; } - const rawInput = rt.transformer.serialize(input); - return rawInput !== undefined ? JSON.stringify(rawInput) : undefined; + return input !== undefined ? JSON.stringify(input) : undefined; } const promise = new Promise((resolve, reject) => { From acc41b5b22ee4edefc185a5b7a77ef3a4188f6c4 Mon Sep 17 00:00:00 2001 From: KATT Date: Sun, 15 Aug 2021 22:08:49 +0200 Subject: [PATCH 10/12] add little comment --- packages/server/src/rpc/codes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/server/src/rpc/codes.ts b/packages/server/src/rpc/codes.ts index 3330c4322f1..0a89a1ec9f6 100644 --- a/packages/server/src/rpc/codes.ts +++ b/packages/server/src/rpc/codes.ts @@ -17,7 +17,7 @@ export const TRPC_ERROR_CODES_BY_KEY = { /** * The JSON sent is not a valid Request object. */ - BAD_REQUEST: -32600, + BAD_REQUEST: -32600, // 400 /** * Internal JSON-RPC error. */ From 5ffe60b5a4ce78219900d74e850fb72e9b0e8e56 Mon Sep 17 00:00:00 2001 From: KATT Date: Mon, 16 Aug 2021 17:00:52 +0200 Subject: [PATCH 11/12] remove useless `input`, add commnet --- packages/server/src/http/requestHandler.ts | 26 ++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/packages/server/src/http/requestHandler.ts b/packages/server/src/http/requestHandler.ts index 7611e4f5c7d..ee2754cae34 100644 --- a/packages/server/src/http/requestHandler.ts +++ b/packages/server/src/http/requestHandler.ts @@ -83,7 +83,6 @@ export async function requestHandler< } const type = HTTP_METHOD_PROCEDURE_TYPE_MAP[req.method!] ?? ('unknown' as const); - const input: unknown = undefined; let ctx: inferRouterContext | undefined = undefined; const reqQueryParams = req.query @@ -145,6 +144,7 @@ export async function requestHandler< const results = await Promise.all( paths.map(async (path, index) => { const id = null; + const input = inputs[index]; try { const output = await callProcedure({ ctx, @@ -179,16 +179,34 @@ export async function requestHandler< const result = isBatchCall ? results : results[0]; endResponse(result); } catch (_err) { + // we get here if + // - batching is called when it's not enabled + // - `createContext()` throws + // - post body is too large + // - input deserialization fails const error = getErrorFromUnknown(_err); const json: TRPCErrorResponse = { - id: -1, + id: null, error: router._def.transformer.output.serialize( - router.getErrorShape({ error, type, path: undefined, input, ctx }), + router.getErrorShape({ + error, + type, + path: undefined, + input: undefined, + ctx, + }), ), }; endResponse(json); - onError?.({ error, path: undefined, input, ctx, type: type, req }); + onError?.({ + error, + path: undefined, + input: undefined, + ctx, + type: type, + req, + }); } await teardown?.(); } From 50ad4eb10842570bf24ef6fcfe0dae7f3e5473f6 Mon Sep 17 00:00:00 2001 From: KATT Date: Fri, 20 Aug 2021 12:39:37 +0200 Subject: [PATCH 12/12] v9.0.0-alpha.2 --- examples/.wip/next-chat/package.json | 10 +++++----- examples/express-server/package.json | 8 ++++---- examples/next-prisma-starter-websockets/package.json | 10 +++++----- examples/next-prisma-starter/package.json | 10 +++++----- examples/next-prisma-todomvc/package.json | 10 +++++----- examples/standalone-server/package.json | 8 ++++---- lerna.json | 2 +- packages/client/package.json | 4 ++-- packages/next/package.json | 8 ++++---- packages/react/package.json | 6 +++--- packages/server/package.json | 2 +- 11 files changed, 39 insertions(+), 39 deletions(-) diff --git a/examples/.wip/next-chat/package.json b/examples/.wip/next-chat/package.json index c696139c1fa..a9833e063ca 100644 --- a/examples/.wip/next-chat/package.json +++ b/examples/.wip/next-chat/package.json @@ -1,6 +1,6 @@ { "name": "@examples/chat", - "version": "9.0.0-alpha.1", + "version": "9.0.0-alpha.2", "private": true, "scripts": { "dx:next": "prisma generate && next dev", @@ -18,10 +18,10 @@ }, "dependencies": { "@prisma/client": "^2.18.0", - "@trpc/client": "^9.0.0-alpha.1", - "@trpc/next": "^9.0.0-alpha.1", - "@trpc/react": "^9.0.0-alpha.1", - "@trpc/server": "^9.0.0-alpha.1", + "@trpc/client": "^9.0.0-alpha.2", + "@trpc/next": "^9.0.0-alpha.2", + "@trpc/react": "^9.0.0-alpha.2", + "@trpc/server": "^9.0.0-alpha.2", "jest": "^27.0.5", "jest-playwright": "^0.0.1", "jest-playwright-preset": "^1.4.5", diff --git a/examples/express-server/package.json b/examples/express-server/package.json index 57b50f0cb4f..c5f1232db1e 100644 --- a/examples/express-server/package.json +++ b/examples/express-server/package.json @@ -1,6 +1,6 @@ { "name": "@examples/express-server", - "version": "9.0.0-alpha.1", + "version": "9.0.0-alpha.2", "private": true, "scripts": { "dev:server": "nodemon -e ts -w . -x ts-node ./src/server.ts", @@ -12,9 +12,9 @@ "test-start": "start-server-and-test 'node dist/server' 2021 'node dist/client'" }, "dependencies": { - "@trpc/client": "^9.0.0-alpha.1", - "@trpc/react": "^9.0.0-alpha.1", - "@trpc/server": "^9.0.0-alpha.1", + "@trpc/client": "^9.0.0-alpha.2", + "@trpc/react": "^9.0.0-alpha.2", + "@trpc/server": "^9.0.0-alpha.2", "@types/node-fetch": "^2.5.11", "abort-controller": "^3.0.0", "express": "^4.17.1", diff --git a/examples/next-prisma-starter-websockets/package.json b/examples/next-prisma-starter-websockets/package.json index 5da9e1f0681..68078b72957 100644 --- a/examples/next-prisma-starter-websockets/package.json +++ b/examples/next-prisma-starter-websockets/package.json @@ -1,6 +1,6 @@ { "name": "@examples/next-starter-websockets", - "version": "9.0.0-alpha.1", + "version": "9.0.0-alpha.2", "private": true, "scripts": { "build:1-generate": "prisma generate", @@ -31,10 +31,10 @@ }, "dependencies": { "@prisma/client": "^2.18.0", - "@trpc/client": "^9.0.0-alpha.1", - "@trpc/next": "^9.0.0-alpha.1", - "@trpc/react": "^9.0.0-alpha.1", - "@trpc/server": "^9.0.0-alpha.1", + "@trpc/client": "^9.0.0-alpha.2", + "@trpc/next": "^9.0.0-alpha.2", + "@trpc/react": "^9.0.0-alpha.2", + "@trpc/server": "^9.0.0-alpha.2", "clsx": "^1.1.1", "next": "^11.1.0", "next-auth": "^3.27.3", diff --git a/examples/next-prisma-starter/package.json b/examples/next-prisma-starter/package.json index 2780b0c79d9..79d121e6789 100644 --- a/examples/next-prisma-starter/package.json +++ b/examples/next-prisma-starter/package.json @@ -1,6 +1,6 @@ { "name": "@examples/next-starter", - "version": "9.0.0-alpha.1", + "version": "9.0.0-alpha.2", "private": true, "scripts": { "build:1-generate": "prisma generate", @@ -30,10 +30,10 @@ }, "dependencies": { "@prisma/client": "^2.18.0", - "@trpc/client": "^9.0.0-alpha.1", - "@trpc/next": "^9.0.0-alpha.1", - "@trpc/react": "^9.0.0-alpha.1", - "@trpc/server": "^9.0.0-alpha.1", + "@trpc/client": "^9.0.0-alpha.2", + "@trpc/next": "^9.0.0-alpha.2", + "@trpc/react": "^9.0.0-alpha.2", + "@trpc/server": "^9.0.0-alpha.2", "clsx": "^1.1.1", "next": "^11.1.0", "react": "^17.0.1", diff --git a/examples/next-prisma-todomvc/package.json b/examples/next-prisma-todomvc/package.json index 79f7431980c..a0e8683e475 100644 --- a/examples/next-prisma-todomvc/package.json +++ b/examples/next-prisma-todomvc/package.json @@ -1,6 +1,6 @@ { "name": "@examples/todo-web", - "version": "9.0.0-alpha.1", + "version": "9.0.0-alpha.2", "private": true, "scripts": { "migrate-sqlite": "npx prisma migrate dev --name init --schema=./prisma/_sqlite/schema.prisma", @@ -24,10 +24,10 @@ }, "dependencies": { "@prisma/client": "^2.18.0", - "@trpc/client": "^9.0.0-alpha.1", - "@trpc/next": "^9.0.0-alpha.1", - "@trpc/react": "^9.0.0-alpha.1", - "@trpc/server": "^9.0.0-alpha.1", + "@trpc/client": "^9.0.0-alpha.2", + "@trpc/next": "^9.0.0-alpha.2", + "@trpc/react": "^9.0.0-alpha.2", + "@trpc/server": "^9.0.0-alpha.2", "clsx": "^1.1.1", "jest": "^27.0.5", "jest-playwright": "^0.0.1", diff --git a/examples/standalone-server/package.json b/examples/standalone-server/package.json index 104a9be36d4..14e0f9c7a53 100644 --- a/examples/standalone-server/package.json +++ b/examples/standalone-server/package.json @@ -1,6 +1,6 @@ { "name": "@examples/standalone-server", - "version": "9.0.0-alpha.1", + "version": "9.0.0-alpha.2", "private": true, "scripts": { "dev:server": "nodemon -e ts -w . -x ts-node ./src/server.ts", @@ -12,9 +12,9 @@ "test-start": "start-server-and-test 'node dist/server' 2022 'node dist/client'" }, "dependencies": { - "@trpc/client": "^9.0.0-alpha.1", - "@trpc/react": "^9.0.0-alpha.1", - "@trpc/server": "^9.0.0-alpha.1", + "@trpc/client": "^9.0.0-alpha.2", + "@trpc/react": "^9.0.0-alpha.2", + "@trpc/server": "^9.0.0-alpha.2", "@types/node-fetch": "^2.5.11", "abort-controller": "^3.0.0", "node-fetch": "^2.6.1", diff --git a/lerna.json b/lerna.json index 4fe83d7d4f3..01ebf2cde77 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "9.0.0-alpha.1", + "version": "9.0.0-alpha.2", "registry": "https://registry.npmjs.org/", "publishConfig": { "access": "public" diff --git a/packages/client/package.json b/packages/client/package.json index 72f9b7b14a1..bacf15ce64d 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@trpc/client", - "version": "9.0.0-alpha.1", + "version": "9.0.0-alpha.2", "description": "tRPC Client lib", "author": "KATT", "license": "MIT", @@ -31,7 +31,7 @@ ], "dependencies": { "@babel/runtime": "^7.9.0", - "@trpc/server": "^9.0.0-alpha.1" + "@trpc/server": "^9.0.0-alpha.2" }, "publishConfig": { "access": "public" diff --git a/packages/next/package.json b/packages/next/package.json index 218c15f2405..8c0381095b5 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "@trpc/next", - "version": "9.0.0-alpha.1", + "version": "9.0.0-alpha.2", "description": "tRPC Next lib", "author": "KATT", "license": "MIT", @@ -36,9 +36,9 @@ }, "dependencies": { "@babel/runtime": "^7.9.0", - "@trpc/client": "^9.0.0-alpha.1", - "@trpc/react": "^9.0.0-alpha.1", - "@trpc/server": "^9.0.0-alpha.1", + "@trpc/client": "^9.0.0-alpha.2", + "@trpc/react": "^9.0.0-alpha.2", + "@trpc/server": "^9.0.0-alpha.2", "react-ssr-prepass": "^1.4.0" }, "devDependencies": { diff --git a/packages/react/package.json b/packages/react/package.json index ce95f823240..9cf33a2c036 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@trpc/react", - "version": "9.0.0-alpha.1", + "version": "9.0.0-alpha.2", "description": "tRPC React lib", "author": "KATT", "license": "MIT", @@ -37,8 +37,8 @@ }, "dependencies": { "@babel/runtime": "^7.9.0", - "@trpc/client": "^9.0.0-alpha.1", - "@trpc/server": "^9.0.0-alpha.1" + "@trpc/client": "^9.0.0-alpha.2", + "@trpc/server": "^9.0.0-alpha.2" }, "devDependencies": { "@types/express": "^4.17.12", diff --git a/packages/server/package.json b/packages/server/package.json index 91ee1ea2d5a..fa41d6b4465 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,6 +1,6 @@ { "name": "@trpc/server", - "version": "9.0.0-alpha.1", + "version": "9.0.0-alpha.2", "description": "tRPC Server", "author": "KATT", "license": "MIT",