@aws-amplify/graphql-model-transformer 0.7.0-auth-dir-v-next.3 → 0.7.0-ext12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -19
- package/lib/graphql-model-transformer.d.ts +14 -9
- package/lib/graphql-model-transformer.d.ts.map +1 -1
- package/lib/graphql-model-transformer.js +71 -41
- package/lib/graphql-model-transformer.js.map +1 -1
- package/lib/graphql-types/mutation.d.ts.map +1 -1
- package/lib/graphql-types/mutation.js +2 -5
- package/lib/graphql-types/mutation.js.map +1 -1
- package/lib/graphql-types/query.js +1 -1
- package/lib/graphql-types/query.js.map +1 -1
- package/lib/resolvers/common.js +2 -2
- package/lib/resolvers/common.js.map +1 -1
- package/lib/resolvers/mutation.d.ts.map +1 -1
- package/lib/resolvers/mutation.js +0 -1
- package/lib/resolvers/mutation.js.map +1 -1
- package/lib/resolvers/query.d.ts.map +1 -1
- package/lib/resolvers/query.js +7 -5
- package/lib/resolvers/query.js.map +1 -1
- package/lib/resolvers/subscriptions.js +1 -1
- package/lib/resolvers/subscriptions.js.map +1 -1
- package/lib/wrappers/object-definition-wrapper.d.ts +2 -15
- package/lib/wrappers/object-definition-wrapper.d.ts.map +1 -1
- package/lib/wrappers/object-definition-wrapper.js +7 -43
- package/lib/wrappers/object-definition-wrapper.js.map +1 -1
- package/package.json +34 -32
- package/src/__tests__/__snapshots__/model-transformer.test.ts.snap +515 -796
- package/src/__tests__/model-transformer.test.ts +92 -6
- package/src/graphql-model-transformer.ts +106 -37
- package/src/graphql-types/mutation.ts +2 -4
- package/src/graphql-types/query.ts +1 -1
- package/src/resolvers/common.ts +2 -2
- package/src/resolvers/mutation.ts +0 -3
- package/src/resolvers/query.ts +10 -11
- package/src/resolvers/subscriptions.ts +1 -1
- package/src/wrappers/object-definition-wrapper.ts +2 -52
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
verifyInputCount,
|
|
14
14
|
verifyMatchingTypes,
|
|
15
15
|
} from './test-utils/helpers';
|
|
16
|
+
import { expect as cdkExpect, haveResource } from '@aws-cdk/assert';
|
|
16
17
|
|
|
17
18
|
const featureFlags = {
|
|
18
19
|
getBoolean: jest.fn(),
|
|
@@ -912,7 +913,7 @@ describe('ModelTransformer: ', () => {
|
|
|
912
913
|
validateModelSchema(parse(definition));
|
|
913
914
|
});
|
|
914
915
|
|
|
915
|
-
it('should generate sync resolver with ConflictHandlerType.
|
|
916
|
+
it('should generate sync resolver with ConflictHandlerType.LAMBDA', () => {
|
|
916
917
|
const validSchema = `
|
|
917
918
|
type Post @model {
|
|
918
919
|
id: ID!
|
|
@@ -983,24 +984,109 @@ describe('ModelTransformer: ', () => {
|
|
|
983
984
|
validateModelSchema(parse(definition));
|
|
984
985
|
});
|
|
985
986
|
|
|
986
|
-
it('should
|
|
987
|
+
it('should generate iam role names under 64 chars and subscriptions under 50', () => {
|
|
987
988
|
const validSchema = `
|
|
988
|
-
type
|
|
989
|
-
|
|
990
|
-
type Post @model {
|
|
989
|
+
type ThisIsAVeryLongNameModelThatShouldNotGenerateIAMRoleNamesOver64Characters @model {
|
|
991
990
|
id: ID!
|
|
992
991
|
title: String!
|
|
993
992
|
}
|
|
994
993
|
`;
|
|
995
994
|
|
|
995
|
+
const config: SyncConfig = {
|
|
996
|
+
ConflictDetection: 'VERSION',
|
|
997
|
+
ConflictHandler: ConflictHandlerType.AUTOMERGE,
|
|
998
|
+
};
|
|
999
|
+
|
|
996
1000
|
const transformer = new GraphQLTransform({
|
|
997
1001
|
transformers: [new ModelTransformer()],
|
|
998
1002
|
featureFlags,
|
|
1003
|
+
transformConfig: {
|
|
1004
|
+
ResolverConfig: {
|
|
1005
|
+
project: config,
|
|
1006
|
+
},
|
|
1007
|
+
},
|
|
1008
|
+
});
|
|
1009
|
+
const out = transformer.transform(validSchema);
|
|
1010
|
+
expect(out).toBeDefined();
|
|
1011
|
+
|
|
1012
|
+
const definition = out.schema;
|
|
1013
|
+
expect(definition).toBeDefined();
|
|
1014
|
+
|
|
1015
|
+
const parsed = parse(definition);
|
|
1016
|
+
const subscriptionType = getObjectType(parsed, 'Subscription');
|
|
1017
|
+
expect(subscriptionType).toBeDefined();
|
|
1018
|
+
|
|
1019
|
+
subscriptionType!.fields!.forEach(it => {
|
|
1020
|
+
expect(it.name.value.length <= 50).toBeTruthy();
|
|
1021
|
+
});
|
|
1022
|
+
|
|
1023
|
+
const iamStackResource = out.stacks.ThisIsAVeryLongNameModelThatShouldNotGenerateIAMRoleNamesOver64Characters;
|
|
1024
|
+
expect(iamStackResource).toBeDefined();
|
|
1025
|
+
cdkExpect(iamStackResource).to(
|
|
1026
|
+
haveResource('AWS::IAM::Role', {
|
|
1027
|
+
AssumeRolePolicyDocument: {
|
|
1028
|
+
Statement: [
|
|
1029
|
+
{
|
|
1030
|
+
Action: 'sts:AssumeRole',
|
|
1031
|
+
Effect: 'Allow',
|
|
1032
|
+
Principal: {
|
|
1033
|
+
Service: 'appsync.amazonaws.com',
|
|
1034
|
+
},
|
|
1035
|
+
},
|
|
1036
|
+
],
|
|
1037
|
+
Version: '2012-10-17',
|
|
1038
|
+
},
|
|
1039
|
+
RoleName: {
|
|
1040
|
+
'Fn::Join': [
|
|
1041
|
+
'',
|
|
1042
|
+
[
|
|
1043
|
+
'ThisIsAVeryLongNameM2d9fca-',
|
|
1044
|
+
{
|
|
1045
|
+
Ref: 'referencetotransformerrootstackGraphQLAPI20497F53ApiId',
|
|
1046
|
+
},
|
|
1047
|
+
'-',
|
|
1048
|
+
{
|
|
1049
|
+
Ref: 'referencetotransformerrootstackenv10C5A902Ref',
|
|
1050
|
+
},
|
|
1051
|
+
],
|
|
1052
|
+
],
|
|
1053
|
+
},
|
|
1054
|
+
}),
|
|
1055
|
+
);
|
|
1056
|
+
|
|
1057
|
+
validateModelSchema(parsed);
|
|
1058
|
+
});
|
|
1059
|
+
|
|
1060
|
+
it('should generate the ID field when not specified', () => {
|
|
1061
|
+
const validSchema = `type Todo @model {
|
|
1062
|
+
name: String
|
|
1063
|
+
}`;
|
|
1064
|
+
|
|
1065
|
+
const transformer = new GraphQLTransform({
|
|
1066
|
+
transformers: [new ModelTransformer()],
|
|
999
1067
|
});
|
|
1000
1068
|
|
|
1001
1069
|
const out = transformer.transform(validSchema);
|
|
1002
1070
|
expect(out).toBeDefined();
|
|
1003
1071
|
|
|
1004
|
-
|
|
1072
|
+
const definition = out.schema;
|
|
1073
|
+
expect(definition).toBeDefined();
|
|
1074
|
+
|
|
1075
|
+
const parsed = parse(definition);
|
|
1076
|
+
validateModelSchema(parsed);
|
|
1077
|
+
|
|
1078
|
+
const createTodoInput = getInputType(parsed, 'CreateTodoInput');
|
|
1079
|
+
expect(createTodoInput).toBeDefined();
|
|
1080
|
+
|
|
1081
|
+
expectFieldsOnInputType(createTodoInput!, ['id', 'name']);
|
|
1082
|
+
|
|
1083
|
+
const idField = createTodoInput!.fields!.find(f => f.name.value === 'id');
|
|
1084
|
+
expect((idField!.type as NamedTypeNode).name!.value).toEqual('ID');
|
|
1085
|
+
expect((idField!.type as NamedTypeNode).kind).toEqual('NamedType');
|
|
1086
|
+
|
|
1087
|
+
const updateTodoInput = getInputType(parsed, 'UpdateTodoInput');
|
|
1088
|
+
expect(updateTodoInput).toBeDefined();
|
|
1089
|
+
|
|
1090
|
+
expectFieldsOnInputType(updateTodoInput!, ['name']);
|
|
1005
1091
|
});
|
|
1006
1092
|
});
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
DirectiveWrapper,
|
|
3
|
+
InvalidDirectiveError,
|
|
4
|
+
MappingTemplate,
|
|
5
|
+
SyncConfig,
|
|
6
|
+
SyncUtils,
|
|
7
|
+
TransformerModelBase,
|
|
8
|
+
} from '@aws-amplify/graphql-transformer-core';
|
|
2
9
|
import {
|
|
3
10
|
AppSyncDataSourceType,
|
|
4
11
|
DataSourceInstance,
|
|
@@ -37,6 +44,7 @@ import {
|
|
|
37
44
|
makeValueNode,
|
|
38
45
|
ModelResourceIDs,
|
|
39
46
|
plurality,
|
|
47
|
+
ResolverResourceIDs,
|
|
40
48
|
ResourceConstants,
|
|
41
49
|
SyncResourceIDs,
|
|
42
50
|
toCamelCase,
|
|
@@ -71,13 +79,9 @@ import {
|
|
|
71
79
|
generateListRequestTemplate,
|
|
72
80
|
generateSyncRequestTemplate,
|
|
73
81
|
} from './resolvers/query';
|
|
74
|
-
import {
|
|
75
|
-
DirectiveWrapper,
|
|
76
|
-
FieldWrapper,
|
|
77
|
-
InputObjectDefinitionWrapper,
|
|
78
|
-
ObjectDefinitionWrapper,
|
|
79
|
-
} from './wrappers/object-definition-wrapper';
|
|
82
|
+
import { FieldWrapper, InputObjectDefinitionWrapper, ObjectDefinitionWrapper } from './wrappers/object-definition-wrapper';
|
|
80
83
|
import { CfnRole } from '@aws-cdk/aws-iam';
|
|
84
|
+
import md5 from 'md5';
|
|
81
85
|
|
|
82
86
|
export type Nullable<T> = T | null;
|
|
83
87
|
export type OptionalAndNullable<T> = Partial<T>;
|
|
@@ -176,14 +180,17 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
176
180
|
}
|
|
177
181
|
// todo: get model configuration with default values and store it in the map
|
|
178
182
|
const typeName = definition.name.value;
|
|
183
|
+
|
|
184
|
+
if (ctx.isProjectUsingDataStore()) {
|
|
185
|
+
SyncUtils.validateResolverConfigForType(ctx, typeName);
|
|
186
|
+
}
|
|
187
|
+
|
|
179
188
|
const directiveWrapped: DirectiveWrapper = new DirectiveWrapper(directive);
|
|
180
189
|
const options = directiveWrapped.getArguments({
|
|
181
190
|
queries: {
|
|
182
191
|
get: toCamelCase(['get', typeName]),
|
|
183
192
|
list: toCamelCase(['list', plurality(typeName, true)]),
|
|
184
|
-
...(
|
|
185
|
-
? { sync: toCamelCase(['sync', plurality(typeName, true)]) }
|
|
186
|
-
: undefined),
|
|
193
|
+
...(ctx.isProjectUsingDataStore() ? { sync: toCamelCase(['sync', plurality(typeName, true)]) } : undefined),
|
|
187
194
|
},
|
|
188
195
|
mutations: {
|
|
189
196
|
create: toCamelCase(['create', typeName]),
|
|
@@ -192,9 +199,9 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
192
199
|
},
|
|
193
200
|
subscriptions: {
|
|
194
201
|
level: SubscriptionLevel.on,
|
|
195
|
-
onCreate: [toCamelCase(['onCreate', typeName])],
|
|
196
|
-
onDelete: [toCamelCase(['onDelete', typeName])],
|
|
197
|
-
onUpdate: [toCamelCase(['onUpdate', typeName])],
|
|
202
|
+
onCreate: [this.ensureValidSubscriptionName(toCamelCase(['onCreate', typeName]))],
|
|
203
|
+
onDelete: [this.ensureValidSubscriptionName(toCamelCase(['onDelete', typeName]))],
|
|
204
|
+
onUpdate: [this.ensureValidSubscriptionName(toCamelCase(['onUpdate', typeName]))],
|
|
198
205
|
},
|
|
199
206
|
timestamps: {
|
|
200
207
|
createdAt: 'createdAt',
|
|
@@ -237,7 +244,6 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
237
244
|
this.addAutoGeneratableFields(ctx, type);
|
|
238
245
|
|
|
239
246
|
if (ctx.isProjectUsingDataStore()) {
|
|
240
|
-
this.options.SyncConfig = SyncUtils.getSyncConfig(ctx as TransformerContextProvider, def!.name.value);
|
|
241
247
|
this.addModelSyncFields(ctx, type);
|
|
242
248
|
}
|
|
243
249
|
}
|
|
@@ -257,13 +263,13 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
257
263
|
let resolver;
|
|
258
264
|
switch (query.type) {
|
|
259
265
|
case QueryFieldType.GET:
|
|
260
|
-
resolver = this.generateGetResolver(context, def!, query.typeName, query.fieldName);
|
|
266
|
+
resolver = this.generateGetResolver(context, def!, query.typeName, query.fieldName, query.resolverLogicalId);
|
|
261
267
|
break;
|
|
262
268
|
case QueryFieldType.LIST:
|
|
263
|
-
resolver = this.generateListResolver(context, def!, query.typeName, query.fieldName);
|
|
269
|
+
resolver = this.generateListResolver(context, def!, query.typeName, query.fieldName, query.resolverLogicalId);
|
|
264
270
|
break;
|
|
265
271
|
case QueryFieldType.SYNC:
|
|
266
|
-
resolver = this.generateSyncResolver(context, def!, query.typeName, query.fieldName);
|
|
272
|
+
resolver = this.generateSyncResolver(context, def!, query.typeName, query.fieldName, query.resolverLogicalId);
|
|
267
273
|
break;
|
|
268
274
|
default:
|
|
269
275
|
throw new Error('Unknown query field type');
|
|
@@ -284,13 +290,13 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
284
290
|
let resolver;
|
|
285
291
|
switch (mutation.type) {
|
|
286
292
|
case MutationFieldType.CREATE:
|
|
287
|
-
resolver = this.generateCreateResolver(context, def!, mutation.typeName, mutation.fieldName);
|
|
293
|
+
resolver = this.generateCreateResolver(context, def!, mutation.typeName, mutation.fieldName, mutation.resolverLogicalId);
|
|
288
294
|
break;
|
|
289
295
|
case MutationFieldType.DELETE:
|
|
290
|
-
resolver = this.generateDeleteResolver(context, def!, mutation.typeName, mutation.fieldName);
|
|
296
|
+
resolver = this.generateDeleteResolver(context, def!, mutation.typeName, mutation.fieldName, mutation.resolverLogicalId);
|
|
291
297
|
break;
|
|
292
298
|
case MutationFieldType.UPDATE:
|
|
293
|
-
resolver = this.generateUpdateResolver(context, def!, mutation.typeName, mutation.fieldName);
|
|
299
|
+
resolver = this.generateUpdateResolver(context, def!, mutation.typeName, mutation.fieldName, mutation.resolverLogicalId);
|
|
294
300
|
break;
|
|
295
301
|
default:
|
|
296
302
|
throw new Error('Unknown mutation field type');
|
|
@@ -314,13 +320,31 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
314
320
|
let resolver;
|
|
315
321
|
switch (subscription.type) {
|
|
316
322
|
case SubscriptionFieldType.ON_CREATE:
|
|
317
|
-
resolver = this.generateOnCreateResolver(
|
|
323
|
+
resolver = this.generateOnCreateResolver(
|
|
324
|
+
context,
|
|
325
|
+
def,
|
|
326
|
+
subscription.typeName,
|
|
327
|
+
subscription.fieldName,
|
|
328
|
+
subscription.resolverLogicalId,
|
|
329
|
+
);
|
|
318
330
|
break;
|
|
319
331
|
case SubscriptionFieldType.ON_UPDATE:
|
|
320
|
-
resolver = this.generateOnUpdateResolver(
|
|
332
|
+
resolver = this.generateOnUpdateResolver(
|
|
333
|
+
context,
|
|
334
|
+
def,
|
|
335
|
+
subscription.typeName,
|
|
336
|
+
subscription.fieldName,
|
|
337
|
+
subscription.resolverLogicalId,
|
|
338
|
+
);
|
|
321
339
|
break;
|
|
322
340
|
case SubscriptionFieldType.ON_DELETE:
|
|
323
|
-
resolver = this.generateOnDeleteResolver(
|
|
341
|
+
resolver = this.generateOnDeleteResolver(
|
|
342
|
+
context,
|
|
343
|
+
def,
|
|
344
|
+
subscription.typeName,
|
|
345
|
+
subscription.fieldName,
|
|
346
|
+
subscription.resolverLogicalId,
|
|
347
|
+
);
|
|
324
348
|
break;
|
|
325
349
|
default:
|
|
326
350
|
throw new Error('Unknown subscription field type');
|
|
@@ -344,6 +368,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
344
368
|
type: ObjectTypeDefinitionNode,
|
|
345
369
|
typeName: string,
|
|
346
370
|
fieldName: string,
|
|
371
|
+
resolverLogicalId: string,
|
|
347
372
|
): TransformerResolverProvider => {
|
|
348
373
|
const isSyncEnabled = ctx.isProjectUsingDataStore();
|
|
349
374
|
const dataSource = this.datasourceMap[type.name.value];
|
|
@@ -352,6 +377,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
352
377
|
this.resolverMap[resolverKey] = ctx.resolvers.generateQueryResolver(
|
|
353
378
|
typeName,
|
|
354
379
|
fieldName,
|
|
380
|
+
resolverLogicalId,
|
|
355
381
|
dataSource,
|
|
356
382
|
MappingTemplate.s3MappingTemplateFromString(generateGetRequestTemplate(), `${typeName}.${fieldName}.req.vtl`),
|
|
357
383
|
MappingTemplate.s3MappingTemplateFromString(generateGetResponseTemplate(isSyncEnabled), `${typeName}.${fieldName}.res.vtl`),
|
|
@@ -365,6 +391,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
365
391
|
type: ObjectTypeDefinitionNode,
|
|
366
392
|
typeName: string,
|
|
367
393
|
fieldName: string,
|
|
394
|
+
resolverLogicalId: string,
|
|
368
395
|
): TransformerResolverProvider => {
|
|
369
396
|
const isSyncEnabled = ctx.isProjectUsingDataStore();
|
|
370
397
|
const dataSource = this.datasourceMap[type.name.value];
|
|
@@ -373,6 +400,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
373
400
|
this.resolverMap[resolverKey] = ctx.resolvers.generateQueryResolver(
|
|
374
401
|
typeName,
|
|
375
402
|
fieldName,
|
|
403
|
+
resolverLogicalId,
|
|
376
404
|
dataSource,
|
|
377
405
|
MappingTemplate.s3MappingTemplateFromString(generateListRequestTemplate(), `${typeName}.${fieldName}.req.vtl`),
|
|
378
406
|
MappingTemplate.s3MappingTemplateFromString(
|
|
@@ -389,6 +417,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
389
417
|
type: ObjectTypeDefinitionNode,
|
|
390
418
|
typeName: string,
|
|
391
419
|
fieldName: string,
|
|
420
|
+
resolverLogicalId: string,
|
|
392
421
|
): TransformerResolverProvider => {
|
|
393
422
|
const isSyncEnabled = ctx.isProjectUsingDataStore();
|
|
394
423
|
const dataSource = this.datasourceMap[type.name.value];
|
|
@@ -397,6 +426,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
397
426
|
const resolver = ctx.resolvers.generateMutationResolver(
|
|
398
427
|
typeName,
|
|
399
428
|
fieldName,
|
|
429
|
+
resolverLogicalId,
|
|
400
430
|
dataSource,
|
|
401
431
|
MappingTemplate.s3MappingTemplateFromString(
|
|
402
432
|
generateUpdateRequestTemplate(typeName, isSyncEnabled),
|
|
@@ -424,6 +454,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
424
454
|
type: ObjectTypeDefinitionNode,
|
|
425
455
|
typeName: string,
|
|
426
456
|
fieldName: string,
|
|
457
|
+
resolverLogicalId: string,
|
|
427
458
|
): TransformerResolverProvider => {
|
|
428
459
|
const isSyncEnabled = ctx.isProjectUsingDataStore();
|
|
429
460
|
const dataSource = this.datasourceMap[type.name.value];
|
|
@@ -432,6 +463,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
432
463
|
this.resolverMap[resolverKey] = ctx.resolvers.generateMutationResolver(
|
|
433
464
|
typeName,
|
|
434
465
|
fieldName,
|
|
466
|
+
resolverLogicalId,
|
|
435
467
|
dataSource,
|
|
436
468
|
MappingTemplate.s3MappingTemplateFromString(generateDeleteRequestTemplate(isSyncEnabled), `${typeName}.${fieldName}.req.vtl`),
|
|
437
469
|
MappingTemplate.s3MappingTemplateFromString(
|
|
@@ -448,12 +480,14 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
448
480
|
type: ObjectTypeDefinitionNode,
|
|
449
481
|
typeName: string,
|
|
450
482
|
fieldName: string,
|
|
483
|
+
resolverLogicalId: string,
|
|
451
484
|
): TransformerResolverProvider => {
|
|
452
485
|
const resolverKey = `OnCreate${generateResolverKey(typeName, fieldName)}`;
|
|
453
486
|
if (!this.resolverMap[resolverKey]) {
|
|
454
487
|
this.resolverMap[resolverKey] = ctx.resolvers.generateSubscriptionResolver(
|
|
455
488
|
typeName,
|
|
456
489
|
fieldName,
|
|
490
|
+
resolverLogicalId,
|
|
457
491
|
MappingTemplate.s3MappingTemplateFromString(generateSubscriptionRequestTemplate(), `${typeName}.${fieldName}.req.vtl`),
|
|
458
492
|
MappingTemplate.s3MappingTemplateFromString(generateSubscriptionResponseTemplate(), `${typeName}.${fieldName}.res.vtl`),
|
|
459
493
|
);
|
|
@@ -465,12 +499,14 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
465
499
|
type: ObjectTypeDefinitionNode,
|
|
466
500
|
typeName: string,
|
|
467
501
|
fieldName: string,
|
|
502
|
+
resolverLogicalId: string,
|
|
468
503
|
): TransformerResolverProvider => {
|
|
469
504
|
const resolverKey = `OnUpdate${generateResolverKey(typeName, fieldName)}`;
|
|
470
505
|
if (!this.resolverMap[resolverKey]) {
|
|
471
506
|
this.resolverMap[resolverKey] = ctx.resolvers.generateSubscriptionResolver(
|
|
472
507
|
typeName,
|
|
473
508
|
fieldName,
|
|
509
|
+
resolverLogicalId,
|
|
474
510
|
MappingTemplate.s3MappingTemplateFromString(generateSubscriptionRequestTemplate(), `${typeName}.${fieldName}.req.vtl`),
|
|
475
511
|
MappingTemplate.s3MappingTemplateFromString(generateSubscriptionResponseTemplate(), `${typeName}.${fieldName}.res.vtl`),
|
|
476
512
|
);
|
|
@@ -482,12 +518,14 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
482
518
|
type: ObjectTypeDefinitionNode,
|
|
483
519
|
typeName: string,
|
|
484
520
|
fieldName: string,
|
|
521
|
+
resolverLogicalId: string,
|
|
485
522
|
): TransformerResolverProvider => {
|
|
486
523
|
const resolverKey = `OnDelete${generateResolverKey(typeName, fieldName)}`;
|
|
487
524
|
if (!this.resolverMap[resolverKey]) {
|
|
488
525
|
this.resolverMap[resolverKey] = ctx.resolvers.generateSubscriptionResolver(
|
|
489
526
|
typeName,
|
|
490
527
|
fieldName,
|
|
528
|
+
resolverLogicalId,
|
|
491
529
|
MappingTemplate.s3MappingTemplateFromString(generateSubscriptionRequestTemplate(), `${typeName}.${fieldName}.req.vtl`),
|
|
492
530
|
MappingTemplate.s3MappingTemplateFromString(generateSubscriptionResponseTemplate(), `${typeName}.${fieldName}.res.vtl`),
|
|
493
531
|
);
|
|
@@ -499,6 +537,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
499
537
|
type: ObjectTypeDefinitionNode,
|
|
500
538
|
typeName: string,
|
|
501
539
|
fieldName: string,
|
|
540
|
+
resolverLogicalId: string,
|
|
502
541
|
): TransformerResolverProvider => {
|
|
503
542
|
const isSyncEnabled = ctx.isProjectUsingDataStore();
|
|
504
543
|
const dataSource = this.datasourceMap[type.name.value];
|
|
@@ -507,6 +546,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
507
546
|
this.resolverMap[resolverKey] = ctx.resolvers.generateQueryResolver(
|
|
508
547
|
typeName,
|
|
509
548
|
fieldName,
|
|
549
|
+
resolverLogicalId,
|
|
510
550
|
dataSource,
|
|
511
551
|
MappingTemplate.s3MappingTemplateFromString(generateSyncRequestTemplate(), `${typeName}.${fieldName}.req.vtl`),
|
|
512
552
|
MappingTemplate.s3MappingTemplateFromString(
|
|
@@ -521,15 +561,16 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
521
561
|
getQueryFieldNames = (
|
|
522
562
|
ctx: TransformerTransformSchemaStepContextProvider,
|
|
523
563
|
type: ObjectTypeDefinitionNode,
|
|
524
|
-
): Set<{ fieldName: string; typeName: string; type: QueryFieldType }> => {
|
|
564
|
+
): Set<{ fieldName: string; typeName: string; type: QueryFieldType; resolverLogicalId: string }> => {
|
|
525
565
|
const typeName = type.name.value;
|
|
526
|
-
const fields: Set<{ fieldName: string; typeName: string; type: QueryFieldType }> = new Set();
|
|
566
|
+
const fields: Set<{ fieldName: string; typeName: string; type: QueryFieldType; resolverLogicalId: string }> = new Set();
|
|
527
567
|
const modelDirectiveConfig = this.modelDirectiveConfig.get(type.name.value);
|
|
528
568
|
if (modelDirectiveConfig?.queries?.get) {
|
|
529
569
|
fields.add({
|
|
530
570
|
typeName: 'Query',
|
|
531
571
|
fieldName: modelDirectiveConfig.queries.get || toCamelCase(['get', typeName]),
|
|
532
572
|
type: QueryFieldType.GET,
|
|
573
|
+
resolverLogicalId: ResolverResourceIDs.DynamoDBGetResolverResourceID(typeName),
|
|
533
574
|
});
|
|
534
575
|
}
|
|
535
576
|
|
|
@@ -538,6 +579,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
538
579
|
typeName: 'Query',
|
|
539
580
|
fieldName: modelDirectiveConfig.queries.list || toCamelCase(['list', typeName]),
|
|
540
581
|
type: QueryFieldType.LIST,
|
|
582
|
+
resolverLogicalId: ResolverResourceIDs.DynamoDBListResolverResourceID(typeName),
|
|
541
583
|
});
|
|
542
584
|
}
|
|
543
585
|
|
|
@@ -546,6 +588,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
546
588
|
typeName: 'Query',
|
|
547
589
|
fieldName: modelDirectiveConfig.queries.sync || toCamelCase(['sync', typeName]),
|
|
548
590
|
type: QueryFieldType.SYNC,
|
|
591
|
+
resolverLogicalId: ResolverResourceIDs.SyncResolverResourceID(typeName),
|
|
549
592
|
});
|
|
550
593
|
}
|
|
551
594
|
|
|
@@ -555,7 +598,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
555
598
|
getMutationFieldNames = (
|
|
556
599
|
ctx: TransformerTransformSchemaStepContextProvider,
|
|
557
600
|
type: ObjectTypeDefinitionNode,
|
|
558
|
-
): Set<{ fieldName: string; typeName: string; type: MutationFieldType }> => {
|
|
601
|
+
): Set<{ fieldName: string; typeName: string; type: MutationFieldType; resolverLogicalId: string }> => {
|
|
559
602
|
// Todo: get fields names from the directives
|
|
560
603
|
const typeName = type.name.value;
|
|
561
604
|
const modelDirectiveConfig = this.modelDirectiveConfig.get(typeName);
|
|
@@ -572,13 +615,27 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
572
615
|
}
|
|
573
616
|
};
|
|
574
617
|
|
|
575
|
-
const
|
|
618
|
+
const getMutationResolverLogicalId = (type: string): string => {
|
|
619
|
+
switch (type) {
|
|
620
|
+
case 'create':
|
|
621
|
+
return ResolverResourceIDs.DynamoDBCreateResolverResourceID(typeName);
|
|
622
|
+
case 'update':
|
|
623
|
+
return ResolverResourceIDs.DynamoDBUpdateResolverResourceID(typeName);
|
|
624
|
+
case 'delete':
|
|
625
|
+
return ResolverResourceIDs.DynamoDBDeleteResolverResourceID(typeName);
|
|
626
|
+
default:
|
|
627
|
+
throw new Error('Unknown mutation type');
|
|
628
|
+
}
|
|
629
|
+
};
|
|
630
|
+
|
|
631
|
+
const fieldNames: Set<{ fieldName: string; typeName: string; type: MutationFieldType; resolverLogicalId: string }> = new Set();
|
|
576
632
|
for (let [mutationType, mutationName] of Object.entries(modelDirectiveConfig?.mutations || {})) {
|
|
577
633
|
if (mutationName) {
|
|
578
634
|
fieldNames.add({
|
|
579
635
|
typeName: 'Mutation',
|
|
580
636
|
fieldName: mutationName,
|
|
581
637
|
type: getMutationType(mutationType),
|
|
638
|
+
resolverLogicalId: getMutationResolverLogicalId(mutationType),
|
|
582
639
|
});
|
|
583
640
|
}
|
|
584
641
|
}
|
|
@@ -592,6 +649,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
592
649
|
fieldName: string;
|
|
593
650
|
typeName: string;
|
|
594
651
|
type: MutationFieldType;
|
|
652
|
+
resolverLogicalId: string;
|
|
595
653
|
}>,
|
|
596
654
|
): string => {
|
|
597
655
|
const mutationToSubscriptionTypeMap = {
|
|
@@ -677,11 +735,13 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
677
735
|
fieldName: string;
|
|
678
736
|
typeName: string;
|
|
679
737
|
type: SubscriptionFieldType;
|
|
738
|
+
resolverLogicalId: string;
|
|
680
739
|
}> => {
|
|
681
740
|
const fields: Set<{
|
|
682
741
|
fieldName: string;
|
|
683
742
|
typeName: string;
|
|
684
743
|
type: SubscriptionFieldType;
|
|
744
|
+
resolverLogicalId: string;
|
|
685
745
|
}> = new Set();
|
|
686
746
|
|
|
687
747
|
const modelDirectiveConfig = this.modelDirectiveConfig.get(type.name.value);
|
|
@@ -692,6 +752,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
692
752
|
typeName: 'Subscription',
|
|
693
753
|
fieldName: fieldName,
|
|
694
754
|
type: SubscriptionFieldType.ON_CREATE,
|
|
755
|
+
resolverLogicalId: ModelResourceIDs.ModelOnCreateSubscriptionName(type.name.value),
|
|
695
756
|
});
|
|
696
757
|
}
|
|
697
758
|
}
|
|
@@ -702,6 +763,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
702
763
|
typeName: 'Subscription',
|
|
703
764
|
fieldName: fieldName,
|
|
704
765
|
type: SubscriptionFieldType.ON_UPDATE,
|
|
766
|
+
resolverLogicalId: ModelResourceIDs.ModelOnUpdateSubscriptionName(type.name.value),
|
|
705
767
|
});
|
|
706
768
|
}
|
|
707
769
|
}
|
|
@@ -712,6 +774,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
712
774
|
typeName: 'Subscription',
|
|
713
775
|
fieldName: fieldName,
|
|
714
776
|
type: SubscriptionFieldType.ON_DELETE,
|
|
777
|
+
resolverLogicalId: ModelResourceIDs.ModelOnDeleteSubscriptionName(type.name.value),
|
|
715
778
|
});
|
|
716
779
|
}
|
|
717
780
|
}
|
|
@@ -734,6 +797,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
734
797
|
type: ObjectTypeDefinitionNode,
|
|
735
798
|
typeName: string,
|
|
736
799
|
fieldName: string,
|
|
800
|
+
resolverLogicalId: string,
|
|
737
801
|
): TransformerResolverProvider => {
|
|
738
802
|
const isSyncEnabled = ctx.isProjectUsingDataStore();
|
|
739
803
|
const dataSource = this.datasourceMap[type.name.value];
|
|
@@ -742,6 +806,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
742
806
|
const resolver = ctx.resolvers.generateMutationResolver(
|
|
743
807
|
typeName,
|
|
744
808
|
fieldName,
|
|
809
|
+
resolverLogicalId,
|
|
745
810
|
dataSource,
|
|
746
811
|
MappingTemplate.s3MappingTemplateFromString(generateCreateRequestTemplate(type.name.value), `${typeName}.${fieldName}.req.vtl`),
|
|
747
812
|
MappingTemplate.s3MappingTemplateFromString(
|
|
@@ -1072,7 +1137,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
1072
1137
|
stream: StreamViewType.NEW_AND_OLD_IMAGES,
|
|
1073
1138
|
encryption: TableEncryption.DEFAULT,
|
|
1074
1139
|
removalPolicy: removalPolicy,
|
|
1075
|
-
...(
|
|
1140
|
+
...(context.isProjectUsingDataStore() ? { timeToLiveAttribute: '_ttl' } : undefined),
|
|
1076
1141
|
});
|
|
1077
1142
|
const cfnTable = table.node.defaultChild as CfnTable;
|
|
1078
1143
|
|
|
@@ -1128,8 +1193,9 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
1128
1193
|
|
|
1129
1194
|
const cfnDataSource = dataSource.node.defaultChild as CfnDataSource;
|
|
1130
1195
|
cfnDataSource.addDependsOn(role.node.defaultChild as CfnRole);
|
|
1196
|
+
cfnDataSource.overrideLogicalId(datasourceRoleLogicalID);
|
|
1131
1197
|
|
|
1132
|
-
if (
|
|
1198
|
+
if (context.isProjectUsingDataStore()) {
|
|
1133
1199
|
const datasourceDynamoDb = cfnDataSource.dynamoDbConfig as any;
|
|
1134
1200
|
datasourceDynamoDb.deltaSyncConfig = {
|
|
1135
1201
|
deltaSyncTableName: context.resourceHelper.generateResourceName(SyncResourceIDs.syncTableName),
|
|
@@ -1153,7 +1219,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
1153
1219
|
}
|
|
1154
1220
|
|
|
1155
1221
|
private createIAMRole(context: TransformerContextProvider, def: ObjectTypeDefinitionNode, stack: cdk.Stack, tableName: string) {
|
|
1156
|
-
const roleName = context.resourceHelper.
|
|
1222
|
+
const roleName = context.resourceHelper.generateIAMRoleName(ModelResourceIDs.ModelTableIAMRoleID(def!.name.value));
|
|
1157
1223
|
const role = new iam.Role(stack, ModelResourceIDs.ModelTableIAMRoleID(def!.name.value), {
|
|
1158
1224
|
roleName: roleName,
|
|
1159
1225
|
assumedBy: new iam.ServicePrincipal('appsync.amazonaws.com'),
|
|
@@ -1184,7 +1250,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
1184
1250
|
cdk.Fn.sub('arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tablename}/*', {
|
|
1185
1251
|
tablename: tableName,
|
|
1186
1252
|
}),
|
|
1187
|
-
...(
|
|
1253
|
+
...(context.isProjectUsingDataStore()
|
|
1188
1254
|
? [
|
|
1189
1255
|
// eslint-disable-next-line no-template-curly-in-string
|
|
1190
1256
|
cdk.Fn.sub('arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tablename}', {
|
|
@@ -1202,13 +1268,10 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
1202
1268
|
}),
|
|
1203
1269
|
);
|
|
1204
1270
|
|
|
1205
|
-
|
|
1271
|
+
const syncConfig = SyncUtils.getSyncConfig(context, def!.name.value);
|
|
1272
|
+
if (syncConfig && SyncUtils.isLambdaSyncConfig(syncConfig)) {
|
|
1206
1273
|
role.attachInlinePolicy(
|
|
1207
|
-
SyncUtils.createSyncLambdaIAMPolicy(
|
|
1208
|
-
stack,
|
|
1209
|
-
this.options.SyncConfig.LambdaConflictHandler.name,
|
|
1210
|
-
this.options.SyncConfig.LambdaConflictHandler.region,
|
|
1211
|
-
),
|
|
1274
|
+
SyncUtils.createSyncLambdaIAMPolicy(stack, syncConfig.LambdaConflictHandler.name, syncConfig.LambdaConflictHandler.region),
|
|
1212
1275
|
);
|
|
1213
1276
|
}
|
|
1214
1277
|
return role;
|
|
@@ -1228,4 +1291,10 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
1228
1291
|
...options,
|
|
1229
1292
|
};
|
|
1230
1293
|
};
|
|
1294
|
+
|
|
1295
|
+
private ensureValidSubscriptionName = (name: string): string => {
|
|
1296
|
+
if (name.length <= 50) return name;
|
|
1297
|
+
|
|
1298
|
+
return name.slice(0, 45) + md5(name).slice(0, 5);
|
|
1299
|
+
};
|
|
1231
1300
|
}
|
|
@@ -45,9 +45,7 @@ export const makeUpdateInputField = (
|
|
|
45
45
|
input.fields.forEach(f => f.makeNullable());
|
|
46
46
|
|
|
47
47
|
// Add id field and make it optional
|
|
48
|
-
if (
|
|
49
|
-
input.addField(InputFieldWrapper.create('id', 'ID', false));
|
|
50
|
-
} else {
|
|
48
|
+
if (hasIdField) {
|
|
51
49
|
const idField = input.fields.find(f => f.name === 'id');
|
|
52
50
|
if (idField) {
|
|
53
51
|
idField.makeNonNullable();
|
|
@@ -127,7 +125,7 @@ export const makeCreateInputField = (
|
|
|
127
125
|
|
|
128
126
|
// Add id field and make it optional
|
|
129
127
|
if (!hasIdField) {
|
|
130
|
-
input.addField(InputFieldWrapper.create('id', 'ID'));
|
|
128
|
+
input.addField(InputFieldWrapper.create('id', 'ID', true));
|
|
131
129
|
} else {
|
|
132
130
|
const idField = input.fields.find(f => f.name === 'id');
|
|
133
131
|
if (idField) {
|
|
@@ -13,7 +13,7 @@ export const makeListQueryFilterInput = (
|
|
|
13
13
|
export const makeListQueryModel = (type: ObjectTypeDefinitionNode, modelName: string, isSyncEnabled: boolean): ObjectTypeDefinitionNode => {
|
|
14
14
|
const outputType = ObjectDefinitionWrapper.create(modelName);
|
|
15
15
|
|
|
16
|
-
outputType.addField(FieldWrapper.create('items', type.name.value,
|
|
16
|
+
outputType.addField(FieldWrapper.create('items', type.name.value, false, true));
|
|
17
17
|
outputType.addField(FieldWrapper.create('nextToken', 'String', true, false));
|
|
18
18
|
|
|
19
19
|
if (isSyncEnabled) {
|
package/src/resolvers/common.ts
CHANGED
|
@@ -99,13 +99,13 @@ export const generateResolverKey = (typeName: string, fieldName: string): string
|
|
|
99
99
|
* @param ctx context to get sandbox mode
|
|
100
100
|
*/
|
|
101
101
|
export const generateAuthExpressionForSandboxMode = (ctx: any): string => {
|
|
102
|
-
|
|
102
|
+
const enabled = ctx.resourceHelper.api.sandboxModeEnabled;
|
|
103
103
|
let exp;
|
|
104
104
|
|
|
105
105
|
if (enabled) exp = iff(notEquals(methodCall(ref('util.authType')), str(API_KEY)), methodCall(ref('util.unauthorized')));
|
|
106
106
|
else exp = methodCall(ref('util.unauthorized'));
|
|
107
107
|
|
|
108
108
|
return printBlock(`Sandbox Mode ${enabled ? 'Enabled' : 'Disabled'}`)(
|
|
109
|
-
compoundExpression([iff(not(ref('ctx.stash.get("hasAuth")')), exp)]),
|
|
109
|
+
compoundExpression([iff(not(ref('ctx.stash.get("hasAuth")')), exp), toJson(obj({}))]),
|
|
110
110
|
);
|
|
111
111
|
};
|
|
@@ -152,8 +152,6 @@ export const generateUpdateRequestTemplate = (modelName: string, isSyncEnabled:
|
|
|
152
152
|
*/
|
|
153
153
|
export const generateCreateRequestTemplate = (modelName: string): string => {
|
|
154
154
|
const statements: Expression[] = [
|
|
155
|
-
// set key the condition
|
|
156
|
-
...generateKeyConditionTemplate(false),
|
|
157
155
|
// Generate conditions
|
|
158
156
|
comment('Set the default values to put request'),
|
|
159
157
|
set(ref('mergedValues'), methodCall(ref('util.defaultIfNull'), ref('ctx.stash.defaultValues'), obj({}))),
|
|
@@ -174,7 +172,6 @@ export const generateCreateRequestTemplate = (modelName: string): string => {
|
|
|
174
172
|
),
|
|
175
173
|
|
|
176
174
|
// add conditions
|
|
177
|
-
|
|
178
175
|
iff(ref('context.args.condition'), qref(methodCall(ref('ctx.stash.conditions.add'), ref('context.args.condition')))),
|
|
179
176
|
// key conditions
|
|
180
177
|
...generateKeyConditionTemplate(false),
|