Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(graphql-model-transformer): fixed input type field generation for enum types #7879

Merged
merged 1 commit into from
Aug 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -368,4 +368,31 @@ describe('ModelTransformer: ', () => {
const commentInputIDField = getFieldOnInputType(commentInputObject!, 'id');
verifyMatchingTypes(commentObjectIDField.type, commentInputIDField.type);
});

it('should support enum as a field', () => {
const validSchema = `
enum Status { DELIVERED IN_TRANSIT PENDING UNKNOWN }
type Test @model {
status: Status!
lastStatus: Status!
}
`;
const transformer = new GraphQLTransform({
transformers: [new ModelTransformer()],
featureFlags,
});

const out = transformer.transform(validSchema);
expect(out).toBeDefined();
const definition = out.schema;
expect(definition).toBeDefined();
const parsed = parse(definition);
validateModelSchema(parsed);

const createTestInput = getInputType(parsed, 'CreateTestInput');
expectFieldsOnInputType(createTestInput!, ['status', 'lastStatus']);

const updateTestInput = getInputType(parsed, 'CreateTestInput');
expectFieldsOnInputType(updateTestInput!, ['status', 'lastStatus']);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -722,10 +722,10 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
const knownModels = this.typesWithModelDirective;
let conditionInput: InputObjectTypeDefinitionNode;
if ([MutationFieldType.CREATE, MutationFieldType.DELETE, MutationFieldType.UPDATE].includes(operation.type as MutationFieldType)) {
const condtionTypeName = toPascalCase(['Model', type.name.value, 'ConditionInput']);
const conditionTypeName = toPascalCase(['Model', type.name.value, 'ConditionInput']);

const filterInputs = createEnumModelFilters(ctx, type);
conditionInput = makeMutationConditionInput(ctx, condtionTypeName, type);
conditionInput = makeMutationConditionInput(ctx, conditionTypeName, type);
filterInputs.push(conditionInput);
for (let input of filterInputs) {
const conditionInputName = input.name.value;
Expand Down Expand Up @@ -756,7 +756,12 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
return [];

case MutationFieldType.CREATE:
const createInputField = makeCreateInputField(type, this.modelDirectiveConfig.get(type.name.value)!, knownModels);
const createInputField = makeCreateInputField(
type,
this.modelDirectiveConfig.get(type.name.value)!,
knownModels,
ctx.inputDocument,
);
const createInputTypeName = createInputField.name.value;
if (!ctx.output.getType(createInputField.name.value)) {
ctx.output.addInput(createInputField);
Expand All @@ -778,7 +783,12 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
];

case MutationFieldType.UPDATE:
const updateInputField = makeUpdateInputField(type, this.modelDirectiveConfig.get(type.name.value)!, knownModels);
const updateInputField = makeUpdateInputField(
type,
this.modelDirectiveConfig.get(type.name.value)!,
knownModels,
ctx.inputDocument,
);
const updateInputTypeName = updateInputField.name.value;
if (!ctx.output.getType(updateInputField.name.value)) {
ctx.output.addInput(updateInputField);
Expand All @@ -795,7 +805,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
break;

default:
throw new Error('Unkown operation type');
throw new Error('Unknown operation type');
}
return [];
};
Expand Down Expand Up @@ -840,7 +850,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
if (def && def.kind == 'ObjectTypeDefinition' && !this.isModelField(def.name.value)) {
const name = this.getNonModelInputObjectName(def.name.value);
if (!ctx.output.getType(name)) {
const inputObj = InputObjectDefinitionWrapper.fromObject(name, def);
const inputObj = InputObjectDefinitionWrapper.fromObject(name, def, ctx.inputDocument);
ctx.output.addInput(inputObj.serialize());
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { TransformerTransformSchemaStepContextProvider } from '@aws-amplify/graphql-transformer-interfaces';
import { ObjectTypeDefinitionNode, InputObjectTypeDefinitionNode } from 'graphql';
import { ObjectTypeDefinitionNode, InputObjectTypeDefinitionNode, DocumentNode } from 'graphql';
import { ModelResourceIDs, toPascalCase } from 'graphql-transformer-common';
import { ModelDirectiveConfiguration } from '../graphql-model-transformer';
import { ObjectDefinitionWrapper, InputObjectDefinitionWrapper, InputFieldWrapper } from '../wrappers/object-definition-wrapper';
Expand All @@ -15,6 +15,7 @@ export const makeUpdateInputField = (
obj: ObjectTypeDefinitionNode,
modelDirectiveConfig: ModelDirectiveConfiguration,
knownModelTypes: Set<string>,
document: DocumentNode,
): InputObjectTypeDefinitionNode => {
// sync related things
const objectWrapped = new ObjectDefinitionWrapper(obj);
Expand All @@ -32,10 +33,12 @@ export const makeUpdateInputField = (
return field.getTypeName();
});

const input = InputObjectDefinitionWrapper.fromObject(name, {
const objectTypeDefinition: ObjectTypeDefinitionNode = {
...obj,
fields: obj.fields?.filter(f => !fieldsToRemove.includes(f.name.value)),
});
};

const input = InputObjectDefinitionWrapper.fromObject(name, objectTypeDefinition, document);

// make all the fields optional
input.fields.forEach(f => f.makeNullable());
Expand Down Expand Up @@ -84,6 +87,7 @@ export const makeCreateInputField = (
obj: ObjectTypeDefinitionNode,
modelDirectiveConfig: ModelDirectiveConfiguration,
knownModelTypes: Set<string>,
document: DocumentNode,
): InputObjectTypeDefinitionNode => {
// sync related things
const objectWrapped = new ObjectDefinitionWrapper(obj);
Expand All @@ -102,10 +106,12 @@ export const makeCreateInputField = (
return field.getTypeName();
});

const input = InputObjectDefinitionWrapper.fromObject(name, {
const objectTypeDefinition: ObjectTypeDefinitionNode = {
...obj,
fields: obj.fields?.filter(f => !fieldsToRemove.includes(f.name.value)),
});
};

const input = InputObjectDefinitionWrapper.fromObject(name, objectTypeDefinition, document);

// Add id field and make it optional
if (!hasIdField) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,17 @@ import {
NamedTypeNode,
EnumTypeDefinitionNode,
Kind,
DocumentNode,
} from 'graphql';
import { DEFAULT_SCALARS, getBaseType, isScalar, ModelResourceIDs, unwrapNonNull, withNamedNodeNamed } from 'graphql-transformer-common';
import {
DEFAULT_SCALARS,
getBaseType,
isEnum,
isScalar,
ModelResourceIDs,
unwrapNonNull,
withNamedNodeNamed,
} from 'graphql-transformer-common';

import { merge } from 'lodash';
// Todo: to be moved to core later. context.output.getObject would return wrapper type so its easier to manipulate
Expand Down Expand Up @@ -181,7 +190,7 @@ export class InputFieldWrapper extends GenericFieldWrapper {
};
};

static fromField = (name: string, field: FieldDefinitionNode): InputFieldWrapper => {
static fromField = (name: string, field: FieldDefinitionNode, document: DocumentNode): InputFieldWrapper => {
const autoGeneratableFieldsWithType: Record<string, string[]> = {
id: ['ID'],
createdAt: ['AWSDateTime', 'String'],
Expand All @@ -199,7 +208,7 @@ export class InputFieldWrapper extends GenericFieldWrapper {
type = unwrapNonNull(field.type);
} else {
type =
isScalar(field.type) || getBaseType(field.type) === Kind.ENUM_TYPE_DEFINITION
isScalar(field.type) || isEnum(field.type, document)
? field.type
: withNamedNodeNamed(field.type, ModelResourceIDs.NonModelInputObjectName(getBaseType(field.type)));
}
Expand Down Expand Up @@ -415,7 +424,7 @@ export class InputObjectDefinitionWrapper {
return wrappedObj;
};

static fromObject = (name: string, def: ObjectTypeDefinitionNode): InputObjectDefinitionWrapper => {
static fromObject = (name: string, def: ObjectTypeDefinitionNode, document: DocumentNode): InputObjectDefinitionWrapper => {
const inputObj: InputObjectTypeDefinitionNode = {
kind: 'InputObjectTypeDefinition',
name: { kind: 'Name', value: name },
Expand All @@ -425,7 +434,7 @@ export class InputObjectDefinitionWrapper {

const wrappedInput = new InputObjectDefinitionWrapper(inputObj);
for (let f of def.fields || []) {
const wrappedField = InputFieldWrapper.fromField(f.name.value, f);
const wrappedField = InputFieldWrapper.fromField(f.name.value, f, document);
wrappedInput.fields.push(wrappedField);
}
return wrappedInput;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ input CreateEmployeeInput {
id: ID
firstName: String!
lastName: String!
type: EmploymentTypeInput!
type: EmploymentType!
}

type Mutation {
Expand All @@ -281,7 +281,7 @@ input UpdateEmployeeInput {
id: ID!
firstName: String
lastName: String
type: EmploymentTypeInput
type: EmploymentType
}

input DeleteEmployeeInput {
Expand Down
8 changes: 0 additions & 8 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -9892,14 +9892,6 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1:
ansi-styles "^4.1.0"
supports-color "^7.1.0"

chalk@^4.1.1:
version "4.1.1"
resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad"
integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==
dependencies:
ansi-styles "^4.1.0"
supports-color "^7.1.0"

change-case@3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/change-case/-/change-case-3.1.0.tgz#0e611b7edc9952df2e8513b27b42de72647dd17e"
Expand Down