diff --git a/packages/amplify-codegen/src/commands/types.js b/packages/amplify-codegen/src/commands/types.js index 5da70cddf..ee28bf6ff 100644 --- a/packages/amplify-codegen/src/commands/types.js +++ b/packages/amplify-codegen/src/commands/types.js @@ -7,7 +7,7 @@ const constants = require('../constants'); const { loadConfig } = require('../codegen-config'); const { ensureIntrospectionSchema, getFrontEndHandler, getAppSyncAPIDetails, getAppSyncAPIInfoFromProject } = require('../utils'); const { generateTypes: generateTypesHelper } = require('@aws-amplify/graphql-generator'); -const { extractDocumentFromJavascript } = require('@aws-amplify/graphql-types-generator'); +const { generate, extractDocumentFromJavascript } = require('@aws-amplify/graphql-types-generator'); async function generateTypes(context, forceDownloadSchema, withoutInit = false, decoupleFrontend = '') { let frontend = decoupleFrontend; @@ -57,25 +57,24 @@ async function generateTypes(context, forceDownloadSchema, withoutInit = false, const target = cfg.amplifyExtension.codeGenTarget; const excludes = cfg.excludes.map(pattern => `!${pattern}`); - const queryFiles = glob - .sync([...includeFiles, ...excludes], { - cwd: projectPath, - absolute: true, - }) - .map(queryFilePath => { - const fileContents = fs.readFileSync(queryFilePath, 'utf8'); - if ( - queryFilePath.endsWith('.jsx') || - queryFilePath.endsWith('.js') || - queryFilePath.endsWith('.tsx') || - queryFilePath.endsWith('.ts') - ) { - return extractDocumentFromJavascript(fileContents, ''); - } - return fileContents; - }); + const queryFilePaths = glob.sync([...includeFiles, ...excludes], { + cwd: projectPath, + absolute: true, + }); + const queryFiles = queryFilePaths.map(queryFilePath => { + const fileContents = fs.readFileSync(queryFilePath, 'utf8'); + if ( + queryFilePath.endsWith('.jsx') || + queryFilePath.endsWith('.js') || + queryFilePath.endsWith('.tsx') || + queryFilePath.endsWith('.ts') + ) { + return extractDocumentFromJavascript(fileContents, ''); + } + return fileContents; + }); if (queryFiles.length === 0) { - throw new Error('No queries found to generate types for, you may need to run \'codegen statements\' first'); + throw new Error("No queries found to generate types for, you may need to run 'codegen statements' first"); } const queries = queryFiles.join('\n'); @@ -96,22 +95,30 @@ async function generateTypes(context, forceDownloadSchema, withoutInit = false, const introspection = path.extname(schemaPath) === '.json'; try { - const output = await generateTypesHelper({ - schema, - queries, - target, - introspection, - }); - const outputs = Object.entries(output); - - const outputPath = path.join(projectPath, generatedFileName); - if (outputs.length === 1) { - const [[, contents]] = outputs; - fs.outputFileSync(path.resolve(outputPath), contents); + if (target === 'swift' && fs.existsSync(outputPath) && fs.statSync(outputPath).isDirectory()) { + generate(queryFilePaths, schemaPath, outputPath, '', target, '', { + addTypename: true, + complexObjectSupport: 'auto', + }); } else { - outputs.forEach(([filepath, contents]) => { - fs.outputFileSync(path.resolve(path.join(outputPath, filepath)), contents); + const output = await generateTypesHelper({ + schema, + queries, + target, + introspection, + multipleSwiftFiles: false, }); + const outputs = Object.entries(output); + + const outputPath = path.join(projectPath, generatedFileName); + if (outputs.length === 1) { + const [[, contents]] = outputs; + fs.outputFileSync(path.resolve(outputPath), contents); + } else { + outputs.forEach(([filepath, contents]) => { + fs.outputFileSync(path.resolve(path.join(outputPath, filepath)), contents); + }); + } } codeGenSpinner.succeed(`${constants.INFO_MESSAGE_CODEGEN_GENERATE_SUCCESS} ${path.relative(path.resolve('.'), outputPath)}`); } catch (err) { diff --git a/packages/amplify-codegen/tests/commands/types.test.js b/packages/amplify-codegen/tests/commands/types.test.js index a9cd3c36f..b492e0d55 100644 --- a/packages/amplify-codegen/tests/commands/types.test.js +++ b/packages/amplify-codegen/tests/commands/types.test.js @@ -1,6 +1,7 @@ const { sync } = require('glob-all'); const path = require('path'); const { generateTypes: generateTypesHelper } = require('@aws-amplify/graphql-generator'); +const { generate: legacyGenerate } = require('@aws-amplify/graphql-types-generator'); const fs = require('fs-extra'); const { loadConfig } = require('../../src/codegen-config'); @@ -20,6 +21,7 @@ const MOCK_CONTEXT = { jest.mock('glob-all'); jest.mock('@aws-amplify/graphql-generator'); +jest.mock('@aws-amplify/graphql-types-generator'); jest.mock('../../src/codegen-config'); jest.mock('../../src/utils'); jest.mock('fs-extra'); @@ -81,9 +83,35 @@ describe('command - types', () => { schema: 'schema', target: 'TYPE_SCRIPT_OR_FLOW_OR_ANY_OTHER_LANGUAGE', introspection: false, + multipleSwiftFiles: false, }); }); + it('should use legacy types generation when generating multiple swift files', async () => { + MOCK_PROJECT.amplifyExtension.codeGenTarget = 'swift'; + MOCK_PROJECT.amplifyExtension.generatedFileName = 'typesDirectory'; + const forceDownload = false; + fs.readFileSync + .mockReturnValueOnce('query 1') + .mockReturnValueOnce('query 2') + .mockReturnValueOnce('schema'); + fs.existsSync.mockReturnValueOnce(true); + fs.statSync.mockReturnValueOnce({ + isDirectory: jest.fn().mockReturnValue(true), + }); + await generateTypes(MOCK_CONTEXT, forceDownload); + expect(generateTypesHelper).not.toHaveBeenCalled(); + expect(legacyGenerate).toHaveBeenCalledWith( + ['q1.gql', 'q2.gql'], + 'MOCK_PROJECT_ROOT/INTROSPECTION_SCHEMA.JSON', + 'MOCK_PROJECT_ROOT/typesDirectory', + '', + 'swift', + '', + { addTypename: true, complexObjectSupport: 'auto' }, + ); + }); + it('should not generate type if the frontend is android', async () => { const forceDownload = false; getFrontEndHandler.mockReturnValue('android'); diff --git a/packages/appsync-modelgen-plugin/package.json b/packages/appsync-modelgen-plugin/package.json index c289ee3f0..15b0ff8b4 100644 --- a/packages/appsync-modelgen-plugin/package.json +++ b/packages/appsync-modelgen-plugin/package.json @@ -29,8 +29,6 @@ "@graphql-codegen/plugin-helpers": "^1.18.8", "@graphql-codegen/visitor-plugin-common": "^1.22.0", "@graphql-tools/utils": "^6.0.18", - "@types/node": "^12.12.6", - "@types/pluralize": "0.0.29", "chalk": "^3.0.0", "change-case": "^4.1.1", "lower-case-first": "^2.0.1", @@ -43,7 +41,9 @@ "@graphql-codegen/typescript": "^2.8.3", "graphql": "^15.5.0", "java-ast": "^0.3.0", - "ts-json-schema-generator": "1.0.0" + "ts-json-schema-generator": "1.0.0", + "@types/node": "^12.12.6", + "@types/pluralize": "0.0.29" }, "peerDependencies": { "graphql": "^15.5.0" diff --git a/packages/graphql-generator/API.md b/packages/graphql-generator/API.md index 169907436..75571257c 100644 --- a/packages/graphql-generator/API.md +++ b/packages/graphql-generator/API.md @@ -22,7 +22,7 @@ export type GenerateModelsOptions = { directives: string; generateIndexRules?: boolean; emitAuthProvider?: boolean; - useExperimentalPipelinedTranformer?: boolean; + useExperimentalPipelinedTransformer?: boolean; transformerVersion?: boolean; respectPrimaryKeyAttributesOnConnectionField?: boolean; generateModelsForLazyLoadAndCustomSelectionSet?: boolean; diff --git a/packages/graphql-generator/src/models.ts b/packages/graphql-generator/src/models.ts index 3dfb490ed..0871a7854 100644 --- a/packages/graphql-generator/src/models.ts +++ b/packages/graphql-generator/src/models.ts @@ -13,7 +13,7 @@ export async function generateModels(options: GenerateModelsOptions): Promise