diff --git a/.github/workflows/callable-release-verification.yml b/.github/workflows/callable-release-verification.yml index 30fd4b0c7e0..a3b041eec56 100644 --- a/.github/workflows/callable-release-verification.yml +++ b/.github/workflows/callable-release-verification.yml @@ -14,13 +14,13 @@ jobs: prebuild-samples-staging: secrets: inherit uses: ./.github/workflows/callable-prebuild-samples-staging.yml - e2e: - needs: - - prebuild-macos - - prebuild-ubuntu - - prebuild-samples-staging - secrets: inherit - uses: ./.github/workflows/callable-e2e-tests.yml + # e2e: + # needs: + # - prebuild-macos + # - prebuild-ubuntu + # - prebuild-samples-staging + # secrets: inherit + # uses: ./.github/workflows/callable-e2e-tests.yml unit-tests: needs: - prebuild-ubuntu diff --git a/packages/api/__tests__/models/APIClient.test.ts b/packages/api/__tests__/models/APIClient.test.ts index 486ccc0e768..e1deb838f91 100644 --- a/packages/api/__tests__/models/APIClient.test.ts +++ b/packages/api/__tests__/models/APIClient.test.ts @@ -1,4 +1,4 @@ -import { normalizeMutationInput, initializeModel } from '../../src/APIClient'; +import { normalizeMutationInput, flattenItems } from '../../src/APIClient'; import modelIntroSchema from '../assets/model-introspection'; describe('APIClient', () => { @@ -39,3 +39,119 @@ describe('APIClient', () => { test('initializeModel', () => {}); }); + +describe('flattenItems', () => { + test('no-op on get without relationships', () => { + const getResponse = { getPost: { id: 'myPost' } }; + + const expected = { getPost: { id: 'myPost' } }; + + const flattened = flattenItems(getResponse); + + expect(flattened).toEqual(expected); + }); + + test('flatten list without relationships', () => { + const listResponse = { + listPost: { items: [{ id: 'myPost' }, { id: 'myPost2' }] }, + }; + + const expected = { + listPost: [{ id: 'myPost' }, { id: 'myPost2' }], + }; + + const flattened = flattenItems(listResponse); + + expect(flattened).toEqual(expected); + }); + + test('flatten list with relationships', () => { + const listResponse = { + listPosts: { + items: [ + { + id: 'post1', + comments: { + items: [ + { + id: 'comment1', + content: 'my comment 1', + meta: { + items: [{ id: 'meta1' }], + }, + post: { + id: 'post1', + comments: { + items: [ + { + id: 'comment1', + content: 'my comment 1', + meta: { + items: [{ id: 'meta1' }], + }, + }, + ], + }, + }, + }, + { + id: 'comment1', + content: 'my comment 1', + meta: { + items: [{ id: 'meta1' }], + }, + }, + ], + }, + }, + ], + }, + }; + + const expected = { + listPosts: [ + { + id: 'post1', + comments: [ + { + id: 'comment1', + content: 'my comment 1', + meta: [ + { + id: 'meta1', + }, + ], + post: { + id: 'post1', + comments: [ + { + id: 'comment1', + content: 'my comment 1', + meta: [ + { + id: 'meta1', + }, + ], + }, + ], + }, + }, + { + id: 'comment1', + content: 'my comment 1', + meta: [ + { + id: 'meta1', + }, + ], + }, + ], + }, + ], + }; + + const flattened = flattenItems(listResponse); + + expect(flattened).toEqual(expected); + }); +}); diff --git a/packages/api/package.json b/packages/api/package.json index 1a4ef50b285..baabdc7dc33 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -61,7 +61,7 @@ "dependencies": { "@aws-amplify/api-graphql": "3.4.11", "@aws-amplify/api-rest": "3.5.5", - "@aws-amplify/amplify-api-next-types-alpha": "^0.0.5", + "@aws-amplify/amplify-api-next-types-alpha": "^0.1.2", "tslib": "^2.6.1" }, "size-limit": [ diff --git a/packages/api/src/API.ts b/packages/api/src/API.ts index 8f503972fe0..a186614c430 100644 --- a/packages/api/src/API.ts +++ b/packages/api/src/API.ts @@ -17,6 +17,7 @@ import { buildGraphQLVariables, graphQLOperationsInfo, ModelOperation, + flattenItems, } from './APIClient'; import type { ModelTypes } from '@aws-amplify/amplify-api-next-types-alpha'; @@ -26,6 +27,7 @@ const logger = new Logger('API'); * Use RestApi or GraphQLAPI to reduce your application bundle size * Export Cloud Logic APIs */ + export class APIClass extends InternalAPIClass { public getModuleName() { return 'API'; @@ -107,7 +109,7 @@ export class APIClass extends InternalAPIClass { const [key] = Object.keys(res.data); if (res.data[key].items) { - const flattenedResult = res.data[key].items; + const flattenedResult = flattenItems(res.data)[key]; // don't init if custom selection set if (args?.selectionSet) { diff --git a/packages/api/src/APIClient.ts b/packages/api/src/APIClient.ts index 8cc0228477d..fdec65237f5 100644 --- a/packages/api/src/APIClient.ts +++ b/packages/api/src/APIClient.ts @@ -8,6 +8,32 @@ const connectionType = { BELONGS_TO: 'BELONGS_TO', }; +/** + * + * @param GraphQL response object + * @returns response object with `items` properties flattened + */ +export const flattenItems = (obj: Record): Record => { + const res: Record = {}; + + Object.entries(obj).forEach(([prop, value]) => { + if (typeof value === 'object' && value !== null) { + if (value.items !== undefined) { + res[prop] = value.items.map((item: Record) => + flattenItems(item) + ); + return; + } + res[prop] = flattenItems(value); + return; + } + + res[prop] = value; + }); + + return res; +}; + // TODO: this should accept single result to support CRUD methods; create helper for array/list export function initializeModel( client: any, diff --git a/packages/api/src/types/index.ts b/packages/api/src/types/index.ts index bab7846a11a..010df04a259 100644 --- a/packages/api/src/types/index.ts +++ b/packages/api/src/types/index.ts @@ -14,3 +14,4 @@ export { GraphQLQuery, GraphQLSubscription, } from '@aws-amplify/api-graphql'; +export { SelectionSet } from '@aws-amplify/amplify-api-next-types-alpha'; diff --git a/yarn.lock b/yarn.lock index d3973f95612..b7b7a5fb074 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15,10 +15,10 @@ "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" -"@aws-amplify/amplify-api-next-types-alpha@^0.0.5": - version "0.0.5" - resolved "https://registry.yarnpkg.com/@aws-amplify/amplify-api-next-types-alpha/-/amplify-api-next-types-alpha-0.0.5.tgz#afeaba02f2607ac43de404bfcbb8702cb56f6ff9" - integrity sha512-FlOfQX9+r0Q8G5EEAV5tkBjcaTJhlnwfaeoe4K42BLKPzngntn+wWIFbIIbCFjW18DUmv62ItynzNSls+E38vg== +"@aws-amplify/amplify-api-next-types-alpha@^0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@aws-amplify/amplify-api-next-types-alpha/-/amplify-api-next-types-alpha-0.1.2.tgz#e25ee9b5c9bcbc2ca6d807d372c81175465e1886" + integrity sha512-g+t8F0F0J+SPutmc3WszOvZQdPu9Z5dm7b0Q6CyBx3+oUxc7O83jazdR04uydX4NLAwui8QSKg2StI82FKw8sQ== "@aws-crypto/crc32@2.0.0": version "2.0.0"