diff --git a/packages/appsync-modelgen-plugin/src/__tests__/visitors/__snapshots__/appsync-dart-visitor.test.ts.snap b/packages/appsync-modelgen-plugin/src/__tests__/visitors/__snapshots__/appsync-dart-visitor.test.ts.snap index b10075580..71743517c 100644 --- a/packages/appsync-modelgen-plugin/src/__tests__/visitors/__snapshots__/appsync-dart-visitor.test.ts.snap +++ b/packages/appsync-modelgen-plugin/src/__tests__/visitors/__snapshots__/appsync-dart-visitor.test.ts.snap @@ -2979,6 +2979,225 @@ class _TestModelModelType extends ModelType { " `; +exports[`AppSync Dart Visitor Granular read operation test should generate correct model file for GraphQL schema with granular read operation 1`] = ` +"/* +* Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. +* +* Licensed under the Apache License, Version 2.0 (the \\"License\\"). +* You may not use this file except in compliance with the License. +* A copy of the License is located at +* +* http://aws.amazon.com/apache2.0 +* +* or in the \\"license\\" file accompanying this file. This file is distributed +* on an \\"AS IS\\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +* express or implied. See the License for the specific language governing +* permissions and limitations under the License. +*/ + +// NOTE: This file is generated and may not follow lint rules defined in your app +// Generated files can be excluded from analysis in analysis_options.yaml +// For more info, see: https://dart.dev/guides/language/analysis-options#excluding-code-from-analysis + +// ignore_for_file: public_member_api_docs, annotate_overrides, dead_code, dead_codepublic_member_api_docs, depend_on_referenced_packages, file_names, library_private_types_in_public_api, no_leading_underscores_for_library_prefixes, no_leading_underscores_for_local_identifiers, non_constant_identifier_names, null_check_on_nullable_type_parameter, prefer_adjacent_string_concatenation, prefer_const_constructors, prefer_if_null_operators, prefer_interpolation_to_compose_strings, slash_for_doc_comments, sort_child_properties_last, unnecessary_const, unnecessary_constructor_name, unnecessary_late, unnecessary_new, unnecessary_null_aware_assignments, unnecessary_nullable_for_final_variable_declarations, unnecessary_string_interpolations, use_build_context_synchronously + +import 'package:amplify_datastore_plugin_interface/amplify_datastore_plugin_interface.dart'; +import 'package:flutter/foundation.dart'; + + +/** This is an auto generated class representing the Todo type in your schema. */ +@immutable +class Todo extends Model { + static const classType = const _TodoModelType(); + final String id; + final String? _name; + final TemporalDateTime? _createdAt; + final TemporalDateTime? _updatedAt; + + @override + getInstanceType() => classType; + + @Deprecated('[getId] is being deprecated in favor of custom primary key feature. Use getter [modelIdentifier] to get model identifier.') + @override + String getId() => id; + + TodoModelIdentifier get modelIdentifier { + return TodoModelIdentifier( + id: id + ); + } + + String? get name { + return _name; + } + + TemporalDateTime? get createdAt { + return _createdAt; + } + + TemporalDateTime? get updatedAt { + return _updatedAt; + } + + const Todo._internal({required this.id, name, createdAt, updatedAt}): _name = name, _createdAt = createdAt, _updatedAt = updatedAt; + + factory Todo({String? id, String? name}) { + return Todo._internal( + id: id == null ? UUID.getUUID() : id, + name: name); + } + + bool equals(Object other) { + return this == other; + } + + @override + bool operator ==(Object other) { + if (identical(other, this)) return true; + return other is Todo && + id == other.id && + _name == other._name; + } + + @override + int get hashCode => toString().hashCode; + + @override + String toString() { + var buffer = new StringBuffer(); + + buffer.write(\\"Todo {\\"); + buffer.write(\\"id=\\" + \\"$id\\" + \\", \\"); + buffer.write(\\"name=\\" + \\"$_name\\" + \\", \\"); + buffer.write(\\"createdAt=\\" + (_createdAt != null ? _createdAt!.format() : \\"null\\") + \\", \\"); + buffer.write(\\"updatedAt=\\" + (_updatedAt != null ? _updatedAt!.format() : \\"null\\")); + buffer.write(\\"}\\"); + + return buffer.toString(); + } + + Todo copyWith({String? name}) { + return Todo._internal( + id: id, + name: name ?? this.name); + } + + Todo.fromJson(Map json) + : id = json['id'], + _name = json['name'], + _createdAt = json['createdAt'] != null ? TemporalDateTime.fromString(json['createdAt']) : null, + _updatedAt = json['updatedAt'] != null ? TemporalDateTime.fromString(json['updatedAt']) : null; + + Map toJson() => { + 'id': id, 'name': _name, 'createdAt': _createdAt?.format(), 'updatedAt': _updatedAt?.format() + }; + + Map toMap() => { + 'id': id, 'name': _name, 'createdAt': _createdAt, 'updatedAt': _updatedAt + }; + + static final QueryModelIdentifier MODEL_IDENTIFIER = QueryModelIdentifier(); + static final QueryField ID = QueryField(fieldName: \\"id\\"); + static final QueryField NAME = QueryField(fieldName: \\"name\\"); + static var schema = Model.defineSchema(define: (ModelSchemaDefinition modelSchemaDefinition) { + modelSchemaDefinition.name = \\"Todo\\"; + modelSchemaDefinition.pluralName = \\"Todos\\"; + + modelSchemaDefinition.authRules = [ + AuthRule( + authStrategy: AuthStrategy.PUBLIC, + operations: [ + ModelOperation.GET, + ModelOperation.LIST, + ModelOperation.LISTEN, + ModelOperation.SYNC, + ModelOperation.SEARCH + ]) + ]; + + modelSchemaDefinition.addField(ModelFieldDefinition.id()); + + modelSchemaDefinition.addField(ModelFieldDefinition.field( + key: Todo.NAME, + isRequired: false, + ofType: ModelFieldType(ModelFieldTypeEnum.string) + )); + + modelSchemaDefinition.addField(ModelFieldDefinition.nonQueryField( + fieldName: 'createdAt', + isRequired: false, + isReadOnly: true, + ofType: ModelFieldType(ModelFieldTypeEnum.dateTime) + )); + + modelSchemaDefinition.addField(ModelFieldDefinition.nonQueryField( + fieldName: 'updatedAt', + isRequired: false, + isReadOnly: true, + ofType: ModelFieldType(ModelFieldTypeEnum.dateTime) + )); + }); +} + +class _TodoModelType extends ModelType { + const _TodoModelType(); + + @override + Todo fromJson(Map jsonData) { + return Todo.fromJson(jsonData); + } + + @override + String modelName() { + return 'Todo'; + } +} + +/** + * This is an auto generated class representing the model identifier + * of [Todo] in your schema. + */ +@immutable +class TodoModelIdentifier implements ModelIdentifier { + final String id; + + /** Create an instance of TodoModelIdentifier using [id] the primary key. */ + const TodoModelIdentifier({ + required this.id}); + + @override + Map serializeAsMap() => ({ + 'id': id + }); + + @override + List> serializeAsList() => serializeAsMap() + .entries + .map((entry) => ({ entry.key: entry.value })) + .toList(); + + @override + String serializeAsString() => serializeAsMap().values.join('#'); + + @override + String toString() => 'TodoModelIdentifier(id: $id)'; + + @override + bool operator ==(Object other) { + if (identical(this, other)) { + return true; + } + + return other is TodoModelIdentifier && + id == other.id; + } + + @override + int get hashCode => + id.hashCode; +}" +`; + exports[`AppSync Dart Visitor Many To Many V2 Tests Should generate the intermediate model successfully with nullsafety disabled 1`] = ` "/* * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. diff --git a/packages/appsync-modelgen-plugin/src/__tests__/visitors/__snapshots__/appsync-java-visitor.test.ts.snap b/packages/appsync-modelgen-plugin/src/__tests__/visitors/__snapshots__/appsync-java-visitor.test.ts.snap index 4ddb156aa..79db0f707 100644 --- a/packages/appsync-modelgen-plugin/src/__tests__/visitors/__snapshots__/appsync-java-visitor.test.ts.snap +++ b/packages/appsync-modelgen-plugin/src/__tests__/visitors/__snapshots__/appsync-java-visitor.test.ts.snap @@ -1822,6 +1822,178 @@ public final class Blog implements Model { " `; +exports[`AppSyncModelVisitor Granular read operation test Should generate correct model file for GraphQL schema with granular read operations 1`] = ` +"package com.amplifyframework.datastore.generated.model; + +import com.amplifyframework.core.model.temporal.Temporal; + +import java.util.List; +import java.util.UUID; +import java.util.Objects; + +import androidx.core.util.ObjectsCompat; + +import com.amplifyframework.core.model.AuthStrategy; +import com.amplifyframework.core.model.Model; +import com.amplifyframework.core.model.ModelOperation; +import com.amplifyframework.core.model.annotations.AuthRule; +import com.amplifyframework.core.model.annotations.Index; +import com.amplifyframework.core.model.annotations.ModelConfig; +import com.amplifyframework.core.model.annotations.ModelField; +import com.amplifyframework.core.model.query.predicate.QueryField; + +import static com.amplifyframework.core.model.query.predicate.QueryField.field; + +/** This is an auto generated class representing the Todo type in your schema. */ +@SuppressWarnings(\\"all\\") +@ModelConfig(pluralName = \\"Todos\\", type = Model.Type.USER, version = 1, authRules = { + @AuthRule(allow = AuthStrategy.PUBLIC, operations = { ModelOperation.GET, ModelOperation.LIST, ModelOperation.LISTEN, ModelOperation.SYNC, ModelOperation.SEARCH }) +}) +public final class Todo implements Model { + public static final QueryField ID = field(\\"Todo\\", \\"id\\"); + public static final QueryField NAME = field(\\"Todo\\", \\"name\\"); + private final @ModelField(targetType=\\"ID\\", isRequired = true) String id; + private final @ModelField(targetType=\\"String\\") String name; + private @ModelField(targetType=\\"AWSDateTime\\", isReadOnly = true) Temporal.DateTime createdAt; + private @ModelField(targetType=\\"AWSDateTime\\", isReadOnly = true) Temporal.DateTime updatedAt; + public String resolveIdentifier() { + return id; + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } + + public Temporal.DateTime getCreatedAt() { + return createdAt; + } + + public Temporal.DateTime getUpdatedAt() { + return updatedAt; + } + + private Todo(String id, String name) { + this.id = id; + this.name = name; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } else if(obj == null || getClass() != obj.getClass()) { + return false; + } else { + Todo todo = (Todo) obj; + return ObjectsCompat.equals(getId(), todo.getId()) && + ObjectsCompat.equals(getName(), todo.getName()) && + ObjectsCompat.equals(getCreatedAt(), todo.getCreatedAt()) && + ObjectsCompat.equals(getUpdatedAt(), todo.getUpdatedAt()); + } + } + + @Override + public int hashCode() { + return new StringBuilder() + .append(getId()) + .append(getName()) + .append(getCreatedAt()) + .append(getUpdatedAt()) + .toString() + .hashCode(); + } + + @Override + public String toString() { + return new StringBuilder() + .append(\\"Todo {\\") + .append(\\"id=\\" + String.valueOf(getId()) + \\", \\") + .append(\\"name=\\" + String.valueOf(getName()) + \\", \\") + .append(\\"createdAt=\\" + String.valueOf(getCreatedAt()) + \\", \\") + .append(\\"updatedAt=\\" + String.valueOf(getUpdatedAt())) + .append(\\"}\\") + .toString(); + } + + public static BuildStep builder() { + return new Builder(); + } + + /** + * WARNING: This method should not be used to build an instance of this object for a CREATE mutation. + * This is a convenience method to return an instance of the object with only its ID populated + * to be used in the context of a parameter in a delete mutation or referencing a foreign key + * in a relationship. + * @param id the id of the existing item this instance will represent + * @return an instance of this model with only ID populated + */ + public static Todo justId(String id) { + return new Todo( + id, + null + ); + } + + public CopyOfBuilder copyOfBuilder() { + return new CopyOfBuilder(id, + name); + } + public interface BuildStep { + Todo build(); + BuildStep id(String id); + BuildStep name(String name); + } + + + public static class Builder implements BuildStep { + private String id; + private String name; + @Override + public Todo build() { + String id = this.id != null ? this.id : UUID.randomUUID().toString(); + + return new Todo( + id, + name); + } + + @Override + public BuildStep name(String name) { + this.name = name; + return this; + } + + /** + * @param id id + * @return Current Builder instance, for fluent method chaining + */ + public BuildStep id(String id) { + this.id = id; + return this; + } + } + + + public final class CopyOfBuilder extends Builder { + private CopyOfBuilder(String id, String name) { + super.id(id); + super.name(name); + } + + @Override + public CopyOfBuilder name(String name) { + return (CopyOfBuilder) super.name(name); + } + } + +} +" +`; + exports[`AppSyncModelVisitor Many To Many V2 Tests Should generate the intermediate model successfully 1`] = ` "package com.amplifyframework.datastore.generated.model; diff --git a/packages/appsync-modelgen-plugin/src/__tests__/visitors/__snapshots__/appsync-json-metadata-visitor.test.ts.snap b/packages/appsync-modelgen-plugin/src/__tests__/visitors/__snapshots__/appsync-json-metadata-visitor.test.ts.snap index 80f3768d5..63f94b858 100644 --- a/packages/appsync-modelgen-plugin/src/__tests__/visitors/__snapshots__/appsync-json-metadata-visitor.test.ts.snap +++ b/packages/appsync-modelgen-plugin/src/__tests__/visitors/__snapshots__/appsync-json-metadata-visitor.test.ts.snap @@ -584,43 +584,40 @@ exports[`Metadata visitor for custom PK support generates with explicit index 1` };" `; -exports[`Metadata visitor for custom PK support relation metadata for hasOne/belongsTo when custom PK is enabled should generate correct metadata in js 1`] = ` +exports[`Metadata visitor for custom PK support relation metadata for hasMany & belongsTo when custom PK is enabled should generate correct metadata in js 1`] = ` "export const schema = { \\"models\\": { - \\"Project\\": { - \\"name\\": \\"Project\\", + \\"Post\\": { + \\"name\\": \\"Post\\", \\"fields\\": { - \\"id\\": { - \\"name\\": \\"id\\", + \\"customPostId\\": { + \\"name\\": \\"customPostId\\", \\"isArray\\": false, \\"type\\": \\"ID\\", \\"isRequired\\": true, \\"attributes\\": [] }, - \\"name\\": { - \\"name\\": \\"name\\", + \\"title\\": { + \\"name\\": \\"title\\", \\"isArray\\": false, \\"type\\": \\"String\\", \\"isRequired\\": true, \\"attributes\\": [] }, - \\"team\\": { - \\"name\\": \\"team\\", - \\"isArray\\": false, + \\"comments\\": { + \\"name\\": \\"comments\\", + \\"isArray\\": true, \\"type\\": { - \\"model\\": \\"Team\\" + \\"model\\": \\"Comment\\" }, \\"isRequired\\": false, \\"attributes\\": [], + \\"isArrayNullable\\": true, \\"association\\": { - \\"connectionType\\": \\"HAS_ONE\\", + \\"connectionType\\": \\"HAS_MANY\\", \\"associatedWith\\": [ - \\"id\\", - \\"name\\" - ], - \\"targetNames\\": [ - \\"projectTeamId\\", - \\"projectTeamName\\" + \\"postCommentsCustomPostId\\", + \\"postCommentsTitle\\" ] } }, @@ -639,24 +636,10 @@ exports[`Metadata visitor for custom PK support relation metadata for hasOne/bel \\"isRequired\\": false, \\"attributes\\": [], \\"isReadOnly\\": true - }, - \\"projectTeamId\\": { - \\"name\\": \\"projectTeamId\\", - \\"isArray\\": false, - \\"type\\": \\"ID\\", - \\"isRequired\\": false, - \\"attributes\\": [] - }, - \\"projectTeamName\\": { - \\"name\\": \\"projectTeamName\\", - \\"isArray\\": false, - \\"type\\": \\"String\\", - \\"isRequired\\": false, - \\"attributes\\": [] } }, \\"syncable\\": true, - \\"pluralName\\": \\"Projects\\", + \\"pluralName\\": \\"Posts\\", \\"attributes\\": [ { \\"type\\": \\"model\\", @@ -666,43 +649,43 @@ exports[`Metadata visitor for custom PK support relation metadata for hasOne/bel \\"type\\": \\"key\\", \\"properties\\": { \\"fields\\": [ - \\"id\\", - \\"name\\" + \\"customPostId\\", + \\"title\\" ] } } ] }, - \\"Team\\": { - \\"name\\": \\"Team\\", + \\"Comment\\": { + \\"name\\": \\"Comment\\", \\"fields\\": { - \\"id\\": { - \\"name\\": \\"id\\", + \\"customCommentId\\": { + \\"name\\": \\"customCommentId\\", \\"isArray\\": false, \\"type\\": \\"ID\\", \\"isRequired\\": true, \\"attributes\\": [] }, - \\"name\\": { - \\"name\\": \\"name\\", + \\"content\\": { + \\"name\\": \\"content\\", \\"isArray\\": false, \\"type\\": \\"String\\", \\"isRequired\\": true, \\"attributes\\": [] }, - \\"project\\": { - \\"name\\": \\"project\\", + \\"post\\": { + \\"name\\": \\"post\\", \\"isArray\\": false, \\"type\\": { - \\"model\\": \\"Project\\" + \\"model\\": \\"Post\\" }, \\"isRequired\\": false, \\"attributes\\": [], \\"association\\": { \\"connectionType\\": \\"BELONGS_TO\\", \\"targetNames\\": [ - \\"teamProjectId\\", - \\"teamProjectName\\" + \\"postCommentsCustomPostId\\", + \\"postCommentsTitle\\" ] } }, @@ -722,15 +705,15 @@ exports[`Metadata visitor for custom PK support relation metadata for hasOne/bel \\"attributes\\": [], \\"isReadOnly\\": true }, - \\"teamProjectId\\": { - \\"name\\": \\"teamProjectId\\", + \\"postCommentsCustomPostId\\": { + \\"name\\": \\"postCommentsCustomPostId\\", \\"isArray\\": false, \\"type\\": \\"ID\\", \\"isRequired\\": false, \\"attributes\\": [] }, - \\"teamProjectName\\": { - \\"name\\": \\"teamProjectName\\", + \\"postCommentsTitle\\": { + \\"name\\": \\"postCommentsTitle\\", \\"isArray\\": false, \\"type\\": \\"String\\", \\"isRequired\\": false, @@ -738,7 +721,7 @@ exports[`Metadata visitor for custom PK support relation metadata for hasOne/bel } }, \\"syncable\\": true, - \\"pluralName\\": \\"Teams\\", + \\"pluralName\\": \\"Comments\\", \\"attributes\\": [ { \\"type\\": \\"model\\", @@ -748,60 +731,43 @@ exports[`Metadata visitor for custom PK support relation metadata for hasOne/bel \\"type\\": \\"key\\", \\"properties\\": { \\"fields\\": [ - \\"id\\", - \\"name\\" + \\"customCommentId\\", + \\"content\\" ] } } ] - } - }, - \\"enums\\": {}, - \\"nonModels\\": {}, - \\"codegenVersion\\": \\"1.0.0\\", - \\"version\\": \\"e44592ddc9b6514a18674da5baacfe68\\" -};" -`; - -exports[`Metadata visitor for custom PK support relation metadata for hasOne/belongsTo when custom PK is enabled should generate correct metadata in ts 1`] = ` -"import { Schema } from \\"@aws-amplify/datastore\\"; - -export const schema: Schema = { - \\"models\\": { - \\"Project\\": { - \\"name\\": \\"Project\\", + }, + \\"Post1\\": { + \\"name\\": \\"Post1\\", \\"fields\\": { - \\"id\\": { - \\"name\\": \\"id\\", + \\"postId\\": { + \\"name\\": \\"postId\\", \\"isArray\\": false, \\"type\\": \\"ID\\", \\"isRequired\\": true, \\"attributes\\": [] }, - \\"name\\": { - \\"name\\": \\"name\\", + \\"title\\": { + \\"name\\": \\"title\\", \\"isArray\\": false, \\"type\\": \\"String\\", \\"isRequired\\": true, \\"attributes\\": [] }, - \\"team\\": { - \\"name\\": \\"team\\", - \\"isArray\\": false, + \\"comments\\": { + \\"name\\": \\"comments\\", + \\"isArray\\": true, \\"type\\": { - \\"model\\": \\"Team\\" + \\"model\\": \\"Comment1\\" }, \\"isRequired\\": false, \\"attributes\\": [], + \\"isArrayNullable\\": true, \\"association\\": { - \\"connectionType\\": \\"HAS_ONE\\", + \\"connectionType\\": \\"HAS_MANY\\", \\"associatedWith\\": [ - \\"id\\", - \\"name\\" - ], - \\"targetNames\\": [ - \\"projectTeamId\\", - \\"projectTeamName\\" + \\"post\\" ] } }, @@ -820,24 +786,10 @@ export const schema: Schema = { \\"isRequired\\": false, \\"attributes\\": [], \\"isReadOnly\\": true - }, - \\"projectTeamId\\": { - \\"name\\": \\"projectTeamId\\", - \\"isArray\\": false, - \\"type\\": \\"ID\\", - \\"isRequired\\": false, - \\"attributes\\": [] - }, - \\"projectTeamName\\": { - \\"name\\": \\"projectTeamName\\", - \\"isArray\\": false, - \\"type\\": \\"String\\", - \\"isRequired\\": false, - \\"attributes\\": [] } }, \\"syncable\\": true, - \\"pluralName\\": \\"Projects\\", + \\"pluralName\\": \\"Post1s\\", \\"attributes\\": [ { \\"type\\": \\"model\\", @@ -847,46 +799,60 @@ export const schema: Schema = { \\"type\\": \\"key\\", \\"properties\\": { \\"fields\\": [ - \\"id\\", - \\"name\\" + \\"postId\\", + \\"title\\" ] } } ] }, - \\"Team\\": { - \\"name\\": \\"Team\\", + \\"Comment1\\": { + \\"name\\": \\"Comment1\\", \\"fields\\": { - \\"id\\": { - \\"name\\": \\"id\\", + \\"commentId\\": { + \\"name\\": \\"commentId\\", \\"isArray\\": false, \\"type\\": \\"ID\\", \\"isRequired\\": true, \\"attributes\\": [] }, - \\"name\\": { - \\"name\\": \\"name\\", + \\"content\\": { + \\"name\\": \\"content\\", \\"isArray\\": false, \\"type\\": \\"String\\", \\"isRequired\\": true, \\"attributes\\": [] }, - \\"project\\": { - \\"name\\": \\"project\\", + \\"post\\": { + \\"name\\": \\"post\\", \\"isArray\\": false, \\"type\\": { - \\"model\\": \\"Project\\" + \\"model\\": \\"Post1\\" }, \\"isRequired\\": false, \\"attributes\\": [], \\"association\\": { \\"connectionType\\": \\"BELONGS_TO\\", \\"targetNames\\": [ - \\"teamProjectId\\", - \\"teamProjectName\\" + \\"postId\\", + \\"postTitle\\" ] } }, + \\"postId\\": { + \\"name\\": \\"postId\\", + \\"isArray\\": false, + \\"type\\": \\"ID\\", + \\"isRequired\\": false, + \\"attributes\\": [] + }, + \\"postTitle\\": { + \\"name\\": \\"postTitle\\", + \\"isArray\\": false, + \\"type\\": \\"String\\", + \\"isRequired\\": false, + \\"attributes\\": [] + }, \\"createdAt\\": { \\"name\\": \\"createdAt\\", \\"isArray\\": false, @@ -902,24 +868,10 @@ export const schema: Schema = { \\"isRequired\\": false, \\"attributes\\": [], \\"isReadOnly\\": true - }, - \\"teamProjectId\\": { - \\"name\\": \\"teamProjectId\\", - \\"isArray\\": false, - \\"type\\": \\"ID\\", - \\"isRequired\\": false, - \\"attributes\\": [] - }, - \\"teamProjectName\\": { - \\"name\\": \\"teamProjectName\\", - \\"isArray\\": false, - \\"type\\": \\"String\\", - \\"isRequired\\": false, - \\"attributes\\": [] } }, \\"syncable\\": true, - \\"pluralName\\": \\"Teams\\", + \\"pluralName\\": \\"Comment1s\\", \\"attributes\\": [ { \\"type\\": \\"model\\", @@ -929,8 +881,18 @@ export const schema: Schema = { \\"type\\": \\"key\\", \\"properties\\": { \\"fields\\": [ - \\"id\\", - \\"name\\" + \\"commentId\\", + \\"content\\" + ] + } + }, + { + \\"type\\": \\"key\\", + \\"properties\\": { + \\"name\\": \\"byPost\\", + \\"fields\\": [ + \\"postId\\", + \\"postTitle\\" ] } } @@ -940,12 +902,14 @@ export const schema: Schema = { \\"enums\\": {}, \\"nonModels\\": {}, \\"codegenVersion\\": \\"1.0.0\\", - \\"version\\": \\"e44592ddc9b6514a18674da5baacfe68\\" + \\"version\\": \\"cb8f120e36ffc33e0b01e0874ba14f7a\\" };" `; -exports[`relation metadata for hasMany & belongsTo when custom PK is enabled should generate correct metadata in js 1`] = ` -"export const schema = { +exports[`Metadata visitor for custom PK support relation metadata for hasMany & belongsTo when custom PK is enabled should generate correct metadata in ts 1`] = ` +"import { Schema } from \\"@aws-amplify/datastore\\"; + +export const schema: Schema = { \\"models\\": { \\"Post\\": { \\"name\\": \\"Post\\", @@ -1266,16 +1230,14 @@ exports[`relation metadata for hasMany & belongsTo when custom PK is enabled sho };" `; -exports[`relation metadata for hasMany & belongsTo when custom PK is enabled should generate correct metadata in ts 1`] = ` -"import { Schema } from \\"@aws-amplify/datastore\\"; - -export const schema: Schema = { +exports[`Metadata visitor for custom PK support relation metadata for hasMany uni when custom PK is enabled should generate correct metadata in js 1`] = ` +"export const schema = { \\"models\\": { \\"Post\\": { \\"name\\": \\"Post\\", \\"fields\\": { - \\"customPostId\\": { - \\"name\\": \\"customPostId\\", + \\"id\\": { + \\"name\\": \\"id\\", \\"isArray\\": false, \\"type\\": \\"ID\\", \\"isRequired\\": true, @@ -1300,7 +1262,7 @@ export const schema: Schema = { \\"association\\": { \\"connectionType\\": \\"HAS_MANY\\", \\"associatedWith\\": [ - \\"postCommentsCustomPostId\\", + \\"postCommentsId\\", \\"postCommentsTitle\\" ] } @@ -1333,7 +1295,7 @@ export const schema: Schema = { \\"type\\": \\"key\\", \\"properties\\": { \\"fields\\": [ - \\"customPostId\\", + \\"id\\", \\"title\\" ] } @@ -1343,8 +1305,8 @@ export const schema: Schema = { \\"Comment\\": { \\"name\\": \\"Comment\\", \\"fields\\": { - \\"customCommentId\\": { - \\"name\\": \\"customCommentId\\", + \\"id\\": { + \\"name\\": \\"id\\", \\"isArray\\": false, \\"type\\": \\"ID\\", \\"isRequired\\": true, @@ -1357,22 +1319,6 @@ export const schema: Schema = { \\"isRequired\\": true, \\"attributes\\": [] }, - \\"post\\": { - \\"name\\": \\"post\\", - \\"isArray\\": false, - \\"type\\": { - \\"model\\": \\"Post\\" - }, - \\"isRequired\\": false, - \\"attributes\\": [], - \\"association\\": { - \\"connectionType\\": \\"BELONGS_TO\\", - \\"targetNames\\": [ - \\"postCommentsCustomPostId\\", - \\"postCommentsTitle\\" - ] - } - }, \\"createdAt\\": { \\"name\\": \\"createdAt\\", \\"isArray\\": false, @@ -1389,8 +1335,8 @@ export const schema: Schema = { \\"attributes\\": [], \\"isReadOnly\\": true }, - \\"postCommentsCustomPostId\\": { - \\"name\\": \\"postCommentsCustomPostId\\", + \\"postCommentsId\\": { + \\"name\\": \\"postCommentsId\\", \\"isArray\\": false, \\"type\\": \\"ID\\", \\"isRequired\\": false, @@ -1415,10 +1361,20 @@ export const schema: Schema = { \\"type\\": \\"key\\", \\"properties\\": { \\"fields\\": [ - \\"customCommentId\\", + \\"id\\", \\"content\\" ] } + }, + { + \\"type\\": \\"key\\", + \\"properties\\": { + \\"name\\": \\"gsi-Post.comments\\", + \\"fields\\": [ + \\"postCommentsId\\", + \\"postCommentsTitle\\" + ] + } } ] }, @@ -1451,7 +1407,7 @@ export const schema: Schema = { \\"association\\": { \\"connectionType\\": \\"HAS_MANY\\", \\"associatedWith\\": [ - \\"post\\" + \\"postId\\" ] } }, @@ -1507,22 +1463,6 @@ export const schema: Schema = { \\"isRequired\\": true, \\"attributes\\": [] }, - \\"post\\": { - \\"name\\": \\"post\\", - \\"isArray\\": false, - \\"type\\": { - \\"model\\": \\"Post1\\" - }, - \\"isRequired\\": false, - \\"attributes\\": [], - \\"association\\": { - \\"connectionType\\": \\"BELONGS_TO\\", - \\"targetNames\\": [ - \\"postId\\", - \\"postTitle\\" - ] - } - }, \\"postId\\": { \\"name\\": \\"postId\\", \\"isArray\\": false, @@ -1586,12 +1526,14 @@ export const schema: Schema = { \\"enums\\": {}, \\"nonModels\\": {}, \\"codegenVersion\\": \\"1.0.0\\", - \\"version\\": \\"cb8f120e36ffc33e0b01e0874ba14f7a\\" + \\"version\\": \\"aa7ec83a3846aece824a211c5304dd88\\" };" `; -exports[`relation metadata for hasMany uni when custom PK is enabled should generate correct metadata in js 1`] = ` -"export const schema = { +exports[`Metadata visitor for custom PK support relation metadata for hasMany uni when custom PK is enabled should generate correct metadata in ts 1`] = ` +"import { Schema } from \\"@aws-amplify/datastore\\"; + +export const schema: Schema = { \\"models\\": { \\"Post\\": { \\"name\\": \\"Post\\", @@ -1890,13 +1832,11 @@ exports[`relation metadata for hasMany uni when custom PK is enabled should gene };" `; -exports[`relation metadata for hasMany uni when custom PK is enabled should generate correct metadata in ts 1`] = ` -"import { Schema } from \\"@aws-amplify/datastore\\"; - -export const schema: Schema = { +exports[`Metadata visitor for custom PK support relation metadata for hasOne/belongsTo when custom PK is enabled should generate correct metadata in js 1`] = ` +"export const schema = { \\"models\\": { - \\"Post\\": { - \\"name\\": \\"Post\\", + \\"Project\\": { + \\"name\\": \\"Project\\", \\"fields\\": { \\"id\\": { \\"name\\": \\"id\\", @@ -1905,27 +1845,30 @@ export const schema: Schema = { \\"isRequired\\": true, \\"attributes\\": [] }, - \\"title\\": { - \\"name\\": \\"title\\", + \\"name\\": { + \\"name\\": \\"name\\", \\"isArray\\": false, \\"type\\": \\"String\\", \\"isRequired\\": true, \\"attributes\\": [] }, - \\"comments\\": { - \\"name\\": \\"comments\\", - \\"isArray\\": true, + \\"team\\": { + \\"name\\": \\"team\\", + \\"isArray\\": false, \\"type\\": { - \\"model\\": \\"Comment\\" + \\"model\\": \\"Team\\" }, \\"isRequired\\": false, \\"attributes\\": [], - \\"isArrayNullable\\": true, \\"association\\": { - \\"connectionType\\": \\"HAS_MANY\\", + \\"connectionType\\": \\"HAS_ONE\\", \\"associatedWith\\": [ - \\"postCommentsId\\", - \\"postCommentsTitle\\" + \\"id\\", + \\"name\\" + ], + \\"targetNames\\": [ + \\"projectTeamId\\", + \\"projectTeamName\\" ] } }, @@ -1944,10 +1887,24 @@ export const schema: Schema = { \\"isRequired\\": false, \\"attributes\\": [], \\"isReadOnly\\": true + }, + \\"projectTeamId\\": { + \\"name\\": \\"projectTeamId\\", + \\"isArray\\": false, + \\"type\\": \\"ID\\", + \\"isRequired\\": false, + \\"attributes\\": [] + }, + \\"projectTeamName\\": { + \\"name\\": \\"projectTeamName\\", + \\"isArray\\": false, + \\"type\\": \\"String\\", + \\"isRequired\\": false, + \\"attributes\\": [] } }, \\"syncable\\": true, - \\"pluralName\\": \\"Posts\\", + \\"pluralName\\": \\"Projects\\", \\"attributes\\": [ { \\"type\\": \\"model\\", @@ -1958,14 +1915,14 @@ export const schema: Schema = { \\"properties\\": { \\"fields\\": [ \\"id\\", - \\"title\\" + \\"name\\" ] } } ] }, - \\"Comment\\": { - \\"name\\": \\"Comment\\", + \\"Team\\": { + \\"name\\": \\"Team\\", \\"fields\\": { \\"id\\": { \\"name\\": \\"id\\", @@ -1974,13 +1931,29 @@ export const schema: Schema = { \\"isRequired\\": true, \\"attributes\\": [] }, - \\"content\\": { - \\"name\\": \\"content\\", + \\"name\\": { + \\"name\\": \\"name\\", \\"isArray\\": false, \\"type\\": \\"String\\", \\"isRequired\\": true, \\"attributes\\": [] }, + \\"project\\": { + \\"name\\": \\"project\\", + \\"isArray\\": false, + \\"type\\": { + \\"model\\": \\"Project\\" + }, + \\"isRequired\\": false, + \\"attributes\\": [], + \\"association\\": { + \\"connectionType\\": \\"BELONGS_TO\\", + \\"targetNames\\": [ + \\"teamProjectId\\", + \\"teamProjectName\\" + ] + } + }, \\"createdAt\\": { \\"name\\": \\"createdAt\\", \\"isArray\\": false, @@ -1997,15 +1970,15 @@ export const schema: Schema = { \\"attributes\\": [], \\"isReadOnly\\": true }, - \\"postCommentsId\\": { - \\"name\\": \\"postCommentsId\\", + \\"teamProjectId\\": { + \\"name\\": \\"teamProjectId\\", \\"isArray\\": false, \\"type\\": \\"ID\\", \\"isRequired\\": false, \\"attributes\\": [] }, - \\"postCommentsTitle\\": { - \\"name\\": \\"postCommentsTitle\\", + \\"teamProjectName\\": { + \\"name\\": \\"teamProjectName\\", \\"isArray\\": false, \\"type\\": \\"String\\", \\"isRequired\\": false, @@ -2013,7 +1986,7 @@ export const schema: Schema = { } }, \\"syncable\\": true, - \\"pluralName\\": \\"Comments\\", + \\"pluralName\\": \\"Teams\\", \\"attributes\\": [ { \\"type\\": \\"model\\", @@ -2024,52 +1997,59 @@ export const schema: Schema = { \\"properties\\": { \\"fields\\": [ \\"id\\", - \\"content\\" - ] - } - }, - { - \\"type\\": \\"key\\", - \\"properties\\": { - \\"name\\": \\"gsi-Post.comments\\", - \\"fields\\": [ - \\"postCommentsId\\", - \\"postCommentsTitle\\" + \\"name\\" ] } } ] - }, - \\"Post1\\": { - \\"name\\": \\"Post1\\", + } + }, + \\"enums\\": {}, + \\"nonModels\\": {}, + \\"codegenVersion\\": \\"1.0.0\\", + \\"version\\": \\"e44592ddc9b6514a18674da5baacfe68\\" +};" +`; + +exports[`Metadata visitor for custom PK support relation metadata for hasOne/belongsTo when custom PK is enabled should generate correct metadata in ts 1`] = ` +"import { Schema } from \\"@aws-amplify/datastore\\"; + +export const schema: Schema = { + \\"models\\": { + \\"Project\\": { + \\"name\\": \\"Project\\", \\"fields\\": { - \\"postId\\": { - \\"name\\": \\"postId\\", + \\"id\\": { + \\"name\\": \\"id\\", \\"isArray\\": false, \\"type\\": \\"ID\\", \\"isRequired\\": true, \\"attributes\\": [] }, - \\"title\\": { - \\"name\\": \\"title\\", + \\"name\\": { + \\"name\\": \\"name\\", \\"isArray\\": false, \\"type\\": \\"String\\", \\"isRequired\\": true, \\"attributes\\": [] }, - \\"comments\\": { - \\"name\\": \\"comments\\", - \\"isArray\\": true, + \\"team\\": { + \\"name\\": \\"team\\", + \\"isArray\\": false, \\"type\\": { - \\"model\\": \\"Comment1\\" + \\"model\\": \\"Team\\" }, \\"isRequired\\": false, \\"attributes\\": [], - \\"isArrayNullable\\": true, \\"association\\": { - \\"connectionType\\": \\"HAS_MANY\\", + \\"connectionType\\": \\"HAS_ONE\\", \\"associatedWith\\": [ - \\"postId\\" + \\"id\\", + \\"name\\" + ], + \\"targetNames\\": [ + \\"projectTeamId\\", + \\"projectTeamName\\" ] } }, @@ -2088,10 +2068,24 @@ export const schema: Schema = { \\"isRequired\\": false, \\"attributes\\": [], \\"isReadOnly\\": true + }, + \\"projectTeamId\\": { + \\"name\\": \\"projectTeamId\\", + \\"isArray\\": false, + \\"type\\": \\"ID\\", + \\"isRequired\\": false, + \\"attributes\\": [] + }, + \\"projectTeamName\\": { + \\"name\\": \\"projectTeamName\\", + \\"isArray\\": false, + \\"type\\": \\"String\\", + \\"isRequired\\": false, + \\"attributes\\": [] } }, \\"syncable\\": true, - \\"pluralName\\": \\"Post1s\\", + \\"pluralName\\": \\"Projects\\", \\"attributes\\": [ { \\"type\\": \\"model\\", @@ -2101,43 +2095,45 @@ export const schema: Schema = { \\"type\\": \\"key\\", \\"properties\\": { \\"fields\\": [ - \\"postId\\", - \\"title\\" + \\"id\\", + \\"name\\" ] } } ] }, - \\"Comment1\\": { - \\"name\\": \\"Comment1\\", + \\"Team\\": { + \\"name\\": \\"Team\\", \\"fields\\": { - \\"commentId\\": { - \\"name\\": \\"commentId\\", + \\"id\\": { + \\"name\\": \\"id\\", \\"isArray\\": false, \\"type\\": \\"ID\\", \\"isRequired\\": true, \\"attributes\\": [] }, - \\"content\\": { - \\"name\\": \\"content\\", + \\"name\\": { + \\"name\\": \\"name\\", \\"isArray\\": false, \\"type\\": \\"String\\", \\"isRequired\\": true, \\"attributes\\": [] }, - \\"postId\\": { - \\"name\\": \\"postId\\", - \\"isArray\\": false, - \\"type\\": \\"ID\\", - \\"isRequired\\": false, - \\"attributes\\": [] - }, - \\"postTitle\\": { - \\"name\\": \\"postTitle\\", + \\"project\\": { + \\"name\\": \\"project\\", \\"isArray\\": false, - \\"type\\": \\"String\\", + \\"type\\": { + \\"model\\": \\"Project\\" + }, \\"isRequired\\": false, - \\"attributes\\": [] + \\"attributes\\": [], + \\"association\\": { + \\"connectionType\\": \\"BELONGS_TO\\", + \\"targetNames\\": [ + \\"teamProjectId\\", + \\"teamProjectName\\" + ] + } }, \\"createdAt\\": { \\"name\\": \\"createdAt\\", @@ -2154,10 +2150,24 @@ export const schema: Schema = { \\"isRequired\\": false, \\"attributes\\": [], \\"isReadOnly\\": true + }, + \\"teamProjectId\\": { + \\"name\\": \\"teamProjectId\\", + \\"isArray\\": false, + \\"type\\": \\"ID\\", + \\"isRequired\\": false, + \\"attributes\\": [] + }, + \\"teamProjectName\\": { + \\"name\\": \\"teamProjectName\\", + \\"isArray\\": false, + \\"type\\": \\"String\\", + \\"isRequired\\": false, + \\"attributes\\": [] } }, \\"syncable\\": true, - \\"pluralName\\": \\"Comment1s\\", + \\"pluralName\\": \\"Teams\\", \\"attributes\\": [ { \\"type\\": \\"model\\", @@ -2167,18 +2177,8 @@ export const schema: Schema = { \\"type\\": \\"key\\", \\"properties\\": { \\"fields\\": [ - \\"commentId\\", - \\"content\\" - ] - } - }, - { - \\"type\\": \\"key\\", - \\"properties\\": { - \\"name\\": \\"byPost\\", - \\"fields\\": [ - \\"postId\\", - \\"postTitle\\" + \\"id\\", + \\"name\\" ] } } @@ -2188,11 +2188,11 @@ export const schema: Schema = { \\"enums\\": {}, \\"nonModels\\": {}, \\"codegenVersion\\": \\"1.0.0\\", - \\"version\\": \\"aa7ec83a3846aece824a211c5304dd88\\" + \\"version\\": \\"e44592ddc9b6514a18674da5baacfe68\\" };" `; -exports[`relation metadata for manyToMany when custom PK is enabled should generate correct metadata in js 1`] = ` +exports[`Metadata visitor for custom PK support relation metadata for manyToMany when custom PK is enabled should generate correct metadata in js 1`] = ` "export const schema = { \\"models\\": { \\"Post\\": { @@ -2462,7 +2462,7 @@ exports[`relation metadata for manyToMany when custom PK is enabled should gener };" `; -exports[`relation metadata for manyToMany when custom PK is enabled should generate correct metadata in ts 1`] = ` +exports[`Metadata visitor for custom PK support relation metadata for manyToMany when custom PK is enabled should generate correct metadata in ts 1`] = ` "import { Schema } from \\"@aws-amplify/datastore\\"; export const schema: Schema = { @@ -2733,3 +2733,147 @@ export const schema: Schema = { \\"version\\": \\"7c85f0b3f2df2a63cd6e1c28593a5381\\" };" `; + +exports[`Metadata visitor for granular read operations should generate correct metadata in js 1`] = ` +"export const schema = { + \\"models\\": { + \\"Todo\\": { + \\"name\\": \\"Todo\\", + \\"fields\\": { + \\"id\\": { + \\"name\\": \\"id\\", + \\"isArray\\": false, + \\"type\\": \\"ID\\", + \\"isRequired\\": true, + \\"attributes\\": [] + }, + \\"name\\": { + \\"name\\": \\"name\\", + \\"isArray\\": false, + \\"type\\": \\"String\\", + \\"isRequired\\": false, + \\"attributes\\": [] + }, + \\"createdAt\\": { + \\"name\\": \\"createdAt\\", + \\"isArray\\": false, + \\"type\\": \\"AWSDateTime\\", + \\"isRequired\\": false, + \\"attributes\\": [], + \\"isReadOnly\\": true + }, + \\"updatedAt\\": { + \\"name\\": \\"updatedAt\\", + \\"isArray\\": false, + \\"type\\": \\"AWSDateTime\\", + \\"isRequired\\": false, + \\"attributes\\": [], + \\"isReadOnly\\": true + } + }, + \\"syncable\\": true, + \\"pluralName\\": \\"Todos\\", + \\"attributes\\": [ + { + \\"type\\": \\"model\\", + \\"properties\\": {} + }, + { + \\"type\\": \\"auth\\", + \\"properties\\": { + \\"rules\\": [ + { + \\"allow\\": \\"public\\", + \\"operations\\": [ + \\"get\\", + \\"list\\", + \\"listen\\", + \\"sync\\", + \\"search\\" + ] + } + ] + } + } + ] + } + }, + \\"enums\\": {}, + \\"nonModels\\": {}, + \\"codegenVersion\\": \\"1.0.0\\", + \\"version\\": \\"92d09fb90dbbf6e134a3c99dc6f0455b\\" +};" +`; + +exports[`Metadata visitor for granular read operations should generate correct metadata in ts 1`] = ` +"import { Schema } from \\"@aws-amplify/datastore\\"; + +export const schema: Schema = { + \\"models\\": { + \\"Todo\\": { + \\"name\\": \\"Todo\\", + \\"fields\\": { + \\"id\\": { + \\"name\\": \\"id\\", + \\"isArray\\": false, + \\"type\\": \\"ID\\", + \\"isRequired\\": true, + \\"attributes\\": [] + }, + \\"name\\": { + \\"name\\": \\"name\\", + \\"isArray\\": false, + \\"type\\": \\"String\\", + \\"isRequired\\": false, + \\"attributes\\": [] + }, + \\"createdAt\\": { + \\"name\\": \\"createdAt\\", + \\"isArray\\": false, + \\"type\\": \\"AWSDateTime\\", + \\"isRequired\\": false, + \\"attributes\\": [], + \\"isReadOnly\\": true + }, + \\"updatedAt\\": { + \\"name\\": \\"updatedAt\\", + \\"isArray\\": false, + \\"type\\": \\"AWSDateTime\\", + \\"isRequired\\": false, + \\"attributes\\": [], + \\"isReadOnly\\": true + } + }, + \\"syncable\\": true, + \\"pluralName\\": \\"Todos\\", + \\"attributes\\": [ + { + \\"type\\": \\"model\\", + \\"properties\\": {} + }, + { + \\"type\\": \\"auth\\", + \\"properties\\": { + \\"rules\\": [ + { + \\"allow\\": \\"public\\", + \\"operations\\": [ + \\"get\\", + \\"list\\", + \\"listen\\", + \\"sync\\", + \\"search\\" + ] + } + ] + } + } + ] + } + }, + \\"enums\\": {}, + \\"nonModels\\": {}, + \\"codegenVersion\\": \\"1.0.0\\", + \\"version\\": \\"92d09fb90dbbf6e134a3c99dc6f0455b\\" +};" +`; diff --git a/packages/appsync-modelgen-plugin/src/__tests__/visitors/__snapshots__/appsync-swift-visitor.test.ts.snap b/packages/appsync-modelgen-plugin/src/__tests__/visitors/__snapshots__/appsync-swift-visitor.test.ts.snap index 503951086..3e63ed9c1 100644 --- a/packages/appsync-modelgen-plugin/src/__tests__/visitors/__snapshots__/appsync-swift-visitor.test.ts.snap +++ b/packages/appsync-modelgen-plugin/src/__tests__/visitors/__snapshots__/appsync-swift-visitor.test.ts.snap @@ -1,5 +1,97 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`AppSyncSwiftVisitor Granular read ops test Should generate model and metadata for a model with granular read operations 1`] = ` +"// swiftlint:disable all +import Amplify +import Foundation + +public struct Todo: Model { + public let id: String + public var name: String? + public var createdAt: Temporal.DateTime? + public var updatedAt: Temporal.DateTime? + + public init(id: String = UUID().uuidString, + name: String? = nil) { + self.init(id: id, + name: name, + createdAt: nil, + updatedAt: nil) + } + internal init(id: String = UUID().uuidString, + name: String? = nil, + createdAt: Temporal.DateTime? = nil, + updatedAt: Temporal.DateTime? = nil) { + self.id = id + self.name = name + self.createdAt = createdAt + self.updatedAt = updatedAt + } +}" +`; + +exports[`AppSyncSwiftVisitor Granular read ops test Should generate model and metadata for a model with granular read operations 2`] = ` +"// swiftlint:disable all +import Amplify +import Foundation + +extension Todo { + // MARK: - CodingKeys + public enum CodingKeys: String, ModelKey { + case id + case name + case createdAt + case updatedAt + } + + public static let keys = CodingKeys.self + // MARK: - ModelSchema + + public static let schema = defineSchema { model in + let todo = Todo.keys + + model.authRules = [ + rule(allow: .public, operations: [.get, .list, .listen, .sync, .search]) + ] + + model.pluralName = \\"Todos\\" + + model.attributes( + .primaryKey(fields: [todo.id]) + ) + + model.fields( + .field(todo.id, is: .required, ofType: .string), + .field(todo.name, is: .optional, ofType: .string), + .field(todo.createdAt, is: .optional, isReadOnly: true, ofType: .dateTime), + .field(todo.updatedAt, is: .optional, isReadOnly: true, ofType: .dateTime) + ) + } + public class Path: ModelPath { } + + public static var rootPath: PropertyContainerPath? { Path() } +} + +extension Todo: ModelIdentifiable { + public typealias IdentifierFormat = ModelIdentifierFormat.Default + public typealias IdentifierProtocol = DefaultModelIdentifier +} +extension ModelPath where ModelType == Todo { + public var id: FieldPath { + string(\\"id\\") + } + public var name: FieldPath { + string(\\"name\\") + } + public var createdAt: FieldPath { + datetime(\\"createdAt\\") + } + public var updatedAt: FieldPath { + datetime(\\"updatedAt\\") + } +}" +`; + exports[`AppSyncSwiftVisitor Many To Many V2 Tests Should generate the intermediate model successfully 1`] = ` "// swiftlint:disable all import Amplify diff --git a/packages/appsync-modelgen-plugin/src/__tests__/visitors/appsync-dart-visitor.test.ts b/packages/appsync-modelgen-plugin/src/__tests__/visitors/appsync-dart-visitor.test.ts index 81f8b480b..e273f751b 100644 --- a/packages/appsync-modelgen-plugin/src/__tests__/visitors/appsync-dart-visitor.test.ts +++ b/packages/appsync-modelgen-plugin/src/__tests__/visitors/appsync-dart-visitor.test.ts @@ -832,4 +832,25 @@ describe('AppSync Dart Visitor', () => { }) }) }); + + describe('Granular read operation test', () => { + it('should generate correct model file for GraphQL schema with granular read operation', () => { + const schema = /* GraphQL */ ` + type Todo @model @auth(rules:[{allow:public, operations:[get, list, listen, sync, search]}]) { + id: ID! + name: String + } + `; + const generatedCode = getVisitor({ + schema, + selectedType: 'Todo', + enableDartNullSafety: true, + enableDartZeroThreeFeatures: true, + isTimestampFieldsAdded: true, + respectPrimaryKeyAttributesOnConnectionField: true, + transformerVersion: 2 + }).generate(); + expect(generatedCode).toMatchSnapshot(); + }); + }); }); diff --git a/packages/appsync-modelgen-plugin/src/__tests__/visitors/appsync-java-visitor.test.ts b/packages/appsync-modelgen-plugin/src/__tests__/visitors/appsync-java-visitor.test.ts index c3315abc5..26d1da86d 100644 --- a/packages/appsync-modelgen-plugin/src/__tests__/visitors/appsync-java-visitor.test.ts +++ b/packages/appsync-modelgen-plugin/src/__tests__/visitors/appsync-java-visitor.test.ts @@ -702,4 +702,17 @@ describe('AppSyncModelVisitor', () => { expect(generatedCodeComment).toMatchSnapshot(); }); }); + + describe('Granular read operation test', () => { + it('Should generate correct model file for GraphQL schema with granular read operations', () => { + const schema = /* GraphQL */ ` + type Todo @model @auth(rules:[{allow:public, operations:[get, list, listen, sync, search]}]) { + id: ID! + name: String + } + `; + const generatedCode = getVisitorPipelinedTransformer(schema, 'Todo', { respectPrimaryKeyAttributesOnConnectionField: true }).generate(); + expect(generatedCode).toMatchSnapshot(); + }); + }); }); diff --git a/packages/appsync-modelgen-plugin/src/__tests__/visitors/appsync-json-metadata-visitor.test.ts b/packages/appsync-modelgen-plugin/src/__tests__/visitors/appsync-json-metadata-visitor.test.ts index 5b3e7292b..cf9cb015c 100644 --- a/packages/appsync-modelgen-plugin/src/__tests__/visitors/appsync-json-metadata-visitor.test.ts +++ b/packages/appsync-modelgen-plugin/src/__tests__/visitors/appsync-json-metadata-visitor.test.ts @@ -1441,7 +1441,6 @@ describe('Metadata visitor for custom PK support', () => { getVisitor(schema, 'javascript', { respectPrimaryKeyAttributesOnConnectionField: true, transformerVersion: 2 }).generate(), ).toMatchSnapshot(); }); -}); describe('relation metadata for hasMany uni when custom PK is enabled', () => { const schema = /* GraphQL */ ` type Post @model { @@ -1538,3 +1537,22 @@ describe('Metadata visitor for custom PK support', () => { }); }); }); + +describe('Metadata visitor for granular read operations', () => { + const schema = /* GraphQL */ ` + type Todo @model @auth(rules:[{allow:public, operations:[get, list, listen, sync, search]}]) { + id: ID! + name: String + } + `; + it('should generate correct metadata in js', () => { + expect( + getVisitor(schema, 'javascript', { respectPrimaryKeyAttributesOnConnectionField: true, transformerVersion: 2 }).generate(), + ).toMatchSnapshot(); + }); + it('should generate correct metadata in ts', () => { + expect( + getVisitor(schema, 'typescript', { respectPrimaryKeyAttributesOnConnectionField: true, transformerVersion: 2 }).generate(), + ).toMatchSnapshot(); + }); +}); diff --git a/packages/appsync-modelgen-plugin/src/__tests__/visitors/appsync-swift-visitor.test.ts b/packages/appsync-modelgen-plugin/src/__tests__/visitors/appsync-swift-visitor.test.ts index 91cca4382..ebf34f3a9 100644 --- a/packages/appsync-modelgen-plugin/src/__tests__/visitors/appsync-swift-visitor.test.ts +++ b/packages/appsync-modelgen-plugin/src/__tests__/visitors/appsync-swift-visitor.test.ts @@ -2946,4 +2946,24 @@ describe('AppSyncSwiftVisitor', () => { expect(generatedMetaComment).toMatchSnapshot(); }); }); + + describe('Granular read ops test', () => { + it('Should generate model and metadata for a model with granular read operations', () => { + const schema = /* GraphQL */ ` + type Todo @model @auth(rules:[{allow:public, operations:[get, list, listen, sync, search]}]) { + id: ID! + name: String + } + `; + const generatedCode = getVisitorPipelinedTransformer(schema, 'Todo', CodeGenGenerateEnum.code, { + respectPrimaryKeyAttributesOnConnectionField: true, + }).generate(); + expect(generatedCode).toMatchSnapshot(); + + const generatedMetadata = getVisitorPipelinedTransformer(schema, 'Todo', CodeGenGenerateEnum.metadata, { + respectPrimaryKeyAttributesOnConnectionField: true, + }).generate(); + expect(generatedMetadata).toMatchSnapshot(); + }); + }) }); diff --git a/packages/appsync-modelgen-plugin/src/visitors/appsync-java-visitor.ts b/packages/appsync-modelgen-plugin/src/visitors/appsync-java-visitor.ts index fd6202b1e..3231adc9a 100644 --- a/packages/appsync-modelgen-plugin/src/visitors/appsync-java-visitor.ts +++ b/packages/appsync-modelgen-plugin/src/visitors/appsync-java-visitor.ts @@ -888,6 +888,12 @@ export class AppSyncModelJavaVisitor< read: 'ModelOperation.READ', update: 'ModelOperation.UPDATE', delete: 'ModelOperation.DELETE', + //granular read + get: 'ModelOperation.GET', + list: 'ModelOperation.LIST', + sync: 'ModelOperation.SYNC', + listen: 'ModelOperation.LISTEN', + search: 'ModelOperation.SEARCH', }; const rules: string[] = []; authDirectives.forEach(directive => {