From 48b10f1236889b0cbd93a242ef339dadccd4cc84 Mon Sep 17 00:00:00 2001 From: Dane Pilcher Date: Wed, 2 Feb 2022 15:33:11 +0000 Subject: [PATCH] feat: add null type union to optional fields --- .../appsync-javascript-visitor.test.ts | 48 +++---- .../appsync-javascript-visitor.test.ts.snap | 122 +++++++++--------- .../visitors/appsync-typescript-visitor.ts | 6 +- 3 files changed, 90 insertions(+), 86 deletions(-) diff --git a/packages/appsync-modelgen-plugin/src/__tests__/visitors/appsync-javascript-visitor.test.ts b/packages/appsync-modelgen-plugin/src/__tests__/visitors/appsync-javascript-visitor.test.ts index 0a6e66a77..8813852d4 100644 --- a/packages/appsync-modelgen-plugin/src/__tests__/visitors/appsync-javascript-visitor.test.ts +++ b/packages/appsync-modelgen-plugin/src/__tests__/visitors/appsync-javascript-visitor.test.ts @@ -109,22 +109,22 @@ describe('Javascript visitor', () => { export declare class SimpleNonModelType { readonly id: string; - readonly names?: (string | null)[]; + readonly names?: (string | null)[] | null; constructor(init: ModelInit); } export declare class SimpleModel { readonly id: string; - readonly name?: string; - readonly bar?: string; - readonly foo?: Bar[]; + readonly name?: string | null; + readonly bar?: string | null; + readonly foo?: Bar[] | null; constructor(init: ModelInit); static copyOf(source: SimpleModel, mutator: (draft: MutableModel) => MutableModel | void): SimpleModel; } export declare class Bar { readonly id: string; - readonly simpleModelFooId?: string; + readonly simpleModelFooId?: string | null; constructor(init: ModelInit); static copyOf(source: Bar, mutator: (draft: MutableModel) => MutableModel | void): Bar; }" @@ -158,7 +158,7 @@ describe('Javascript visitor', () => { export declare class SimpleNonModelType { readonly id: string; - readonly names?: (string | null)[]; + readonly names?: (string | null)[] | null; constructor(init: ModelInit); } @@ -172,20 +172,20 @@ describe('Javascript visitor', () => { export declare class SimpleModel { readonly id: string; - readonly name?: string; - readonly bar?: string; - readonly foo?: Bar[]; - readonly createdAt?: string; - readonly updatedAt?: string; + readonly name?: string | null; + readonly bar?: string | null; + readonly foo?: Bar[] | null; + readonly createdAt?: string | null; + readonly updatedAt?: string | null; constructor(init: ModelInit); static copyOf(source: SimpleModel, mutator: (draft: MutableModel) => MutableModel | void): SimpleModel; } export declare class Bar { readonly id: string; - readonly createdAt?: string; - readonly updatedAt?: string; - readonly simpleModelFooId?: string; + readonly createdAt?: string | null; + readonly updatedAt?: string | null; + readonly simpleModelFooId?: string | null; constructor(init: ModelInit); static copyOf(source: Bar, mutator: (draft: MutableModel) => MutableModel | void): Bar; }" @@ -290,14 +290,14 @@ describe('Javascript visitor with default owner auth', () => { export declare class SimpleNonModelType { readonly id: string; - readonly names?: (string | null)[]; + readonly names?: (string | null)[] | null; constructor(init: ModelInit); } export declare class SimpleModel { readonly id: string; - readonly name?: string; - readonly bar?: string; + readonly name?: string | null; + readonly bar?: string | null; constructor(init: ModelInit); static copyOf(source: SimpleModel, mutator: (draft: MutableModel) => MutableModel | void): SimpleModel; }" @@ -359,14 +359,14 @@ describe('Javascript visitor with custom owner field auth', () => { export declare class SimpleNonModelType { readonly id: string; - readonly names?: (string | null)[]; + readonly names?: (string | null)[] | null; constructor(init: ModelInit); } export declare class SimpleModel { readonly id: string; - readonly name?: string; - readonly bar?: string; + readonly name?: string | null; + readonly bar?: string | null; constructor(init: ModelInit); static copyOf(source: SimpleModel, mutator: (draft: MutableModel) => MutableModel | void): SimpleModel; }" @@ -430,14 +430,14 @@ describe('Javascript visitor with multiple owner field auth', () => { export declare class SimpleNonModelType { readonly id: string; - readonly names?: (string | null)[]; + readonly names?: (string | null)[] | null; constructor(init: ModelInit); } export declare class SimpleModel { readonly id: string; - readonly name?: string; - readonly bar?: string; + readonly name?: string | null; + readonly bar?: string | null; constructor(init: ModelInit); static copyOf(source: SimpleModel, mutator: (draft: MutableModel) => MutableModel | void): SimpleModel; }" @@ -492,7 +492,7 @@ describe('Javascript visitor with auth directives in field level', () => { readonly id: string; readonly name: string; readonly address: string; - readonly ssn?: string; + readonly ssn?: string | null; constructor(init: ModelInit); static copyOf(source: Employee, mutator: (draft: MutableModel) => MutableModel | void): Employee; }" diff --git a/packages/appsync-modelgen-plugin/src/__tests__/visitors/gqlv2-regression-tests/__snapshots__/appsync-javascript-visitor.test.ts.snap b/packages/appsync-modelgen-plugin/src/__tests__/visitors/gqlv2-regression-tests/__snapshots__/appsync-javascript-visitor.test.ts.snap index 0644f1125..2803af006 100644 --- a/packages/appsync-modelgen-plugin/src/__tests__/visitors/gqlv2-regression-tests/__snapshots__/appsync-javascript-visitor.test.ts.snap +++ b/packages/appsync-modelgen-plugin/src/__tests__/visitors/gqlv2-regression-tests/__snapshots__/appsync-javascript-visitor.test.ts.snap @@ -25,7 +25,7 @@ exports[`AppSyncJavascriptVisitor - GQLv2 Regression Tests Works on explicit has export declare class Post { readonly id: string; readonly title: string; - readonly comments?: (Comment | null)[]; + readonly comments?: (Comment | null)[] | null; constructor(init: ModelInit); static copyOf(source: Post, mutator: (draft: MutableModel) => MutableModel | void): Post; } @@ -33,7 +33,7 @@ export declare class Post { export declare class Comment { readonly id: string; readonly content: string; - readonly post?: Post; + readonly post?: Post | null; constructor(init: ModelInit); static copyOf(source: Comment, mutator: (draft: MutableModel) => MutableModel | void): Comment; }" @@ -64,7 +64,7 @@ exports[`AppSyncJavascriptVisitor - GQLv2 Regression Tests Works on explicit has export declare class Post { readonly id: string; readonly title: string; - readonly comments?: (Comment | null)[]; + readonly comments?: (Comment | null)[] | null; constructor(init: ModelInit); static copyOf(source: Post, mutator: (draft: MutableModel) => MutableModel | void): Post; } @@ -72,7 +72,7 @@ export declare class Post { export declare class Comment { readonly id: string; readonly content: string; - readonly post?: Post; + readonly post?: Post | null; constructor(init: ModelInit); static copyOf(source: Comment, mutator: (draft: MutableModel) => MutableModel | void): Comment; }" @@ -102,9 +102,9 @@ exports[`AppSyncJavascriptVisitor - GQLv2 Regression Tests Works on explicit has export declare class Project2 { readonly id: string; - readonly name?: string; - readonly team?: Team2; - readonly project2TeamId?: string; + readonly name?: string | null; + readonly team?: Team2 | null; + readonly project2TeamId?: string | null; constructor(init: ModelInit); static copyOf(source: Project2, mutator: (draft: MutableModel) => MutableModel | void): Project2; } @@ -112,7 +112,7 @@ export declare class Project2 { export declare class Team2 { readonly id: string; readonly name: string; - readonly project?: Project2; + readonly project?: Project2 | null; constructor(init: ModelInit); static copyOf(source: Team2, mutator: (draft: MutableModel) => MutableModel | void): Team2; }" @@ -142,9 +142,9 @@ exports[`AppSyncJavascriptVisitor - GQLv2 Regression Tests Works on explicit has export declare class Project2 { readonly id: string; - readonly name?: string; - readonly team?: Team2; - readonly project2TeamId?: string; + readonly name?: string | null; + readonly team?: Team2 | null; + readonly project2TeamId?: string | null; constructor(init: ModelInit); static copyOf(source: Project2, mutator: (draft: MutableModel) => MutableModel | void): Project2; } @@ -152,7 +152,7 @@ export declare class Project2 { export declare class Team2 { readonly id: string; readonly name: string; - readonly project?: Project2; + readonly project?: Project2 | null; constructor(init: ModelInit); static copyOf(source: Team2, mutator: (draft: MutableModel) => MutableModel | void): Team2; }" @@ -184,7 +184,7 @@ exports[`AppSyncJavascriptVisitor - GQLv2 Regression Tests Works on implicit has export declare class Blog7V2 { readonly id: string; readonly name: string; - readonly posts?: (Post7V2 | null)[]; + readonly posts?: (Post7V2 | null)[] | null; constructor(init: ModelInit); static copyOf(source: Blog7V2, mutator: (draft: MutableModel) => MutableModel | void): Blog7V2; } @@ -192,16 +192,16 @@ export declare class Blog7V2 { export declare class Post7V2 { readonly id: string; readonly title: string; - readonly blog?: Blog7V2; - readonly comments?: (Comment7V2 | null)[]; + readonly blog?: Blog7V2 | null; + readonly comments?: (Comment7V2 | null)[] | null; constructor(init: ModelInit); static copyOf(source: Post7V2, mutator: (draft: MutableModel) => MutableModel | void): Post7V2; } export declare class Comment7V2 { readonly id: string; - readonly content?: string; - readonly post?: Post7V2; + readonly content?: string | null; + readonly post?: Post7V2 | null; constructor(init: ModelInit); static copyOf(source: Comment7V2, mutator: (draft: MutableModel) => MutableModel | void): Comment7V2; }" @@ -233,7 +233,7 @@ exports[`AppSyncJavascriptVisitor - GQLv2 Regression Tests Works on implicit has export declare class Blog7V2 { readonly id: string; readonly name: string; - readonly posts?: (Post7V2 | null)[]; + readonly posts?: (Post7V2 | null)[] | null; constructor(init: ModelInit); static copyOf(source: Blog7V2, mutator: (draft: MutableModel) => MutableModel | void): Blog7V2; } @@ -241,16 +241,16 @@ export declare class Blog7V2 { export declare class Post7V2 { readonly id: string; readonly title: string; - readonly blog?: Blog7V2; - readonly comments?: (Comment7V2 | null)[]; + readonly blog?: Blog7V2 | null; + readonly comments?: (Comment7V2 | null)[] | null; constructor(init: ModelInit); static copyOf(source: Post7V2, mutator: (draft: MutableModel) => MutableModel | void): Post7V2; } export declare class Comment7V2 { readonly id: string; - readonly content?: string; - readonly post?: Post7V2; + readonly content?: string | null; + readonly post?: Post7V2 | null; constructor(init: ModelInit); static copyOf(source: Comment7V2, mutator: (draft: MutableModel) => MutableModel | void): Comment7V2; }" @@ -282,7 +282,7 @@ exports[`AppSyncJavascriptVisitor - GQLv2 Regression Tests Works on implicit has export declare class Blog7V2 { readonly id: string; readonly name: string; - readonly posts?: (Post7V2 | null)[]; + readonly posts?: (Post7V2 | null)[] | null; constructor(init: ModelInit); static copyOf(source: Blog7V2, mutator: (draft: MutableModel) => MutableModel | void): Blog7V2; } @@ -290,16 +290,16 @@ export declare class Blog7V2 { export declare class Post7V2 { readonly id: string; readonly title: string; - readonly blog?: Blog7V2; - readonly comments?: (Comment7V2 | null)[]; + readonly blog?: Blog7V2 | null; + readonly comments?: (Comment7V2 | null)[] | null; constructor(init: ModelInit); static copyOf(source: Post7V2, mutator: (draft: MutableModel) => MutableModel | void): Post7V2; } export declare class Comment7V2 { readonly id: string; - readonly content?: string; - readonly post?: Post7V2; + readonly content?: string | null; + readonly post?: Post7V2 | null; constructor(init: ModelInit); static copyOf(source: Comment7V2, mutator: (draft: MutableModel) => MutableModel | void): Comment7V2; }" @@ -329,9 +329,9 @@ exports[`AppSyncJavascriptVisitor - GQLv2 Regression Tests Works on implicit has export declare class Project { readonly id: string; - readonly name?: string; - readonly team?: Team; - readonly projectTeamId?: string; + readonly name?: string | null; + readonly team?: Team | null; + readonly projectTeamId?: string | null; constructor(init: ModelInit); static copyOf(source: Project, mutator: (draft: MutableModel) => MutableModel | void): Project; } @@ -339,7 +339,7 @@ export declare class Project { export declare class Team { readonly id: string; readonly name: string; - readonly project?: Project; + readonly project?: Project | null; constructor(init: ModelInit); static copyOf(source: Team, mutator: (draft: MutableModel) => MutableModel | void): Team; }" @@ -369,9 +369,9 @@ exports[`AppSyncJavascriptVisitor - GQLv2 Regression Tests Works on implicit has export declare class Project { readonly id: string; - readonly name?: string; - readonly team?: Team; - readonly projectTeamId?: string; + readonly name?: string | null; + readonly team?: Team | null; + readonly projectTeamId?: string | null; constructor(init: ModelInit); static copyOf(source: Project, mutator: (draft: MutableModel) => MutableModel | void): Project; } @@ -379,7 +379,7 @@ export declare class Project { export declare class Team { readonly id: string; readonly name: string; - readonly project?: Project; + readonly project?: Project | null; constructor(init: ModelInit); static copyOf(source: Team, mutator: (draft: MutableModel) => MutableModel | void): Team; }" @@ -411,8 +411,8 @@ exports[`AppSyncJavascriptVisitor - GQLv2 Regression Tests Works on many to many export declare class Post { readonly id: string; readonly title: string; - readonly content?: string; - readonly tags?: (PostTags | null)[]; + readonly content?: string | null; + readonly tags?: (PostTags | null)[] | null; constructor(init: ModelInit); static copyOf(source: Post, mutator: (draft: MutableModel) => MutableModel | void): Post; } @@ -420,7 +420,7 @@ export declare class Post { export declare class Tag { readonly id: string; readonly label: string; - readonly posts?: (PostTags | null)[]; + readonly posts?: (PostTags | null)[] | null; constructor(init: ModelInit); static copyOf(source: Tag, mutator: (draft: MutableModel) => MutableModel | void): Tag; } @@ -460,8 +460,8 @@ exports[`AppSyncJavascriptVisitor - GQLv2 Regression Tests Works on many to many export declare class Post { readonly id: string; readonly title: string; - readonly content?: string; - readonly tags?: (PostTags | null)[]; + readonly content?: string | null; + readonly tags?: (PostTags | null)[] | null; constructor(init: ModelInit); static copyOf(source: Post, mutator: (draft: MutableModel) => MutableModel | void): Post; } @@ -469,7 +469,7 @@ export declare class Post { export declare class Tag { readonly id: string; readonly label: string; - readonly posts?: (PostTags | null)[]; + readonly posts?: (PostTags | null)[] | null; constructor(init: ModelInit); static copyOf(source: Tag, mutator: (draft: MutableModel) => MutableModel | void): Tag; } @@ -506,7 +506,7 @@ exports[`AppSyncJavascriptVisitor - GQLv2 Regression Tests Works on record creat export declare class Todo { readonly id: string; - readonly content?: string; + readonly content?: string | null; constructor(init: ModelInit); static copyOf(source: Todo, mutator: (draft: MutableModel) => MutableModel | void): Todo; }" @@ -537,7 +537,7 @@ exports[`AppSyncJavascriptVisitor - GQLv2 Regression Tests Works on uni-directio export declare class Post2 { readonly id: string; readonly title: string; - readonly comments?: (Comment2 | null)[]; + readonly comments?: (Comment2 | null)[] | null; constructor(init: ModelInit); static copyOf(source: Post2, mutator: (draft: MutableModel) => MutableModel | void): Post2; } @@ -576,7 +576,7 @@ exports[`AppSyncJavascriptVisitor - GQLv2 Regression Tests Works on uni-directio export declare class Post2 { readonly id: string; readonly title: string; - readonly comments?: (Comment2 | null)[]; + readonly comments?: (Comment2 | null)[] | null; constructor(init: ModelInit); static copyOf(source: Post2, mutator: (draft: MutableModel) => MutableModel | void): Post2; } @@ -614,9 +614,9 @@ exports[`AppSyncJavascriptVisitor - GQLv2 Regression Tests Works on uni-directio export declare class Project2 { readonly id: string; - readonly name?: string; - readonly teamID?: string; - readonly team?: Team2; + readonly name?: string | null; + readonly teamID?: string | null; + readonly team?: Team2 | null; constructor(init: ModelInit); static copyOf(source: Project2, mutator: (draft: MutableModel) => MutableModel | void): Project2; } @@ -653,9 +653,9 @@ exports[`AppSyncJavascriptVisitor - GQLv2 Regression Tests Works on uni-directio export declare class Project2 { readonly id: string; - readonly name?: string; - readonly teamID?: string; - readonly team?: Team2; + readonly name?: string | null; + readonly teamID?: string | null; + readonly team?: Team2 | null; constructor(init: ModelInit); static copyOf(source: Project2, mutator: (draft: MutableModel) => MutableModel | void): Project2; } @@ -693,7 +693,7 @@ exports[`AppSyncJavascriptVisitor - GQLv2 Regression Tests Works on uni-directio export declare class Post { readonly id: string; readonly title: string; - readonly comments?: (Comment | null)[]; + readonly comments?: (Comment | null)[] | null; constructor(init: ModelInit); static copyOf(source: Post, mutator: (draft: MutableModel) => MutableModel | void): Post; } @@ -701,7 +701,7 @@ export declare class Post { export declare class Comment { readonly id: string; readonly content: string; - readonly postCommentsId?: string; + readonly postCommentsId?: string | null; constructor(init: ModelInit); static copyOf(source: Comment, mutator: (draft: MutableModel) => MutableModel | void): Comment; }" @@ -732,7 +732,7 @@ exports[`AppSyncJavascriptVisitor - GQLv2 Regression Tests Works on uni-directio export declare class Post { readonly id: string; readonly title: string; - readonly comments?: (Comment | null)[]; + readonly comments?: (Comment | null)[] | null; constructor(init: ModelInit); static copyOf(source: Post, mutator: (draft: MutableModel) => MutableModel | void): Post; } @@ -740,7 +740,7 @@ export declare class Post { export declare class Comment { readonly id: string; readonly content: string; - readonly postCommentsId?: string; + readonly postCommentsId?: string | null; constructor(init: ModelInit); static copyOf(source: Comment, mutator: (draft: MutableModel) => MutableModel | void): Comment; }" @@ -770,9 +770,9 @@ exports[`AppSyncJavascriptVisitor - GQLv2 Regression Tests Works on uni-directio export declare class Project { readonly id: string; - readonly name?: string; - readonly team?: Team; - readonly projectTeamId?: string; + readonly name?: string | null; + readonly team?: Team | null; + readonly projectTeamId?: string | null; constructor(init: ModelInit); static copyOf(source: Project, mutator: (draft: MutableModel) => MutableModel | void): Project; } @@ -809,9 +809,9 @@ exports[`AppSyncJavascriptVisitor - GQLv2 Regression Tests Works on uni-directio export declare class Project { readonly id: string; - readonly name?: string; - readonly team?: Team; - readonly projectTeamId?: string; + readonly name?: string | null; + readonly team?: Team | null; + readonly projectTeamId?: string | null; constructor(init: ModelInit); static copyOf(source: Project, mutator: (draft: MutableModel) => MutableModel | void): Project; } @@ -848,7 +848,7 @@ exports[`AppSyncJavascriptVisitor - GQLv2 Regression Tests Works when configurin export declare class Customer { readonly id: string; readonly name: string; - readonly phoneNumber?: string; + readonly phoneNumber?: string | null; readonly accountRepresentativeID: string; constructor(init: ModelInit); static copyOf(source: Customer, mutator: (draft: MutableModel) => MutableModel | void): Customer; diff --git a/packages/appsync-modelgen-plugin/src/visitors/appsync-typescript-visitor.ts b/packages/appsync-modelgen-plugin/src/visitors/appsync-typescript-visitor.ts index b9c8e8bce..d0e14ba14 100644 --- a/packages/appsync-modelgen-plugin/src/visitors/appsync-typescript-visitor.ts +++ b/packages/appsync-modelgen-plugin/src/visitors/appsync-typescript-visitor.ts @@ -246,10 +246,12 @@ export class AppSyncModelTypeScriptVisitor< protected getNativeType(field: CodeGenField): string { const typeName = field.type; + const isNullable = field.isList ? field.isListNullable : field.isNullable; + const nullableTypeUnion = isNullable ? ' | null' : ''; if (this.isModelType(field)) { const modelType = this.modelMap[typeName]; const typeNameStr = this.generateModelTypeDeclarationName(modelType); - return field.isList ? this.getListType(typeNameStr, field) : typeNameStr; + return (field.isList ? this.getListType(typeNameStr, field) : typeNameStr) + nullableTypeUnion; } let nativeType = super.getNativeType(field); @@ -258,6 +260,8 @@ export class AppSyncModelTypeScriptVisitor< nativeType = `${nativeType} | keyof typeof ${this.getEnumName(this.enumMap[typeName])}`; } + nativeType = nativeType + nullableTypeUnion; + return nativeType; } }