Skip to content

Commit

Permalink
fix: generate multiple swift files in graphql-generator (#718)
Browse files Browse the repository at this point in the history
  • Loading branch information
dpilch authored Sep 26, 2023
1 parent e33eb4a commit 1e484af
Show file tree
Hide file tree
Showing 9 changed files with 306 additions and 716 deletions.
49 changes: 21 additions & 28 deletions packages/amplify-codegen/src/commands/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ const path = require('path');
const fs = require('fs-extra');
const Ora = require('ora');
const glob = require('glob-all');
const { Source } = require('graphql');

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 { generate, extractDocumentFromJavascript } = require('@aws-amplify/graphql-types-generator');
const { extractDocumentFromJavascript } = require('@aws-amplify/graphql-types-generator');

async function generateTypes(context, forceDownloadSchema, withoutInit = false, decoupleFrontend = '') {
let frontend = decoupleFrontend;
Expand Down Expand Up @@ -61,7 +62,7 @@ async function generateTypes(context, forceDownloadSchema, withoutInit = false,
cwd: projectPath,
absolute: true,
});
const queryFiles = queryFilePaths.map(queryFilePath => {
const queries = queryFilePaths.map(queryFilePath => {
const fileContents = fs.readFileSync(queryFilePath, 'utf8');
if (
queryFilePath.endsWith('.jsx') ||
Expand All @@ -71,12 +72,11 @@ async function generateTypes(context, forceDownloadSchema, withoutInit = false,
) {
return extractDocumentFromJavascript(fileContents, '');
}
return fileContents;
return new Source(fileContents, queryFilePath);
});
if (queryFiles.length === 0) {
if (queries.length === 0) {
throw new Error("No queries found to generate types for, you may need to run 'codegen statements' first");
}
const queries = queryFiles.join('\n');

const schemaPath = path.join(projectPath, cfg.schema);

Expand All @@ -93,32 +93,25 @@ async function generateTypes(context, forceDownloadSchema, withoutInit = false,
codeGenSpinner.start();
const schema = fs.readFileSync(schemaPath, 'utf8');
const introspection = path.extname(schemaPath) === '.json';

const multipleSwiftFiles = target === 'swift' && fs.existsSync(outputPath) && fs.statSync(outputPath).isDirectory();
try {
if (target === 'swift' && fs.existsSync(outputPath) && fs.statSync(outputPath).isDirectory()) {
generate(queryFilePaths, schemaPath, outputPath, '', target, '', {
addTypename: true,
complexObjectSupport: 'auto',
});
const output = await generateTypesHelper({
schema,
queries,
target,
introspection,
multipleSwiftFiles,
});
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 {
const output = await generateTypesHelper({
schema,
queries,
target,
introspection,
multipleSwiftFiles: false,
outputs.forEach(([filepath, contents]) => {
fs.outputFileSync(path.resolve(path.join(outputPath, filepath)), contents);
});
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) {
Expand Down
21 changes: 8 additions & 13 deletions packages/amplify-codegen/tests/commands/types.test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
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 { Source } = require('graphql');

const { loadConfig } = require('../../src/codegen-config');
const generateTypes = require('../../src/commands/types');
Expand Down Expand Up @@ -60,6 +60,9 @@ describe('command - types', () => {
beforeEach(() => {
jest.clearAllMocks();
fs.existsSync.mockReturnValue(true);
fs.statSync.mockReturnValue({
isDirectory: jest.fn().mockReturnValue(false),
});
getFrontEndHandler.mockReturnValue('javascript');
loadConfig.mockReturnValue({
getProjects: jest.fn().mockReturnValue([MOCK_PROJECT]),
Expand All @@ -79,15 +82,15 @@ describe('command - types', () => {
expect(loadConfig).toHaveBeenCalledWith(MOCK_CONTEXT, false);
expect(sync).toHaveBeenCalledWith([MOCK_INCLUDE_PATH, `!${MOCK_EXCLUDE_PATH}`], { cwd: MOCK_PROJECT_ROOT, absolute: true });
expect(generateTypesHelper).toHaveBeenCalledWith({
queries: 'query 1\nquery 2',
queries: [new Source('query 1', 'q1.gql'), new Source('query 2', 'q2.gql')],
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 () => {
it('should use generate multiple swift files', async () => {
MOCK_PROJECT.amplifyExtension.codeGenTarget = 'swift';
MOCK_PROJECT.amplifyExtension.generatedFileName = 'typesDirectory';
const forceDownload = false;
Expand All @@ -100,16 +103,6 @@ describe('command - types', () => {
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 () => {
Expand All @@ -121,6 +114,7 @@ describe('command - types', () => {

it('should download the schema if forceDownload flag is passed', async () => {
const forceDownload = true;
fs.readFileSync.mockReturnValueOnce('query 1').mockReturnValueOnce('query 2');
await generateTypes(MOCK_CONTEXT, forceDownload);
expect(ensureIntrospectionSchema).toHaveBeenCalledWith(
MOCK_CONTEXT,
Expand All @@ -134,6 +128,7 @@ describe('command - types', () => {
it('should download the schema if the schema file is missing', async () => {
fs.existsSync.mockReturnValue(false);
const forceDownload = false;
fs.readFileSync.mockReturnValueOnce('query 1').mockReturnValueOnce('query 2');
await generateTypes(MOCK_CONTEXT, forceDownload);
expect(ensureIntrospectionSchema).toHaveBeenCalledWith(
MOCK_CONTEXT,
Expand Down
3 changes: 2 additions & 1 deletion packages/graphql-generator/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
```ts

import { Source } from 'graphql';
import { Target } from '@aws-amplify/appsync-modelgen-plugin';
import { Target as Target_2 } from '@aws-amplify/graphql-types-generator';

Expand Down Expand Up @@ -49,7 +50,7 @@ export function generateTypes(options: GenerateTypesOptions): Promise<GeneratedO
export type GenerateTypesOptions = {
schema: string;
target: TypesTarget;
queries: string;
queries: string | Source[];
introspection?: boolean;
multipleSwiftFiles?: boolean;
};
Expand Down
Loading

0 comments on commit 1e484af

Please sign in to comment.