diff --git a/packages/amplify-codegen/src/commands/statements.js b/packages/amplify-codegen/src/commands/statements.js index 86184b91d..522a605da 100644 --- a/packages/amplify-codegen/src/commands/statements.js +++ b/packages/amplify-codegen/src/commands/statements.js @@ -10,6 +10,7 @@ const { getAppSyncAPIDetails, readSchemaFromFile, getAppSyncAPIInfoFromProject, + getRelativeTypesPath, } = require('../utils'); const { generateGraphQLDocuments } = require('@aws-amplify/graphql-docs-generator'); const { generateStatements: generateStatementsHelper } = require('@aws-amplify/graphql-generator'); @@ -64,9 +65,6 @@ async function generateStatements(context, forceDownloadSchema, maxDepth, withou try { const schemaData = readSchemaFromFile(schemaPath); - const relativeTypesPath = cfg.amplifyExtension.generatedFileName - ? path.relative(opsGenDirectory, cfg.amplifyExtension.generatedFileName) - : null; const generatedOps = generateStatementsHelper({ schema: schemaData, target: language, @@ -75,7 +73,7 @@ async function generateStatements(context, forceDownloadSchema, maxDepth, withou // default typenameIntrospection to true when not set typenameIntrospection: cfg.amplifyExtension.typenameIntrospection === undefined ? true : !!cfg.amplifyExtension.typenameIntrospection, - relativeTypesPath, + relativeTypesPath: getRelativeTypesPath(opsGenDirectory, cfg.amplifyExtension.generatedFileName), }); if (!generatedOps) { context.print.warning('No GraphQL statements are generated. Check if the introspection schema has GraphQL operations defined.'); diff --git a/packages/amplify-codegen/src/utils/getRelativeTypesPath.js b/packages/amplify-codegen/src/utils/getRelativeTypesPath.js new file mode 100644 index 000000000..7d3f8cb5b --- /dev/null +++ b/packages/amplify-codegen/src/utils/getRelativeTypesPath.js @@ -0,0 +1,19 @@ +const path = require('path'); + +function getRelativeTypesPath(opsGenDirectory, generatedFileName) { + if (generatedFileName) { + const relativePath = path.relative(opsGenDirectory, generatedFileName); + + // generatedFileName is in same directory as opsGenDirectory + // i.e. generatedFileName: src/graphql/API.ts, opsGenDirectory: src/graphql + if (!relativePath.startsWith('.')) { + // path.join will strip prefixed ./ + return `./${relativePath}`; + } + + return relativePath; + } + return null; +} + +module.exports = getRelativeTypesPath; diff --git a/packages/amplify-codegen/src/utils/index.js b/packages/amplify-codegen/src/utils/index.js index 35dbbbbb8..25d2a1e89 100644 --- a/packages/amplify-codegen/src/utils/index.js +++ b/packages/amplify-codegen/src/utils/index.js @@ -17,6 +17,7 @@ const switchToSDLSchema = require('./switchToSDLSchema'); const ensureIntrospectionSchema = require('./ensureIntrospectionSchema'); const { readSchemaFromFile } = require('./readSchemaFromFile'); const defaultDirectiveDefinitions = require('./defaultDirectiveDefinitions'); +const getRelativeTypesPath = require('./getRelativeTypesPath'); module.exports = { getAppSyncAPIDetails, getFrontEndHandler, @@ -37,4 +38,5 @@ module.exports = { ensureIntrospectionSchema, readSchemaFromFile, defaultDirectiveDefinitions, + getRelativeTypesPath, }; diff --git a/packages/amplify-codegen/tests/commands/statements.test.js b/packages/amplify-codegen/tests/commands/statements.test.js index f1e8a5102..21440dc71 100644 --- a/packages/amplify-codegen/tests/commands/statements.test.js +++ b/packages/amplify-codegen/tests/commands/statements.test.js @@ -3,8 +3,15 @@ const fs = require('fs-extra'); const { loadConfig } = require('../../src/codegen-config'); const generateStatements = require('../../src/commands/statements'); +const { generateStatements: generateStatementsHelper } = require('@aws-amplify/graphql-generator'); const constants = require('../../src/constants'); -const { ensureIntrospectionSchema, getFrontEndHandler, getAppSyncAPIDetails, readSchemaFromFile } = require('../../src/utils'); +const { + ensureIntrospectionSchema, + getFrontEndHandler, + getAppSyncAPIDetails, + readSchemaFromFile, + getRelativeTypesPath, +} = require('../../src/utils'); const MOCK_CONTEXT = { print: { @@ -16,6 +23,7 @@ const MOCK_CONTEXT = { }, }; +jest.mock('@aws-amplify/graphql-generator'); jest.mock('../../src/codegen-config'); jest.mock('../../src/utils'); jest.mock('fs-extra'); @@ -67,21 +75,32 @@ describe('command - statements', () => { MOCK_CONTEXT.amplify.getEnvInfo.mockReturnValue({ projectPath: MOCK_PROJECT_ROOT }); getAppSyncAPIDetails.mockReturnValue(MOCK_APIS); readSchemaFromFile.mockReturnValue(MOCK_SCHEMA); + generateStatementsHelper.mockReturnValue({ + 'queries.js': 'queries', + }); }); it('should generate statements', async () => { const forceDownload = false; + const relativePath = './relative_path'; + getRelativeTypesPath.mockReturnValueOnce(relativePath); await generateStatements(MOCK_CONTEXT, forceDownload); expect(getFrontEndHandler).toHaveBeenCalledWith(MOCK_CONTEXT); expect(loadConfig).toHaveBeenCalledWith(MOCK_CONTEXT, false); + expect(getRelativeTypesPath).toHaveBeenCalledWith('MOCK_PROJECT_ROOT/MOCK_STATEMENTS_PATH', 'API.TS'); + expect(generateStatementsHelper).toHaveBeenCalledWith({ + relativeTypesPath: relativePath, + schema: MOCK_SCHEMA, + target: MOCK_TARGET_LANGUAGE, + typenameIntrospection: true, + useExternalFragmentForS3Object: false, + }); }); it('should generate graphql statements for non JS projects', async () => { getFrontEndHandler.mockReturnValue('ios'); loadConfig.mockReturnValue({ - getProjects: jest.fn().mockReturnValue([ - { ...MOCK_PROJECT, ...{ amplifyExtension: { codeGenTarget: 'javascript' }} } - ]), + getProjects: jest.fn().mockReturnValue([{ ...MOCK_PROJECT, ...{ amplifyExtension: { codeGenTarget: 'javascript' } } }]), }); const forceDownload = false; await generateStatements(MOCK_CONTEXT, forceDownload); diff --git a/packages/amplify-codegen/tests/utils/getRelativeTypesPath.test.js b/packages/amplify-codegen/tests/utils/getRelativeTypesPath.test.js new file mode 100644 index 000000000..56bd46a9b --- /dev/null +++ b/packages/amplify-codegen/tests/utils/getRelativeTypesPath.test.js @@ -0,0 +1,31 @@ +const getRelativeTypesPath = require('../../src/utils/getRelativeTypesPath'); + +describe('getRelativeTypesPath', () => { + test('in same directory', () => { + expect(getRelativeTypesPath('src/graphql', 'src/graphql/API.ts')).toEqual('./API.ts'); + }); + + test('one dir up', () => { + expect(getRelativeTypesPath('src/graphql', 'src/API.ts')).toEqual('../API.ts'); + }); + + test('two dir up', () => { + expect(getRelativeTypesPath('src/graphql', 'API.ts')).toEqual('../../API.ts'); + }); + + test('one dir down', () => { + expect(getRelativeTypesPath('src/graphql', 'src/graphql/types/API.ts')).toEqual('./types/API.ts'); + }); + + test('two dir down', () => { + expect(getRelativeTypesPath('src/graphql', 'src/graphql/types/foo/API.ts')).toEqual('./types/foo/API.ts'); + }); + + test('sibling dirs', () => { + expect(getRelativeTypesPath('src/graphql', 'src/types/API.ts')).toEqual('../types/API.ts'); + }); + + test('no types file', () => { + expect(getRelativeTypesPath('src/graphql', null)).toEqual(null); + }); +});