Skip to content

Commit 3e23919

Browse files
authored
fix(api): GraphQL Model Helpers support lowercase model names #4143 (#4144)
1 parent 864adb4 commit 3e23919

File tree

18 files changed

+967
-474
lines changed

18 files changed

+967
-474
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Getting Started with Amplify CLI
2+
This directory was generated by [Amplify CLI](https://docs.amplify.aws/cli).
3+
4+
Helpful resources:
5+
- Amplify documentation: https://docs.amplify.aws
6+
- Amplify CLI documentation: https://docs.amplify.aws/cli
7+
- More details on this folder & generated files: https://docs.amplify.aws/cli/reference/files
8+
- Join Amplify's community: https://amplify.aws/community/

packages/api/amplify_api/example/amplify/backend/api/apiintegmultiauth/schema.graphql

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,18 @@ type OwnerOnly @model @auth(rules: [{allow: owner}]) {
6767
id: ID!
6868
name: String!
6969
}
70+
71+
type lowerCase
72+
@model
73+
@auth(
74+
rules: [
75+
{ allow: public, operations: [read], provider: apiKey },
76+
{ allow: public, operations: [read], provider: iam },
77+
{ allow: private, operations: [read], provider: iam },
78+
{ allow: private, operations: [read], provider: userPools },
79+
{ allow: owner, operations: [create, read, update, delete] }
80+
]
81+
) {
82+
id: ID!
83+
name: String!
84+
}

packages/api/amplify_api/example/amplify/backend/function/apiintegmultiauth0aef1d4a/apiintegmultiauth0aef1d4a-cloudformation-template.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"AWSTemplateFormatVersion": "2010-09-09",
3-
"Description": "{\"createdOn\":\"Mac\",\"createdBy\":\"Amplify\",\"createdWith\":\"9.2.1\",\"stackType\":\"function-Lambda\",\"metadata\":{}}",
3+
"Description": "{\"createdOn\":\"Mac\",\"createdBy\":\"Amplify\",\"createdWith\":\"12.8.2\",\"stackType\":\"function-Lambda\",\"metadata\":{}}",
44
"Parameters": {
55
"CloudWatchRule": {
66
"Type": "String",

packages/api/amplify_api/example/amplify/backend/function/apiintegmultiauth131fe55a131fe55aPreSignup/apiintegmultiauth131fe55a131fe55aPreSignup-cloudformation-template.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"AWSTemplateFormatVersion": "2010-09-09",
3-
"Description": "{\"createdOn\":\"Mac\",\"createdBy\":\"Amplify\",\"createdWith\":\"9.2.1\",\"stackType\":\"function-Lambda\",\"metadata\":{}}",
3+
"Description": "{\"createdOn\":\"Mac\",\"createdBy\":\"Amplify\",\"createdWith\":\"12.8.2\",\"stackType\":\"function-Lambda\",\"metadata\":{}}",
44
"Parameters": {
55
"DOMAINBLACKLIST": {
66
"Type": "String",

packages/api/amplify_api/example/integration_test/graphql/user_pools_test.dart

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,24 @@ void main({bool useExistingTestUser = false}) {
122122
expect(data.rating, equals(rating));
123123
});
124124

125+
testWidgets('should CREATE a lower case model name with Model helper',
126+
(WidgetTester tester) async {
127+
final name = 'Integration Test lowercase - ${uuid()}';
128+
final model = lowerCase(name: name);
129+
130+
final req = ModelMutations.create(
131+
model,
132+
authorizationMode: APIAuthorizationType.userPools,
133+
);
134+
final res = await Amplify.API.mutate(request: req).response;
135+
expect(res, hasNoGraphQLErrors);
136+
final data = res.data;
137+
if (data != null) lowerCaseCache.add(data);
138+
139+
expect(data?.name, equals(model.name));
140+
expect(data?.id, equals(model.id));
141+
});
142+
125143
testWidgets('should UPDATE a blog with Model helper',
126144
(WidgetTester tester) async {
127145
const oldName = 'Integration Test Blog to update';

packages/api/amplify_api/example/integration_test/util.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ TestUser? testUser;
1919
final blogCache = <Blog>[];
2020
final postCache = <Post>[];
2121
final ownerOnlyCache = <OwnerOnly>[];
22+
final lowerCaseCache = <lowerCase>[];
2223
final cpkParentCache = <CpkOneToOneBidirectionalParentCD>[];
2324
final cpkExplicitChildCache = <CpkOneToOneBidirectionalChildExplicitCD>[];
2425
final cpkImplicitChildCache = <CpkOneToOneBidirectionalChildImplicitCD>[];
@@ -297,12 +298,25 @@ Future<OwnerOnly?> deleteOwnerOnly(OwnerOnly model) async {
297298
return res.data;
298299
}
299300

301+
Future<lowerCase?> deleteLowerCase(lowerCase model) async {
302+
final request = ModelMutations.deleteById(
303+
lowerCase.classType,
304+
model.modelIdentifier,
305+
authorizationMode: APIAuthorizationType.userPools,
306+
);
307+
final res = await Amplify.API.mutate(request: request).response;
308+
expect(res, hasNoGraphQLErrors);
309+
lowerCaseCache.removeWhere((modelFromCache) => modelFromCache.id == model.id);
310+
return res.data;
311+
}
312+
300313
Future<void> deleteTestModels() async {
301314
await Future.wait(blogCache.map(deleteBlog));
302315
await Future.wait(postCache.map(deletePost));
303316
await Future.wait(cpkExplicitChildCache.map(deleteCpkExplicitChild));
304317
await Future.wait(cpkImplicitChildCache.map(deleteCpkImplicitChild));
305318
await Future.wait(ownerOnlyCache.map(deleteOwnerOnly));
319+
await Future.wait(lowerCaseCache.map(deleteLowerCase));
306320
}
307321

308322
/// Wait for subscription established for given request.

packages/api/amplify_api/example/ios/Runner.xcodeproj/project.pbxproj

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/api/amplify_api/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/api/amplify_api/example/lib/models/Blog.dart

Lines changed: 86 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,17 @@
2020
// 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
2121

2222
import 'ModelProvider.dart';
23-
import 'package:amplify_core/amplify_core.dart';
23+
import 'package:amplify_core/amplify_core.dart' as amplify_core;
2424
import 'package:collection/collection.dart';
25-
import 'package:flutter/foundation.dart';
2625

27-
/// This is an auto generated class representing the Blog type in your schema.
28-
@immutable
29-
class Blog extends Model {
30-
static const classType = _BlogModelType();
26+
/** This is an auto generated class representing the Blog type in your schema. */
27+
class Blog extends amplify_core.Model {
28+
static const classType = const _BlogModelType();
3129
final String id;
3230
final String? _name;
3331
final List<Post>? _posts;
34-
final TemporalDateTime? _createdAt;
35-
final TemporalDateTime? _updatedAt;
32+
final amplify_core.TemporalDateTime? _createdAt;
33+
final amplify_core.TemporalDateTime? _updatedAt;
3634

3735
@override
3836
getInstanceType() => classType;
@@ -50,10 +48,10 @@ class Blog extends Model {
5048
try {
5149
return _name!;
5250
} catch (e) {
53-
throw AmplifyCodeGenModelException(
54-
AmplifyExceptionMessages
51+
throw amplify_core.AmplifyCodeGenModelException(
52+
amplify_core.AmplifyExceptionMessages
5553
.codeGenRequiredFieldForceCastExceptionMessage,
56-
recoverySuggestion: AmplifyExceptionMessages
54+
recoverySuggestion: amplify_core.AmplifyExceptionMessages
5755
.codeGenRequiredFieldForceCastRecoverySuggestion,
5856
underlyingException: e.toString());
5957
}
@@ -63,11 +61,11 @@ class Blog extends Model {
6361
return _posts;
6462
}
6563

66-
TemporalDateTime? get createdAt {
64+
amplify_core.TemporalDateTime? get createdAt {
6765
return _createdAt;
6866
}
6967

70-
TemporalDateTime? get updatedAt {
68+
amplify_core.TemporalDateTime? get updatedAt {
7169
return _updatedAt;
7270
}
7371

@@ -80,7 +78,7 @@ class Blog extends Model {
8078

8179
factory Blog({String? id, required String name, List<Post>? posts}) {
8280
return Blog._internal(
83-
id: id == null ? UUID.getUUID() : id,
81+
id: id == null ? amplify_core.UUID.getUUID() : id,
8482
name: name,
8583
posts: posts != null ? List<Post>.unmodifiable(posts) : posts);
8684
}
@@ -103,7 +101,7 @@ class Blog extends Model {
103101

104102
@override
105103
String toString() {
106-
var buffer = StringBuffer();
104+
var buffer = new StringBuffer();
107105

108106
buffer.write("Blog {");
109107
buffer.write("id=" + "$id" + ", ");
@@ -123,21 +121,29 @@ class Blog extends Model {
123121
id: id, name: name ?? this.name, posts: posts ?? this.posts);
124122
}
125123

124+
Blog copyWithModelFieldValues(
125+
{ModelFieldValue<String>? name, ModelFieldValue<List<Post>?>? posts}) {
126+
return Blog._internal(
127+
id: id,
128+
name: name == null ? this.name : name.value,
129+
posts: posts == null ? this.posts : posts.value);
130+
}
131+
126132
Blog.fromJson(Map<String, dynamic> json)
127133
: id = json['id'],
128134
_name = json['name'],
129135
_posts = json['posts'] is List
130136
? (json['posts'] as List)
131137
.where((e) => e?['serializedData'] != null)
132138
.map((e) => Post.fromJson(
133-
Map<String, dynamic>.from(e['serializedData'])))
139+
new Map<String, dynamic>.from(e['serializedData'])))
134140
.toList()
135141
: null,
136142
_createdAt = json['createdAt'] != null
137-
? TemporalDateTime.fromString(json['createdAt'])
143+
? amplify_core.TemporalDateTime.fromString(json['createdAt'])
138144
: null,
139145
_updatedAt = json['updatedAt'] != null
140-
? TemporalDateTime.fromString(json['updatedAt'])
146+
? amplify_core.TemporalDateTime.fromString(json['updatedAt'])
141147
: null;
142148

143149
Map<String, dynamic> toJson() => {
@@ -156,76 +162,84 @@ class Blog extends Model {
156162
'updatedAt': _updatedAt
157163
};
158164

159-
static final QueryModelIdentifier<BlogModelIdentifier> MODEL_IDENTIFIER =
160-
QueryModelIdentifier<BlogModelIdentifier>();
161-
static final QueryField ID = QueryField(fieldName: "id");
162-
static final QueryField NAME = QueryField(fieldName: "name");
163-
static final QueryField POSTS = QueryField(
165+
static final amplify_core.QueryModelIdentifier<BlogModelIdentifier>
166+
MODEL_IDENTIFIER =
167+
amplify_core.QueryModelIdentifier<BlogModelIdentifier>();
168+
static final ID = amplify_core.QueryField(fieldName: "id");
169+
static final NAME = amplify_core.QueryField(fieldName: "name");
170+
static final POSTS = amplify_core.QueryField(
164171
fieldName: "posts",
165-
fieldType: ModelFieldType(ModelFieldTypeEnum.model, ofModelName: 'Post'));
166-
static var schema =
167-
Model.defineSchema(define: (ModelSchemaDefinition modelSchemaDefinition) {
172+
fieldType: amplify_core.ModelFieldType(
173+
amplify_core.ModelFieldTypeEnum.model,
174+
ofModelName: 'Post'));
175+
static var schema = amplify_core.Model.defineSchema(
176+
define: (amplify_core.ModelSchemaDefinition modelSchemaDefinition) {
168177
modelSchemaDefinition.name = "Blog";
169178
modelSchemaDefinition.pluralName = "Blogs";
170179

171180
modelSchemaDefinition.authRules = [
172-
AuthRule(
173-
authStrategy: AuthStrategy.PUBLIC,
174-
provider: AuthRuleProvider.APIKEY,
175-
operations: [ModelOperation.READ]),
176-
AuthRule(
177-
authStrategy: AuthStrategy.PUBLIC,
178-
provider: AuthRuleProvider.IAM,
179-
operations: [ModelOperation.READ]),
180-
AuthRule(
181-
authStrategy: AuthStrategy.PRIVATE,
182-
provider: AuthRuleProvider.IAM,
183-
operations: [ModelOperation.READ]),
184-
AuthRule(
185-
authStrategy: AuthStrategy.PRIVATE,
186-
provider: AuthRuleProvider.USERPOOLS,
187-
operations: [ModelOperation.READ]),
188-
AuthRule(
189-
authStrategy: AuthStrategy.OWNER,
181+
amplify_core.AuthRule(
182+
authStrategy: amplify_core.AuthStrategy.PUBLIC,
183+
provider: amplify_core.AuthRuleProvider.APIKEY,
184+
operations: const [amplify_core.ModelOperation.READ]),
185+
amplify_core.AuthRule(
186+
authStrategy: amplify_core.AuthStrategy.PUBLIC,
187+
provider: amplify_core.AuthRuleProvider.IAM,
188+
operations: const [amplify_core.ModelOperation.READ]),
189+
amplify_core.AuthRule(
190+
authStrategy: amplify_core.AuthStrategy.PRIVATE,
191+
provider: amplify_core.AuthRuleProvider.IAM,
192+
operations: const [amplify_core.ModelOperation.READ]),
193+
amplify_core.AuthRule(
194+
authStrategy: amplify_core.AuthStrategy.PRIVATE,
195+
provider: amplify_core.AuthRuleProvider.USERPOOLS,
196+
operations: const [amplify_core.ModelOperation.READ]),
197+
amplify_core.AuthRule(
198+
authStrategy: amplify_core.AuthStrategy.OWNER,
190199
ownerField: "owner",
191200
identityClaim: "cognito:username",
192-
provider: AuthRuleProvider.USERPOOLS,
193-
operations: [
194-
ModelOperation.CREATE,
195-
ModelOperation.READ,
196-
ModelOperation.UPDATE,
197-
ModelOperation.DELETE
201+
provider: amplify_core.AuthRuleProvider.USERPOOLS,
202+
operations: const [
203+
amplify_core.ModelOperation.CREATE,
204+
amplify_core.ModelOperation.READ,
205+
amplify_core.ModelOperation.UPDATE,
206+
amplify_core.ModelOperation.DELETE
198207
])
199208
];
200209

201-
modelSchemaDefinition.addField(ModelFieldDefinition.id());
210+
modelSchemaDefinition.addField(amplify_core.ModelFieldDefinition.id());
202211

203-
modelSchemaDefinition.addField(ModelFieldDefinition.field(
212+
modelSchemaDefinition.addField(amplify_core.ModelFieldDefinition.field(
204213
key: Blog.NAME,
205214
isRequired: true,
206-
ofType: ModelFieldType(ModelFieldTypeEnum.string)));
215+
ofType: amplify_core.ModelFieldType(
216+
amplify_core.ModelFieldTypeEnum.string)));
207217

208-
modelSchemaDefinition.addField(ModelFieldDefinition.hasMany(
218+
modelSchemaDefinition.addField(amplify_core.ModelFieldDefinition.hasMany(
209219
key: Blog.POSTS,
210220
isRequired: false,
211221
ofModelName: 'Post',
212222
associatedKey: Post.BLOG));
213223

214-
modelSchemaDefinition.addField(ModelFieldDefinition.nonQueryField(
215-
fieldName: 'createdAt',
216-
isRequired: false,
217-
isReadOnly: true,
218-
ofType: ModelFieldType(ModelFieldTypeEnum.dateTime)));
219-
220-
modelSchemaDefinition.addField(ModelFieldDefinition.nonQueryField(
221-
fieldName: 'updatedAt',
222-
isRequired: false,
223-
isReadOnly: true,
224-
ofType: ModelFieldType(ModelFieldTypeEnum.dateTime)));
224+
modelSchemaDefinition.addField(
225+
amplify_core.ModelFieldDefinition.nonQueryField(
226+
fieldName: 'createdAt',
227+
isRequired: false,
228+
isReadOnly: true,
229+
ofType: amplify_core.ModelFieldType(
230+
amplify_core.ModelFieldTypeEnum.dateTime)));
231+
232+
modelSchemaDefinition.addField(
233+
amplify_core.ModelFieldDefinition.nonQueryField(
234+
fieldName: 'updatedAt',
235+
isRequired: false,
236+
isReadOnly: true,
237+
ofType: amplify_core.ModelFieldType(
238+
amplify_core.ModelFieldTypeEnum.dateTime)));
225239
});
226240
}
227241

228-
class _BlogModelType extends ModelType<Blog> {
242+
class _BlogModelType extends amplify_core.ModelType<Blog> {
229243
const _BlogModelType();
230244

231245
@override
@@ -239,13 +253,14 @@ class _BlogModelType extends ModelType<Blog> {
239253
}
240254
}
241255

242-
/// This is an auto generated class representing the model identifier
243-
/// of [Blog] in your schema.
244-
@immutable
245-
class BlogModelIdentifier implements ModelIdentifier<Blog> {
256+
/**
257+
* This is an auto generated class representing the model identifier
258+
* of [Blog] in your schema.
259+
*/
260+
class BlogModelIdentifier implements amplify_core.ModelIdentifier<Blog> {
246261
final String id;
247262

248-
/// Create an instance of BlogModelIdentifier using [id] the primary key.
263+
/** Create an instance of BlogModelIdentifier using [id] the primary key. */
249264
const BlogModelIdentifier({required this.id});
250265

251266
@override

0 commit comments

Comments
 (0)