Skip to content

Commit

Permalink
made types path computed from config
Browse files Browse the repository at this point in the history
  • Loading branch information
svidgen committed Jul 13, 2023
1 parent 1c37267 commit 4d03b46
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 39 deletions.
11 changes: 7 additions & 4 deletions packages/amplify-codegen/src/commands/statements.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,15 @@ async function generateStatements(context, forceDownloadSchema, maxDepth, withou
// default typenameIntrospection to true when not set
typenameIntrospection:
cfg.amplifyExtension.typenameIntrospection === undefined ? true : !!cfg.amplifyExtension.typenameIntrospection,
includeMetaData: true
includeMetaData: true,
});
if (!generatedOps) {
context.print.warning('No GraphQL statements are generated. Check if the introspection schema has GraphQL operations defined.');
} else {
await writeGeneratedDocuments(language, generatedOps, opsGenDirectory);
const relativeTypesPath = cfg.amplifyExtension.generatedFileName
? path.relative(opsGenDirectory, cfg.amplifyExtension.generatedFileName)
: null;
await writeGeneratedDocuments(language, generatedOps, opsGenDirectory, relativeTypesPath);
opsGenSpinner.succeed(constants.INFO_MESSAGE_OPS_GEN_SUCCESS + path.relative(path.resolve('.'), opsGenDirectory));
}
} finally {
Expand All @@ -86,13 +89,13 @@ async function generateStatements(context, forceDownloadSchema, maxDepth, withou
}
}

async function writeGeneratedDocuments(language, generatedStatements, outputPath) {
async function writeGeneratedDocuments(language, generatedStatements, outputPath, relativeTypesPath) {
const fileExtension = FILE_EXTENSION_MAP[language];

['queries', 'mutations', 'subscriptions'].forEach(op => {
const ops = generatedStatements[op];
if (ops && ops.size) {
const formattedStatements = new GraphQLStatementsFormatter(language, op).format(ops);
const formattedStatements = new GraphQLStatementsFormatter(language, op, relativeTypesPath).format(ops);
const outputFile = path.resolve(path.join(outputPath, `${op}.${fileExtension}`));
fs.writeFileSync(outputFile, formattedStatements);
}
Expand Down
21 changes: 7 additions & 14 deletions packages/amplify-codegen/src/utils/GraphQLStatementsFormatter.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const prettier = require('prettier');
const {
interfaceNameFromOperation,
interfaceVariablesNameFromOperation
interfaceVariablesNameFromOperation,
} = require('@aws-amplify/graphql-types-generator/lib/typescript/codeGeneration');

const CODEGEN_WARNING = 'this is an auto generated file. This will be overwritten';
Expand All @@ -11,7 +11,7 @@ const LINE_DELIMITOR = '\n';
* Utility class to format the generated GraphQL statements based on frontend language type
*/
class GraphQLStatementsFormatter {
constructor(language, op) {
constructor(language, op, typesPath) {
this.language = language || 'graphql';
this.opTypeName = {
queries: 'Query',
Expand All @@ -20,12 +20,13 @@ class GraphQLStatementsFormatter {
}[op];
this.lintOverrides = [];
this.headerComments = [];
this.typesPath = typesPath ? typesPath.replace(/.ts/i, '') : null;
}

get typeDefs() {
if (this.language === 'typescript' && this.opTypeName) {
if (this.language === 'typescript' && this.opTypeName && this.typesPath) {
return [
`import * as APITypes from '../API';`,
`import * as APITypes from '${this.typesPath}';`,
`type Generated${this.opTypeName}<InputType, OutputType> = string & {`,
` __generated${this.opTypeName}Input: InputType;`,
` __generated${this.opTypeName}Output: OutputType;`,
Expand Down Expand Up @@ -66,8 +67,7 @@ class GraphQLStatementsFormatter {
const headerBuffer = this.headerComments.map(comment => `// ${comment}`).join(LINE_DELIMITOR);
const formattedStatements = [];
if (statements) {
console.log('STATEMENTS', { statements });
for (const [key, {graphql, operationName, operationType}] of statements) {
for (const [key, { graphql, operationName, operationType }] of statements) {
const typeTag = this.buildTypeTag(operationName, operationType);
formattedStatements.push(`export const ${key} = /* GraphQL */ \`${graphql}\`${typeTag}`);
}
Expand All @@ -79,23 +79,16 @@ class GraphQLStatementsFormatter {
}

buildTypeTag(operationName, operationType) {
if (this.language !== 'typescript') return '';
if (!operationType) return '';
if (!operationType || !this.typesPath || this.language !== 'typescript') return '';

// const titleCasedName = `${name[0].toUpperCase()}${name.slice(1)}`;

const resultTypeName = `APITypes.${interfaceNameFromOperation({
operationName,
operationType,
// operationName: titleCasedName,
// operationType: this.opTypeName,
})}`;

const variablesTypeName = `APITypes.${interfaceVariablesNameFromOperation({
operationName,
operationType,
// operationName: titleCasedName,
// operationType: this.opTypeName,
})}`;

return ` as Generated${this.opTypeName}<
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,20 @@ describe('GraphQL statements Formatter', () => {
}
`;

statements.set(
'getProject',
{
graphql,
operationName: 'GetProject',
operationType: 'query',
fieldName: 'getProject'
},
);
statements.set('getProject', {
graphql,
operationName: 'GetProject',
operationType: 'query',
fieldName: 'getProject',
});

it('Generates formatted output for JS frontend', () => {
const formattedOutput = new GraphQLStatementsFormatter('javascript').format(statements);
expect(formattedOutput).toMatchSnapshot();
});

it('Generates formatted output for TS frontend', () => {
console.log({ statements });
const formattedOutput = new GraphQLStatementsFormatter('typescript', 'queries').format(statements);
const formattedOutput = new GraphQLStatementsFormatter('typescript', 'queries', '../API.ts').format(statements);
expect(formattedOutput).toMatchSnapshot();
});

Expand Down
21 changes: 11 additions & 10 deletions packages/graphql-docs-generator/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export function generateGraphQLDocuments<INCLUDE_META extends boolean>(

['queries', 'mutations', 'subscriptions'].forEach(op => {
const ops = gqlOperations[op];
console.log({ ops });
// console.log({ ops });
if (ops.length) {
const renderedOperations = renderOperations(gqlOperations[op], options.includeMetaData);
allOperations[op] = renderedOperations;
Expand All @@ -61,26 +61,26 @@ type GraphQLWithMeta = {

/**
* E.g., `GetMyModel` or `ListMyModels`.
*
*
* This is used for generating type names.
*
*
* `undefined` for fragments.
*/
operationName: string | undefined;

/**
* `undefined` for fragments.
*/
operationType: "query" | "mutation" | "subscription" | undefined;
operationType: 'query' | 'mutation' | 'subscription' | undefined;

/**
* E.g., `getMyModel` or `listMyModels`.
*
*
* It's the name of the operation that lives under Queries, Mutations, or Subscriptions
* in the schema and is generally used as the key + variable name referring to the query.
*/
fieldName: string;
}
};

type GeneratedOperations<T> = {
queries: Map<string, T>;
Expand All @@ -91,9 +91,10 @@ type GeneratedOperations<T> = {

type MapValueType<INCLUDE_META extends boolean> = INCLUDE_META extends true ? GraphQLWithMeta : string;

function renderOperations<
INCLUDE_META extends boolean,
>(operations: Array<GQLTemplateOp>, includeMetaData: INCLUDE_META): Map<string, MapValueType<INCLUDE_META>> {
function renderOperations<INCLUDE_META extends boolean>(
operations: Array<GQLTemplateOp>,
includeMetaData: INCLUDE_META,
): Map<string, MapValueType<INCLUDE_META>> {
const renderedOperations = new Map<string, MapValueType<INCLUDE_META>>();
if (operations?.length) {
operations.forEach(op => {
Expand All @@ -104,7 +105,7 @@ function renderOperations<
graphql: gql,
operationName: op.name,
operationType: op.type,
fieldName: op.fieldName
fieldName: op.fieldName,
} as any);
} else {
renderedOperations.set(name, gql as any);
Expand Down

0 comments on commit 4d03b46

Please sign in to comment.