From 25ce5b580cc77657cc7d69e2e28aacbb3e314b19 Mon Sep 17 00:00:00 2001 From: Jon Wire Date: Tue, 17 Oct 2023 09:02:52 -0500 Subject: [PATCH] feat: change `client.models` return to include data, errors, nextToken (#12318) * stash * runtime re-mapping of return types * cruft cleanup * added missing extensions prop * removed accidentally added file --- .../__tests__/generateClient.test.ts | 34 ++--- .../src/internals/generateModelsProperty.ts | 126 +++++++++++------- 2 files changed, 95 insertions(+), 65 deletions(-) diff --git a/packages/api-graphql/__tests__/generateClient.test.ts b/packages/api-graphql/__tests__/generateClient.test.ts index bdd43f2a5f8..3cd0fc79f94 100644 --- a/packages/api-graphql/__tests__/generateClient.test.ts +++ b/packages/api-graphql/__tests__/generateClient.test.ts @@ -153,7 +153,7 @@ describe('generateClient', () => { }); const client = generateClient({ amplify: Amplify }); - const result = await client.models.Todo.create({ + const { data } = await client.models.Todo.create({ name: 'some name', description: 'something something', }); @@ -177,7 +177,7 @@ describe('generateClient', () => { }) ); - expect(result).toEqual( + expect(data).toEqual( expect.objectContaining({ __typename: 'Todo', id: 'some-id', @@ -201,7 +201,7 @@ describe('generateClient', () => { }); const client = generateClient({ amplify: Amplify }); - const result = await client.models.Todo.get({ id: 'asdf' }); + const { data } = await client.models.Todo.get({ id: 'asdf' }); expect(spy).toHaveBeenCalledWith( expect.objectContaining({ @@ -219,7 +219,7 @@ describe('generateClient', () => { }) ); - expect(result).toEqual( + expect(data).toEqual( expect.objectContaining({ __typename: 'Todo', id: 'some-id', @@ -247,7 +247,7 @@ describe('generateClient', () => { }); const client = generateClient({ amplify: Amplify }); - const result = await client.models.Todo.list({ + const { data } = await client.models.Todo.list({ filter: { name: { contains: 'name' } }, }); @@ -271,8 +271,8 @@ describe('generateClient', () => { }) ); - expect(result.length).toBe(1); - expect(result[0]).toEqual( + expect(data.length).toBe(1); + expect(data[0]).toEqual( expect.objectContaining({ __typename: 'Todo', id: 'some-id', @@ -296,7 +296,7 @@ describe('generateClient', () => { }); const client = generateClient({ amplify: Amplify }); - const result = await client.models.Todo.update({ + const { data } = await client.models.Todo.update({ id: 'some-id', name: 'some other name', }); @@ -320,7 +320,7 @@ describe('generateClient', () => { }) ); - expect(result).toEqual( + expect(data).toEqual( expect.objectContaining({ __typename: 'Todo', id: 'some-id', @@ -344,7 +344,7 @@ describe('generateClient', () => { }); const client = generateClient({ amplify: Amplify }); - const result = await client.models.Todo.delete({ + const { data } = await client.models.Todo.delete({ id: 'some-id', }); @@ -366,7 +366,7 @@ describe('generateClient', () => { }) ); - expect(result).toEqual( + expect(data).toEqual( expect.objectContaining({ __typename: 'Todo', id: 'some-id', @@ -391,7 +391,7 @@ describe('generateClient', () => { }); const client = generateClient({ amplify: Amplify }); - const result = await client.models.Todo.get({ id: 'todo-id' }); + const { data } = await client.models.Todo.get({ id: 'todo-id' }); const getChildNotesSpy = mockApiResponse({ data: { @@ -408,7 +408,7 @@ describe('generateClient', () => { }, }); - const notes = await result.notes(); + const { data: notes } = await data.notes(); expect(getChildNotesSpy).toHaveBeenCalledWith( expect.objectContaining({ @@ -453,7 +453,7 @@ describe('generateClient', () => { }); const client = generateClient({ amplify: Amplify }); - const result = await client.models.Note.get({ id: 'note-id' }); + const { data } = await client.models.Note.get({ id: 'note-id' }); const getChildNotesSpy = mockApiResponse({ data: { @@ -467,7 +467,7 @@ describe('generateClient', () => { }, }); - const todo = await result.todo(); + const { data: todo } = await data.todo(); expect(getChildNotesSpy).toHaveBeenCalledWith( expect.objectContaining({ @@ -509,7 +509,7 @@ describe('generateClient', () => { }); const client = generateClient({ amplify: Amplify }); - const result = await client.models.Todo.get({ id: 'todo-id' }); + const { data } = await client.models.Todo.get({ id: 'todo-id' }); const getChildMetaSpy = mockApiResponse({ data: { @@ -522,7 +522,7 @@ describe('generateClient', () => { }, }); - const todo = await result.meta(); + const { data: todo } = await data.meta(); expect(getChildMetaSpy).toHaveBeenCalledWith( expect.objectContaining({ diff --git a/packages/api-graphql/src/internals/generateModelsProperty.ts b/packages/api-graphql/src/internals/generateModelsProperty.ts index 56277c9880d..5342df12b77 100644 --- a/packages/api-graphql/src/internals/generateModelsProperty.ts +++ b/packages/api-graphql/src/internals/generateModelsProperty.ts @@ -49,37 +49,57 @@ export function generateModelsProperty = never>( modelIntrospection ); - const res = (await client.graphql({ - query, - variables, - })) as any; - - // flatten response - if (res.data !== undefined) { - const [key] = Object.keys(res.data); - - if (res.data[key].items) { - const flattenedResult = res.data[key].items; - - // don't init if custom selection set - if (args?.selectionSet) { - return flattenedResult; - } else { - const initialized = initializeModel( - client, - name, - flattenedResult, - modelIntrospection - ); - - return initialized; + try { + const { data, nextToken, extensions } = (await client.graphql({ + query, + variables, + })) as any; + + // flatten response + if (data !== undefined) { + const [key] = Object.keys(data); + + if (data[key].items) { + const flattenedResult = data[key].items; + + // don't init if custom selection set + if (args?.selectionSet) { + return { + data: flattenedResult, + nextToken, + extensions, + }; + } else { + const initialized = initializeModel( + client, + name, + flattenedResult, + modelIntrospection + ); + + return { + data: initialized, + nextToken, + extensions, + }; + } } - } - return res.data[key]; + return { + data: data[key], + nextToken, + extensions, + }; + } + } catch (error) { + if (error.errors) { + // graphql errors pass through + return error as any; + } else { + // non-graphql errors re re-thrown + throw error; + } } - - return res as any; }; } else { models[name][operationPrefix] = async (arg?: any, options?: any) => { @@ -95,27 +115,37 @@ export function generateModelsProperty = never>( modelIntrospection ); - const res = (await client.graphql({ - query, - variables, - })) as any; - - // flatten response - if (res.data !== undefined) { - const [key] = Object.keys(res.data); - - // TODO: refactor to avoid destructuring here - const [initialized] = initializeModel( - client, - name, - [res.data[key]], - modelIntrospection - ); - - return initialized; + try { + const { data, extensions } = (await client.graphql({ + query, + variables, + })) as any; + + // flatten response + if (data !== undefined) { + const [key] = Object.keys(data); + + // TODO: refactor to avoid destructuring here + const [initialized] = initializeModel( + client, + name, + [data[key]], + modelIntrospection + ); + + return { data: initialized, extensions }; + } else { + return { data: null, extensions }; + } + } catch (error) { + if (error.errors) { + // graphql errors pass through + return error as any; + } else { + // non-graphql errors re re-thrown + throw error; + } } - - return res; }; } }