@aws-amplify/graphql-model-transformer 0.13.4 → 0.13.5-beta.2

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.
@@ -27,7 +27,9 @@ import {
27
27
  TransformerValidationStepContextProvider,
28
28
  TransformerBeforeStepContextProvider,
29
29
  } from '@aws-amplify/graphql-transformer-interfaces';
30
- import { AttributeType, CfnTable, ITable, StreamViewType, Table, TableEncryption } from '@aws-cdk/aws-dynamodb';
30
+ import {
31
+ AttributeType, CfnTable, ITable, StreamViewType, Table, TableEncryption,
32
+ } from '@aws-cdk/aws-dynamodb';
31
33
  import * as iam from '@aws-cdk/aws-iam';
32
34
  import * as cdk from '@aws-cdk/core';
33
35
  import { CfnDataSource } from '@aws-cdk/aws-appsync';
@@ -55,6 +57,7 @@ import {
55
57
  toCamelCase,
56
58
  toPascalCase,
57
59
  } from 'graphql-transformer-common';
60
+ import { CfnRole } from '@aws-cdk/aws-iam';
58
61
  import {
59
62
  addDirectivesToOperation,
60
63
  addModelConditionInputs,
@@ -87,40 +90,13 @@ import {
87
90
  generateListRequestTemplate,
88
91
  generateSyncRequestTemplate,
89
92
  } from './resolvers/query';
90
- import { CfnRole } from '@aws-cdk/aws-iam';
91
- import md5 from 'md5';
92
93
  import { API_KEY_DIRECTIVE } from './definitions';
94
+ import { SubscriptionLevel, ModelDirectiveConfiguration } from './directive';
93
95
 
96
+ /**
97
+ * Nullable
98
+ */
94
99
  export type Nullable<T> = T | null;
95
- export type OptionalAndNullable<T> = Partial<T>;
96
-
97
- export enum SubscriptionLevel {
98
- off = 'off',
99
- public = 'public',
100
- on = 'on',
101
- }
102
- export type ModelDirectiveConfiguration = {
103
- queries?: OptionalAndNullable<{
104
- get: OptionalAndNullable<string>;
105
- list: OptionalAndNullable<string>;
106
- sync: OptionalAndNullable<string>;
107
- }>;
108
- mutations: OptionalAndNullable<{
109
- create: OptionalAndNullable<string>;
110
- update: OptionalAndNullable<string>;
111
- delete: OptionalAndNullable<string>;
112
- }>;
113
- subscriptions: OptionalAndNullable<{
114
- onCreate: OptionalAndNullable<string>[];
115
- onUpdate: OptionalAndNullable<string>[];
116
- onDelete: OptionalAndNullable<string>[];
117
- level: SubscriptionLevel;
118
- }>;
119
- timestamps: OptionalAndNullable<{
120
- createdAt: OptionalAndNullable<string>;
121
- updatedAt: OptionalAndNullable<string>;
122
- }>;
123
- };
124
100
 
125
101
  export const directiveDefinition = /* GraphQl */ `
126
102
  directive @model(
@@ -160,6 +136,9 @@ type ModelTransformerOptions = {
160
136
  SyncConfig?: SyncConfig;
161
137
  };
162
138
 
139
+ /**
140
+ * ModelTransformer
141
+ */
163
142
  export class ModelTransformer extends TransformerModelBase implements TransformerModelProvider {
164
143
  private options: ModelTransformerOptions;
165
144
  private datasourceMap: Record<string, DataSourceProvider> = {};
@@ -175,7 +154,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
175
154
  this.options = this.getOptions(options);
176
155
  }
177
156
 
178
- before = (ctx: TransformerBeforeStepContextProvider) => {
157
+ before = (ctx: TransformerBeforeStepContextProvider): void => {
179
158
  // add model related-parameters to the root stack
180
159
  ctx.stackManager.addParameter(ResourceConstants.PARAMETERS.DynamoDBModelTableReadIOPS, {
181
160
  description: 'The number of read IOPS the table should support.',
@@ -207,10 +186,9 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
207
186
  };
208
187
 
209
188
  object = (definition: ObjectTypeDefinitionNode, directive: DirectiveNode, ctx: TransformerSchemaVisitStepContextProvider): void => {
210
- const isTypeNameReserved =
211
- definition.name.value === ctx.output.getQueryTypeName() ||
212
- definition.name.value === ctx.output.getMutationTypeName() ||
213
- definition.name.value === ctx.output.getSubscriptionTypeName();
189
+ const isTypeNameReserved = definition.name.value === ctx.output.getQueryTypeName()
190
+ || definition.name.value === ctx.output.getMutationTypeName()
191
+ || definition.name.value === ctx.output.getSubscriptionTypeName();
214
192
 
215
193
  if (isTypeNameReserved) {
216
194
  throw new InvalidDirectiveError(
@@ -264,12 +242,11 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
264
242
  this.typesWithModelDirective.add(typeName);
265
243
  };
266
244
 
267
- validate = () => {};
268
- prepare = (context: TransformerPrepareStepContextProvider) => {
269
- for (const modelTypeName of this.typesWithModelDirective) {
245
+ prepare = (context: TransformerPrepareStepContextProvider): void => {
246
+ this.typesWithModelDirective.forEach(modelTypeName => {
270
247
  const type = context.output.getObject(modelTypeName);
271
248
  context.providerRegistry.registerDataSourceProvider(type!, this);
272
- }
249
+ });
273
250
  };
274
251
 
275
252
  transformSchema = (ctx: TransformerTransformSchemaStepContextProvider): void => {
@@ -277,7 +254,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
277
254
  addModelConditionInputs(ctx);
278
255
 
279
256
  this.ensureModelSortDirectionEnum(ctx);
280
- for (const type of this.typesWithModelDirective) {
257
+ this.typesWithModelDirective.forEach(type => {
281
258
  const def = ctx.output.getObject(type)!;
282
259
  const hasAuth = def.directives!.some(dir => dir.name.value === 'auth');
283
260
 
@@ -304,24 +281,24 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
304
281
  const apiKeyDirArray = [makeDirective(API_KEY_DIRECTIVE, [])];
305
282
  extendTypeWithDirectives(ctx, def.name.value, apiKeyDirArray);
306
283
  propagateApiKeyToNestedTypes(ctx as TransformerContextProvider, def, new Set<string>());
307
- for (let operationField of queryFields) {
284
+ queryFields.forEach(operationField => {
308
285
  const operationName = operationField.name.value;
309
286
  addDirectivesToOperation(ctx, ctx.output.getQueryTypeName()!, operationName, apiKeyDirArray);
310
- }
311
- for (let operationField of mutationFields) {
287
+ });
288
+ mutationFields.forEach(operationField => {
312
289
  const operationName = operationField.name.value;
313
290
  addDirectivesToOperation(ctx, ctx.output.getMutationTypeName()!, operationName, apiKeyDirArray);
314
- }
315
- for (let operationField of subscriptionsFields) {
291
+ });
292
+ subscriptionsFields.forEach(operationField => {
316
293
  const operationName = operationField.name.value;
317
294
  addDirectivesToOperation(ctx, ctx.output.getSubscriptionTypeName()!, operationName, apiKeyDirArray);
318
- }
295
+ });
319
296
  }
320
- }
297
+ });
321
298
  };
322
299
 
323
300
  generateResolvers = (context: TransformerContextProvider): void => {
324
- for (let type of this.typesWithModelDirective) {
301
+ this.typesWithModelDirective.forEach(type => {
325
302
  const def = context.output.getObject(type)!;
326
303
  // This name is used by the mock functionality. Changing this can break mock.
327
304
  const tableBaseName = context.resourceHelper.getModelNameMapping(def!.name.value);
@@ -330,8 +307,8 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
330
307
 
331
308
  this.createModelTable(stack, def!, context);
332
309
 
333
- const queryFields = this.getQueryFieldNames(context, def!);
334
- for (let query of queryFields.values()) {
310
+ const queryFields = this.getQueryFieldNames(def!);
311
+ queryFields.forEach(query => {
335
312
  let resolver;
336
313
  switch (query.type) {
337
314
  case QueryFieldType.GET:
@@ -357,10 +334,10 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
357
334
  );
358
335
  resolver.mapToStack(context.stackManager.getStackFor(query.resolverLogicalId, def!.name.value));
359
336
  context.resolvers.addResolver(query.typeName, query.fieldName, resolver);
360
- }
337
+ });
361
338
 
362
- const mutationFields = this.getMutationFieldNames(context, def!);
363
- for (let mutation of mutationFields.values()) {
339
+ const mutationFields = this.getMutationFieldNames(def!);
340
+ mutationFields.forEach(mutation => {
364
341
  let resolver;
365
342
  switch (mutation.type) {
366
343
  case MutationFieldType.CREATE:
@@ -384,19 +361,18 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
384
361
  );
385
362
  resolver.mapToStack(context.stackManager.getStackFor(mutation.resolverLogicalId, def!.name.value));
386
363
  context.resolvers.addResolver(mutation.typeName, mutation.fieldName, resolver);
387
- }
364
+ });
388
365
 
389
366
  const subscriptionLevel = this.modelDirectiveConfig.get(def.name.value)?.subscriptions?.level;
390
367
  // in order to create subscription resolvers the level needs to be on
391
368
  if (subscriptionLevel === SubscriptionLevel.on) {
392
- const subscriptionFields = this.getSubscriptionFieldNames(context, def!);
393
- for (let subscription of subscriptionFields.values()) {
369
+ const subscriptionFields = this.getSubscriptionFieldNames(def!);
370
+ subscriptionFields.forEach(subscription => {
394
371
  let resolver;
395
372
  switch (subscription.type) {
396
373
  case SubscriptionFieldType.ON_CREATE:
397
374
  resolver = this.generateOnCreateResolver(
398
375
  context,
399
- def,
400
376
  subscription.typeName,
401
377
  subscription.fieldName,
402
378
  subscription.resolverLogicalId,
@@ -405,7 +381,6 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
405
381
  case SubscriptionFieldType.ON_UPDATE:
406
382
  resolver = this.generateOnUpdateResolver(
407
383
  context,
408
- def,
409
384
  subscription.typeName,
410
385
  subscription.fieldName,
411
386
  subscription.resolverLogicalId,
@@ -414,7 +389,6 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
414
389
  case SubscriptionFieldType.ON_DELETE:
415
390
  resolver = this.generateOnDeleteResolver(
416
391
  context,
417
- def,
418
392
  subscription.typeName,
419
393
  subscription.fieldName,
420
394
  subscription.resolverLogicalId,
@@ -432,9 +406,9 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
432
406
  );
433
407
  resolver.mapToStack(context.stackManager.getStackFor(subscription.resolverLogicalId, def!.name.value));
434
408
  context.resolvers.addResolver(subscription.typeName, subscription.fieldName, resolver);
435
- }
409
+ });
436
410
  }
437
- }
411
+ });
438
412
  };
439
413
 
440
414
  generateGetResolver = (
@@ -515,7 +489,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
515
489
  resolver.addToSlot(
516
490
  'init',
517
491
  MappingTemplate.s3MappingTemplateFromString(
518
- generateUpdateInitSlotTemplate(type.name.value, this.modelDirectiveConfig.get(type.name.value)!),
492
+ generateUpdateInitSlotTemplate(this.modelDirectiveConfig.get(type.name.value)!),
519
493
  `${typeName}.${fieldName}.{slotName}.{slotIndex}.req.vtl`,
520
494
  ),
521
495
  );
@@ -523,6 +497,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
523
497
  }
524
498
  return this.resolverMap[resolverKey];
525
499
  };
500
+
526
501
  generateDeleteResolver = (
527
502
  ctx: TransformerContextProvider,
528
503
  type: ObjectTypeDefinitionNode,
@@ -551,7 +526,6 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
551
526
 
552
527
  generateOnCreateResolver = (
553
528
  ctx: TransformerContextProvider,
554
- type: ObjectTypeDefinitionNode,
555
529
  typeName: string,
556
530
  fieldName: string,
557
531
  resolverLogicalId: string,
@@ -568,9 +542,9 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
568
542
  }
569
543
  return this.resolverMap[resolverKey];
570
544
  };
545
+
571
546
  generateOnUpdateResolver = (
572
547
  ctx: TransformerContextProvider,
573
- type: ObjectTypeDefinitionNode,
574
548
  typeName: string,
575
549
  fieldName: string,
576
550
  resolverLogicalId: string,
@@ -587,9 +561,9 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
587
561
  }
588
562
  return this.resolverMap[resolverKey];
589
563
  };
564
+
590
565
  generateOnDeleteResolver = (
591
566
  ctx: TransformerContextProvider,
592
- type: ObjectTypeDefinitionNode,
593
567
  typeName: string,
594
568
  fieldName: string,
595
569
  resolverLogicalId: string,
@@ -606,6 +580,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
606
580
  }
607
581
  return this.resolverMap[resolverKey];
608
582
  };
583
+
609
584
  generateSyncResolver = (
610
585
  ctx: TransformerContextProvider,
611
586
  type: ObjectTypeDefinitionNode,
@@ -633,7 +608,6 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
633
608
  };
634
609
 
635
610
  getQueryFieldNames = (
636
- ctx: TransformerTransformSchemaStepContextProvider,
637
611
  type: ObjectTypeDefinitionNode,
638
612
  ): Set<{ fieldName: string; typeName: string; type: QueryFieldType; resolverLogicalId: string }> => {
639
613
  const typeName = type.name.value;
@@ -670,14 +644,13 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
670
644
  };
671
645
 
672
646
  getMutationFieldNames = (
673
- ctx: TransformerTransformSchemaStepContextProvider,
674
647
  type: ObjectTypeDefinitionNode,
675
648
  ): Set<{ fieldName: string; typeName: string; type: MutationFieldType; resolverLogicalId: string }> => {
676
649
  // Todo: get fields names from the directives
677
650
  const typeName = type.name.value;
678
651
  const modelDirectiveConfig = this.modelDirectiveConfig.get(typeName);
679
- const getMutationType = (type: string): MutationFieldType => {
680
- switch (type) {
652
+ const getMutationType = (mutationType: string): MutationFieldType => {
653
+ switch (mutationType) {
681
654
  case 'create':
682
655
  return MutationFieldType.CREATE;
683
656
  case 'update':
@@ -689,8 +662,8 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
689
662
  }
690
663
  };
691
664
 
692
- const getMutationResolverLogicalId = (type: string): string => {
693
- switch (type) {
665
+ const getMutationResolverLogicalId = (mutationType: string): string => {
666
+ switch (mutationType) {
694
667
  case 'create':
695
668
  return ResolverResourceIDs.DynamoDBCreateResolverResourceID(typeName);
696
669
  case 'update':
@@ -703,7 +676,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
703
676
  };
704
677
 
705
678
  const fieldNames: Set<{ fieldName: string; typeName: string; type: MutationFieldType; resolverLogicalId: string }> = new Set();
706
- for (let [mutationType, mutationName] of Object.entries(modelDirectiveConfig?.mutations || {})) {
679
+ Object.entries(modelDirectiveConfig?.mutations || {}).forEach(([mutationType, mutationName]) => {
707
680
  if (mutationName) {
708
681
  fieldNames.add({
709
682
  typeName: 'Mutation',
@@ -712,7 +685,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
712
685
  resolverLogicalId: getMutationResolverLogicalId(mutationType),
713
686
  });
714
687
  }
715
- }
688
+ });
716
689
 
717
690
  return fieldNames;
718
691
  };
@@ -731,7 +704,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
731
704
  [SubscriptionFieldType.ON_UPDATE]: MutationFieldType.UPDATE,
732
705
  [SubscriptionFieldType.ON_DELETE]: MutationFieldType.DELETE,
733
706
  };
734
- const mutation = Array.from(mutationMap).find(m => m.type == mutationToSubscriptionTypeMap[subscriptionType]);
707
+ const mutation = Array.from(mutationMap).find(m => m.type === mutationToSubscriptionTypeMap[subscriptionType]);
735
708
  if (mutation) {
736
709
  return mutation.fieldName;
737
710
  }
@@ -740,8 +713,8 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
740
713
 
741
714
  private createQueryFields = (ctx: TransformerValidationStepContextProvider, def: ObjectTypeDefinitionNode): FieldDefinitionNode[] => {
742
715
  const queryFields: FieldDefinitionNode[] = [];
743
- const queryFieldNames = this.getQueryFieldNames(ctx, def!);
744
- for (const queryField of queryFieldNames.values()) {
716
+ const queryFieldNames = this.getQueryFieldNames(def!);
717
+ queryFieldNames.forEach(queryField => {
745
718
  const outputType = this.getOutputType(ctx, def, queryField);
746
719
  const args = this.getInputs(ctx, def!, {
747
720
  fieldName: queryField.fieldName,
@@ -749,15 +722,15 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
749
722
  type: queryField.type,
750
723
  });
751
724
  queryFields.push(makeField(queryField.fieldName, args, makeNamedType(outputType.name.value)));
752
- }
725
+ });
753
726
 
754
727
  return queryFields;
755
728
  };
756
729
 
757
730
  private createMutationFields = (ctx: TransformerValidationStepContextProvider, def: ObjectTypeDefinitionNode): FieldDefinitionNode[] => {
758
731
  const mutationFields: FieldDefinitionNode[] = [];
759
- const mutationFieldNames = this.getMutationFieldNames(ctx, def!);
760
- for (const mutationField of mutationFieldNames) {
732
+ const mutationFieldNames = this.getMutationFieldNames(def!);
733
+ mutationFieldNames.forEach(mutationField => {
761
734
  const args = this.getInputs(ctx, def!, {
762
735
  fieldName: mutationField.fieldName,
763
736
  typeName: mutationField.typeName,
@@ -765,7 +738,8 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
765
738
  });
766
739
 
767
740
  mutationFields.push(makeField(mutationField.fieldName, args, makeNamedType(def!.name.value)));
768
- }
741
+ });
742
+
769
743
  return mutationFields;
770
744
  };
771
745
 
@@ -773,23 +747,22 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
773
747
  ctx: TransformerTransformSchemaStepContextProvider,
774
748
  def: ObjectTypeDefinitionNode,
775
749
  ): FieldDefinitionNode[] => {
776
- const subscriptionToMutationsMap = this.getSubscriptionToMutationsReverseMap(ctx, def);
777
- const mutationFields = this.getMutationFieldNames(ctx, def!);
750
+ const subscriptionToMutationsMap = this.getSubscriptionToMutationsReverseMap(def);
751
+ const mutationFields = this.getMutationFieldNames(def!);
778
752
 
779
753
  const subscriptionFields: FieldDefinitionNode[] = [];
780
- for (const subscriptionFieldName of Object.keys(subscriptionToMutationsMap)) {
754
+
755
+ Object.keys(subscriptionToMutationsMap).forEach(subscriptionFieldName => {
781
756
  const maps = subscriptionToMutationsMap[subscriptionFieldName];
782
757
 
783
758
  const args: InputValueDefinitionNode[] = [];
784
- maps.map(it =>
785
- args.concat(
786
- this.getInputs(ctx, def!, {
787
- fieldName: it.fieldName,
788
- typeName: it.typeName,
789
- type: it.type,
790
- }),
791
- ),
792
- );
759
+ maps.map(it => args.concat(
760
+ this.getInputs(ctx, def!, {
761
+ fieldName: it.fieldName,
762
+ typeName: it.typeName,
763
+ type: it.type,
764
+ }),
765
+ ));
793
766
 
794
767
  const mutationNames = maps.map(it => this.getMutationName(it.type, mutationFields));
795
768
 
@@ -797,13 +770,12 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
797
770
  const directive = makeDirective('aws_subscribe', [makeArgument('mutations', makeValueNode(mutationNames))]);
798
771
  const field = makeField(subscriptionFieldName, args, makeNamedType(def!.name.value), [directive]);
799
772
  subscriptionFields.push(field);
800
- }
773
+ });
801
774
 
802
775
  return subscriptionFields;
803
776
  };
804
777
 
805
778
  getSubscriptionFieldNames = (
806
- ctx: TransformerTransformSchemaStepContextProvider,
807
779
  type: ObjectTypeDefinitionNode,
808
780
  ): Set<{
809
781
  fieldName: string;
@@ -821,50 +793,46 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
821
793
  const modelDirectiveConfig = this.modelDirectiveConfig.get(type.name.value);
822
794
  if (modelDirectiveConfig?.subscriptions?.level !== SubscriptionLevel.off) {
823
795
  if (modelDirectiveConfig?.subscriptions?.onCreate && modelDirectiveConfig.mutations?.create) {
824
- for (const fieldName of modelDirectiveConfig.subscriptions.onCreate) {
796
+ modelDirectiveConfig.subscriptions.onCreate.forEach((fieldName: string) => {
825
797
  fields.add({
826
798
  typeName: 'Subscription',
827
- fieldName: fieldName,
799
+ fieldName,
828
800
  type: SubscriptionFieldType.ON_CREATE,
829
801
  resolverLogicalId: ResolverResourceIDs.ResolverResourceID('Subscription', fieldName),
830
802
  });
831
- }
803
+ });
832
804
  }
833
805
 
834
806
  if (modelDirectiveConfig?.subscriptions?.onUpdate && modelDirectiveConfig.mutations?.update) {
835
- for (const fieldName of modelDirectiveConfig.subscriptions.onUpdate) {
807
+ modelDirectiveConfig.subscriptions.onUpdate.forEach((fieldName: string) => {
836
808
  fields.add({
837
809
  typeName: 'Subscription',
838
- fieldName: fieldName,
810
+ fieldName,
839
811
  type: SubscriptionFieldType.ON_UPDATE,
840
812
  resolverLogicalId: ResolverResourceIDs.ResolverResourceID('Subscription', fieldName),
841
813
  });
842
- }
814
+ });
843
815
  }
844
816
 
845
817
  if (modelDirectiveConfig?.subscriptions?.onDelete && modelDirectiveConfig.mutations?.delete) {
846
- for (const fieldName of modelDirectiveConfig.subscriptions.onDelete) {
818
+ modelDirectiveConfig.subscriptions.onDelete.forEach((fieldName: string) => {
847
819
  fields.add({
848
820
  typeName: 'Subscription',
849
- fieldName: fieldName,
821
+ fieldName,
850
822
  type: SubscriptionFieldType.ON_DELETE,
851
823
  resolverLogicalId: ResolverResourceIDs.ResolverResourceID('Subscription', fieldName),
852
824
  });
853
- }
825
+ });
854
826
  }
855
827
  }
856
828
 
857
829
  return fields;
858
830
  };
859
831
 
860
- getDataSourceResource = (ctx: TransformerContextProvider, type: ObjectTypeDefinitionNode): DataSourceInstance => {
861
- // Todo: add sanity check to ensure the type has an table
862
- return this.ddbTableMap[type.name.value];
863
- };
832
+ // Todo: add sanity check to ensure the type has an table
833
+ getDataSourceResource = (type: ObjectTypeDefinitionNode): DataSourceInstance => this.ddbTableMap[type.name.value];
864
834
 
865
- getDataSourceType = (): AppSyncDataSourceType => {
866
- return AppSyncDataSourceType.AMAZON_DYNAMODB;
867
- };
835
+ getDataSourceType = (): AppSyncDataSourceType => AppSyncDataSourceType.AMAZON_DYNAMODB;
868
836
 
869
837
  generateCreateResolver = (
870
838
  ctx: TransformerContextProvider,
@@ -876,13 +844,14 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
876
844
  const isSyncEnabled = ctx.isProjectUsingDataStore();
877
845
  const dataSource = this.datasourceMap[type.name.value];
878
846
  const resolverKey = `Create${generateResolverKey(typeName, fieldName)}`;
847
+ const modelIndexFields = type.fields!.filter(field => field.directives?.some(it => it.name.value === 'index')).map(it => it.name.value);
879
848
  if (!this.resolverMap[resolverKey]) {
880
849
  const resolver = ctx.resolvers.generateMutationResolver(
881
850
  typeName,
882
851
  fieldName,
883
852
  resolverLogicalId,
884
853
  dataSource,
885
- MappingTemplate.s3MappingTemplateFromString(generateCreateRequestTemplate(type.name.value), `${typeName}.${fieldName}.req.vtl`),
854
+ MappingTemplate.s3MappingTemplateFromString(generateCreateRequestTemplate(type.name.value, modelIndexFields), `${typeName}.${fieldName}.req.vtl`),
886
855
  MappingTemplate.s3MappingTemplateFromString(
887
856
  generateDefaultResponseMappingTemplate(isSyncEnabled, true),
888
857
  `${typeName}.${fieldName}.res.vtl`,
@@ -892,7 +861,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
892
861
  resolver.addToSlot(
893
862
  'init',
894
863
  MappingTemplate.s3MappingTemplateFromString(
895
- generateCreateInitSlotTemplate(type.name.value, this.modelDirectiveConfig.get(type.name.value)!),
864
+ generateCreateInitSlotTemplate(this.modelDirectiveConfig.get(type.name.value)!),
896
865
  `${typeName}.${fieldName}.{slotName}.{slotIndex}.req.vtl`,
897
866
  ),
898
867
  );
@@ -919,34 +888,35 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
919
888
  const filterInputs = createEnumModelFilters(ctx, type);
920
889
  conditionInput = makeMutationConditionInput(ctx, conditionTypeName, type);
921
890
  filterInputs.push(conditionInput);
922
- for (let input of filterInputs) {
891
+ filterInputs.forEach(input => {
923
892
  const conditionInputName = input.name.value;
924
893
  if (!ctx.output.getType(conditionInputName)) {
925
894
  ctx.output.addInput(input);
926
895
  }
927
- }
896
+ });
928
897
  }
929
898
  switch (operation.type) {
930
899
  case QueryFieldType.GET:
931
900
  return [makeInputValueDefinition('id', makeNonNullType(makeNamedType('ID')))];
932
901
 
933
- case QueryFieldType.LIST:
902
+ case QueryFieldType.LIST: {
934
903
  const filterInputName = toPascalCase(['Model', type.name.value, 'FilterInput']);
935
904
  const filterInputs = createEnumModelFilters(ctx, type);
936
905
  filterInputs.push(makeListQueryFilterInput(ctx, filterInputName, type));
937
- for (let input of filterInputs) {
906
+ filterInputs.forEach(input => {
938
907
  const conditionInputName = input.name.value;
939
908
  if (!ctx.output.getType(conditionInputName)) {
940
909
  ctx.output.addInput(input);
941
910
  }
942
- }
911
+ });
943
912
 
944
913
  return [
945
914
  makeInputValueDefinition('filter', makeNamedType(filterInputName)),
946
915
  makeInputValueDefinition('limit', makeNamedType('Int')),
947
916
  makeInputValueDefinition('nextToken', makeNamedType('String')),
948
917
  ];
949
- case QueryFieldType.SYNC:
918
+ }
919
+ case QueryFieldType.SYNC: {
950
920
  const syncFilterInputName = toPascalCase(['Model', type.name.value, 'FilterInput']);
951
921
  const syncFilterInputs = makeListQueryFilterInput(ctx, syncFilterInputName, type);
952
922
  const conditionInputName = syncFilterInputs.name.value;
@@ -959,8 +929,8 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
959
929
  makeInputValueDefinition('nextToken', makeNamedType('String')),
960
930
  makeInputValueDefinition('lastSync', makeNamedType('AWSTimestamp')),
961
931
  ];
962
-
963
- case MutationFieldType.CREATE:
932
+ }
933
+ case MutationFieldType.CREATE: {
964
934
  const createInputField = makeCreateInputField(
965
935
  type,
966
936
  this.modelDirectiveConfig.get(type.name.value)!,
@@ -976,8 +946,8 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
976
946
  makeInputValueDefinition('input', makeNonNullType(makeNamedType(createInputTypeName))),
977
947
  makeInputValueDefinition('condition', makeNamedType(conditionInput!.name.value)),
978
948
  ];
979
-
980
- case MutationFieldType.DELETE:
949
+ }
950
+ case MutationFieldType.DELETE: {
981
951
  const deleteInputField = makeDeleteInputField(type, isSyncEnabled);
982
952
  const deleteInputTypeName = deleteInputField.name.value;
983
953
  if (!ctx.output.getType(deleteInputField.name.value)) {
@@ -987,8 +957,8 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
987
957
  makeInputValueDefinition('input', makeNonNullType(makeNamedType(deleteInputTypeName))),
988
958
  makeInputValueDefinition('condition', makeNamedType(conditionInput!.name.value)),
989
959
  ];
990
-
991
- case MutationFieldType.UPDATE:
960
+ }
961
+ case MutationFieldType.UPDATE: {
992
962
  const updateInputField = makeUpdateInputField(
993
963
  type,
994
964
  this.modelDirectiveConfig.get(type.name.value)!,
@@ -1004,17 +974,15 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
1004
974
  makeInputValueDefinition('input', makeNonNullType(makeNamedType(updateInputTypeName))),
1005
975
  makeInputValueDefinition('condition', makeNamedType(conditionInput!.name.value)),
1006
976
  ];
1007
-
977
+ }
1008
978
  case SubscriptionFieldType.ON_CREATE:
1009
979
  case SubscriptionFieldType.ON_DELETE:
1010
980
  case SubscriptionFieldType.ON_UPDATE:
1011
981
  return [];
1012
- break;
1013
982
 
1014
983
  default:
1015
984
  throw new Error('Unknown operation type');
1016
985
  }
1017
- return [];
1018
986
  };
1019
987
 
1020
988
  getOutputType = (
@@ -1038,11 +1006,12 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
1038
1006
  outputType = type;
1039
1007
  break;
1040
1008
  case QueryFieldType.SYNC:
1041
- case QueryFieldType.LIST:
1009
+ case QueryFieldType.LIST: {
1042
1010
  const isSyncEnabled = ctx.isProjectUsingDataStore();
1043
1011
  const connectionFieldName = toPascalCase(['Model', type.name.value, 'Connection']);
1044
1012
  outputType = makeListQueryModel(type, connectionFieldName, isSyncEnabled);
1045
1013
  break;
1014
+ }
1046
1015
  default:
1047
1016
  throw new Error(`${operation.type} not supported for ${type.name.value}`);
1048
1017
  }
@@ -1053,10 +1022,10 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
1053
1022
  };
1054
1023
 
1055
1024
  private createNonModelInputs = (ctx: TransformerTransformSchemaStepContextProvider, obj: ObjectTypeDefinitionNode): void => {
1056
- for (let field of obj.fields || []) {
1025
+ (obj.fields ?? []).forEach(field => {
1057
1026
  if (!isScalar(field.type)) {
1058
1027
  const def = ctx.output.getType(getBaseType(field.type));
1059
- if (def && def.kind == 'ObjectTypeDefinition' && !this.isModelField(def.name.value)) {
1028
+ if (def && def.kind === 'ObjectTypeDefinition' && !this.isModelField(def.name.value)) {
1060
1029
  const name = this.getNonModelInputObjectName(def.name.value);
1061
1030
  if (!ctx.output.getType(name)) {
1062
1031
  const inputObj = InputObjectDefinitionWrapper.fromObject(name, def, ctx.inputDocument);
@@ -1065,18 +1034,16 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
1065
1034
  }
1066
1035
  }
1067
1036
  }
1068
- }
1069
- };
1070
- private isModelField = (name: string): boolean => {
1071
- return this.typesWithModelDirective.has(name) ? true : false;
1037
+ });
1072
1038
  };
1073
1039
 
1074
- private getNonModelInputObjectName = (name: string): string => {
1075
- return `${name}Input`;
1076
- };
1040
+ private isModelField = (name: string): boolean => (!!this.typesWithModelDirective.has(name));
1041
+
1042
+ private getNonModelInputObjectName = (name: string): string => `${name}Input`;
1077
1043
 
1078
1044
  /**
1079
1045
  * Model directive automatically adds id, created and updated time stamps to the filed, if they are configured
1046
+ * @param ctx transform context
1080
1047
  * @param name Name of the type
1081
1048
  */
1082
1049
  private addAutoGeneratableFields = (ctx: TransformerTransformSchemaStepContextProvider, name: string): void => {
@@ -1103,7 +1070,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
1103
1070
  }
1104
1071
  }
1105
1072
 
1106
- for (let fieldName of timestamps) {
1073
+ timestamps.forEach(fieldName => {
1107
1074
  if (typeWrapper.hasField(fieldName)) {
1108
1075
  const field = typeWrapper.getField(fieldName);
1109
1076
  if (!['String', 'AWSDateTime'].includes(field.getTypeName())) {
@@ -1113,7 +1080,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
1113
1080
  const field = FieldWrapper.create(fieldName, 'AWSDateTime');
1114
1081
  typeWrapper.addField(field);
1115
1082
  }
1116
- }
1083
+ });
1117
1084
 
1118
1085
  ctx.output.updateObject(typeWrapper.serialize());
1119
1086
  };
@@ -1133,23 +1100,22 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
1133
1100
  };
1134
1101
 
1135
1102
  private getSubscriptionToMutationsReverseMap = (
1136
- ctx: TransformerValidationStepContextProvider,
1137
1103
  def: ObjectTypeDefinitionNode,
1138
1104
  ): { [subField: string]: { fieldName: string; typeName: string; type: SubscriptionFieldType }[] } => {
1139
1105
  const subscriptionToMutationsMap: { [subField: string]: { fieldName: string; typeName: string; type: SubscriptionFieldType }[] } = {};
1140
- const subscriptionFieldNames = this.getSubscriptionFieldNames(ctx, def);
1106
+ const subscriptionFieldNames = this.getSubscriptionFieldNames(def);
1141
1107
 
1142
- for (const subscriptionFieldName of subscriptionFieldNames) {
1108
+ subscriptionFieldNames.forEach(subscriptionFieldName => {
1143
1109
  if (!subscriptionToMutationsMap[subscriptionFieldName.fieldName]) {
1144
1110
  subscriptionToMutationsMap[subscriptionFieldName.fieldName] = [];
1145
1111
  }
1146
1112
  subscriptionToMutationsMap[subscriptionFieldName.fieldName].push(subscriptionFieldName);
1147
- }
1113
+ });
1148
1114
 
1149
1115
  return subscriptionToMutationsMap;
1150
1116
  };
1151
1117
 
1152
- private createModelTable(stack: cdk.Stack, def: ObjectTypeDefinitionNode, context: TransformerContextProvider) {
1118
+ private createModelTable(stack: cdk.Stack, def: ObjectTypeDefinitionNode, context: TransformerContextProvider): void {
1153
1119
  const tableLogicalName = ModelResourceIDs.ModelTableResourceID(def!.name.value);
1154
1120
  const tableName = context.resourceHelper.generateTableName(def!.name.value);
1155
1121
 
@@ -1222,7 +1188,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
1222
1188
  },
1223
1189
  stream: StreamViewType.NEW_AND_OLD_IMAGES,
1224
1190
  encryption: TableEncryption.DEFAULT,
1225
- removalPolicy: removalPolicy,
1191
+ removalPolicy,
1226
1192
  ...(context.isProjectUsingDataStore() ? { timeToLiveAttribute: '_ttl' } : undefined),
1227
1193
  });
1228
1194
  const cfnTable = table.node.defaultChild as CfnTable;
@@ -1269,7 +1235,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
1269
1235
  stack: cdk.Stack,
1270
1236
  role: iam.Role,
1271
1237
  dataSourceLogicalName: string,
1272
- ) {
1238
+ ): void {
1273
1239
  const datasourceRoleLogicalID = ModelResourceIDs.ModelTableDataSourceID(def!.name.value);
1274
1240
  const dataSource = context.api.host.addDynamoDbDataSource(
1275
1241
  datasourceRoleLogicalID,
@@ -1282,6 +1248,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
1282
1248
  cfnDataSource.addDependsOn(role.node.defaultChild as CfnRole);
1283
1249
 
1284
1250
  if (context.isProjectUsingDataStore()) {
1251
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1285
1252
  const datasourceDynamoDb = cfnDataSource.dynamoDbConfig as any;
1286
1253
  datasourceDynamoDb.deltaSyncConfig = {
1287
1254
  deltaSyncTableName: context.resourceHelper.generateTableName(SyncResourceIDs.syncTableName),
@@ -1304,10 +1271,13 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
1304
1271
  this.datasourceMap[def!.name.value] = dataSource;
1305
1272
  }
1306
1273
 
1307
- private createIAMRole(context: TransformerContextProvider, def: ObjectTypeDefinitionNode, stack: cdk.Stack, tableName: string) {
1274
+ /**
1275
+ * createIAMRole
1276
+ */
1277
+ createIAMRole = (context: TransformerContextProvider, def: ObjectTypeDefinitionNode, stack: cdk.Stack, tableName: string): iam.Role => {
1308
1278
  const roleName = context.resourceHelper.generateIAMRoleName(ModelResourceIDs.ModelTableIAMRoleID(def!.name.value));
1309
1279
  const role = new iam.Role(stack, ModelResourceIDs.ModelTableIAMRoleID(def!.name.value), {
1310
- roleName: roleName,
1280
+ roleName,
1311
1281
  assumedBy: new iam.ServicePrincipal('appsync.amazonaws.com'),
1312
1282
  });
1313
1283
 
@@ -1338,15 +1308,15 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
1338
1308
  }),
1339
1309
  ...(context.isProjectUsingDataStore()
1340
1310
  ? [
1341
- // eslint-disable-next-line no-template-curly-in-string
1342
- cdk.Fn.sub('arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tablename}', {
1343
- tablename: amplifyDataStoreTableName,
1344
- }),
1345
- // eslint-disable-next-line no-template-curly-in-string
1346
- cdk.Fn.sub('arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tablename}/*', {
1347
- tablename: amplifyDataStoreTableName,
1348
- }),
1349
- ]
1311
+ // eslint-disable-next-line no-template-curly-in-string
1312
+ cdk.Fn.sub('arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tablename}', {
1313
+ tablename: amplifyDataStoreTableName,
1314
+ }),
1315
+ // eslint-disable-next-line no-template-curly-in-string
1316
+ cdk.Fn.sub('arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tablename}/*', {
1317
+ tablename: amplifyDataStoreTableName,
1318
+ }),
1319
+ ]
1350
1320
  : []),
1351
1321
  ],
1352
1322
  }),
@@ -1360,10 +1330,11 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
1360
1330
  SyncUtils.createSyncLambdaIAMPolicy(stack, syncConfig.LambdaConflictHandler.name, syncConfig.LambdaConflictHandler.region),
1361
1331
  );
1362
1332
  }
1333
+
1363
1334
  return role;
1364
1335
  }
1365
1336
 
1366
- private ensureModelSortDirectionEnum(ctx: TransformerValidationStepContextProvider): void {
1337
+ ensureModelSortDirectionEnum = (ctx: TransformerValidationStepContextProvider): void => {
1367
1338
  if (!ctx.output.hasType('ModelSortDirection')) {
1368
1339
  const modelSortDirection = makeModelSortDirectionEnumObject();
1369
1340
 
@@ -1371,16 +1342,8 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
1371
1342
  }
1372
1343
  }
1373
1344
 
1374
- private getOptions = (options: ModelTransformerOptions): ModelTransformerOptions => {
1375
- return {
1376
- EnableDeletionProtection: false,
1377
- ...options,
1378
- };
1379
- };
1380
-
1381
- private ensureValidSubscriptionName = (name: string): string => {
1382
- if (name.length <= 50) return name;
1383
-
1384
- return name.slice(0, 45) + md5(name).slice(0, 5);
1385
- };
1345
+ private getOptions = (options: ModelTransformerOptions): ModelTransformerOptions => ({
1346
+ EnableDeletionProtection: false,
1347
+ ...options,
1348
+ });
1386
1349
  }