@aws-amplify/graphql-model-transformer 0.7.0-auth-dir-v-next.2 → 0.7.0-graphql-vnext-dev-preview.1
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 +17 -16
- package/lib/graphql-model-transformer.d.ts +1 -0
- package/lib/graphql-model-transformer.d.ts.map +1 -1
- package/lib/graphql-model-transformer.js +21 -10
- package/lib/graphql-model-transformer.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/package.json +34 -32
- package/src/__tests__/__snapshots__/model-transformer.test.ts.snap +504 -785
- package/src/__tests__/model-transformer.test.ts +59 -6
- package/src/graphql-model-transformer.ts +22 -11
- 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/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(),
|
|
@@ -983,24 +984,76 @@ 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
|
+
},
|
|
999
1008
|
});
|
|
1000
|
-
|
|
1001
1009
|
const out = transformer.transform(validSchema);
|
|
1002
1010
|
expect(out).toBeDefined();
|
|
1003
1011
|
|
|
1004
|
-
|
|
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);
|
|
1005
1058
|
});
|
|
1006
1059
|
});
|
|
@@ -78,6 +78,7 @@ import {
|
|
|
78
78
|
ObjectDefinitionWrapper,
|
|
79
79
|
} from './wrappers/object-definition-wrapper';
|
|
80
80
|
import { CfnRole } from '@aws-cdk/aws-iam';
|
|
81
|
+
import md5 from 'md5';
|
|
81
82
|
|
|
82
83
|
export type Nullable<T> = T | null;
|
|
83
84
|
export type OptionalAndNullable<T> = Partial<T>;
|
|
@@ -176,14 +177,17 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
176
177
|
}
|
|
177
178
|
// todo: get model configuration with default values and store it in the map
|
|
178
179
|
const typeName = definition.name.value;
|
|
180
|
+
|
|
181
|
+
if (ctx.isProjectUsingDataStore()) {
|
|
182
|
+
SyncUtils.validateResolverConfigForType(ctx, typeName);
|
|
183
|
+
}
|
|
184
|
+
|
|
179
185
|
const directiveWrapped: DirectiveWrapper = new DirectiveWrapper(directive);
|
|
180
186
|
const options = directiveWrapped.getArguments({
|
|
181
187
|
queries: {
|
|
182
188
|
get: toCamelCase(['get', typeName]),
|
|
183
189
|
list: toCamelCase(['list', plurality(typeName, true)]),
|
|
184
|
-
...(
|
|
185
|
-
? { sync: toCamelCase(['sync', plurality(typeName, true)]) }
|
|
186
|
-
: undefined),
|
|
190
|
+
...(ctx.isProjectUsingDataStore() ? { sync: toCamelCase(['sync', plurality(typeName, true)]) } : undefined),
|
|
187
191
|
},
|
|
188
192
|
mutations: {
|
|
189
193
|
create: toCamelCase(['create', typeName]),
|
|
@@ -192,9 +196,9 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
192
196
|
},
|
|
193
197
|
subscriptions: {
|
|
194
198
|
level: SubscriptionLevel.on,
|
|
195
|
-
onCreate: [toCamelCase(['onCreate', typeName])],
|
|
196
|
-
onDelete: [toCamelCase(['onDelete', typeName])],
|
|
197
|
-
onUpdate: [toCamelCase(['onUpdate', typeName])],
|
|
199
|
+
onCreate: [this.ensureValidSubscriptionName(toCamelCase(['onCreate', typeName]))],
|
|
200
|
+
onDelete: [this.ensureValidSubscriptionName(toCamelCase(['onDelete', typeName]))],
|
|
201
|
+
onUpdate: [this.ensureValidSubscriptionName(toCamelCase(['onUpdate', typeName]))],
|
|
198
202
|
},
|
|
199
203
|
timestamps: {
|
|
200
204
|
createdAt: 'createdAt',
|
|
@@ -237,7 +241,8 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
237
241
|
this.addAutoGeneratableFields(ctx, type);
|
|
238
242
|
|
|
239
243
|
if (ctx.isProjectUsingDataStore()) {
|
|
240
|
-
|
|
244
|
+
SyncUtils.validateResolverConfigForType(ctx, def!.name.value);
|
|
245
|
+
this.options.SyncConfig = SyncUtils.getSyncConfig(ctx, def!.name.value);
|
|
241
246
|
this.addModelSyncFields(ctx, type);
|
|
242
247
|
}
|
|
243
248
|
}
|
|
@@ -1072,7 +1077,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
1072
1077
|
stream: StreamViewType.NEW_AND_OLD_IMAGES,
|
|
1073
1078
|
encryption: TableEncryption.DEFAULT,
|
|
1074
1079
|
removalPolicy: removalPolicy,
|
|
1075
|
-
...(
|
|
1080
|
+
...(context.isProjectUsingDataStore() ? { timeToLiveAttribute: '_ttl' } : undefined),
|
|
1076
1081
|
});
|
|
1077
1082
|
const cfnTable = table.node.defaultChild as CfnTable;
|
|
1078
1083
|
|
|
@@ -1129,7 +1134,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
1129
1134
|
const cfnDataSource = dataSource.node.defaultChild as CfnDataSource;
|
|
1130
1135
|
cfnDataSource.addDependsOn(role.node.defaultChild as CfnRole);
|
|
1131
1136
|
|
|
1132
|
-
if (
|
|
1137
|
+
if (context.isProjectUsingDataStore()) {
|
|
1133
1138
|
const datasourceDynamoDb = cfnDataSource.dynamoDbConfig as any;
|
|
1134
1139
|
datasourceDynamoDb.deltaSyncConfig = {
|
|
1135
1140
|
deltaSyncTableName: context.resourceHelper.generateResourceName(SyncResourceIDs.syncTableName),
|
|
@@ -1153,7 +1158,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
1153
1158
|
}
|
|
1154
1159
|
|
|
1155
1160
|
private createIAMRole(context: TransformerContextProvider, def: ObjectTypeDefinitionNode, stack: cdk.Stack, tableName: string) {
|
|
1156
|
-
const roleName = context.resourceHelper.
|
|
1161
|
+
const roleName = context.resourceHelper.generateIAMRoleName(ModelResourceIDs.ModelTableIAMRoleID(def!.name.value));
|
|
1157
1162
|
const role = new iam.Role(stack, ModelResourceIDs.ModelTableIAMRoleID(def!.name.value), {
|
|
1158
1163
|
roleName: roleName,
|
|
1159
1164
|
assumedBy: new iam.ServicePrincipal('appsync.amazonaws.com'),
|
|
@@ -1184,7 +1189,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
1184
1189
|
cdk.Fn.sub('arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tablename}/*', {
|
|
1185
1190
|
tablename: tableName,
|
|
1186
1191
|
}),
|
|
1187
|
-
...(
|
|
1192
|
+
...(context.isProjectUsingDataStore()
|
|
1188
1193
|
? [
|
|
1189
1194
|
// eslint-disable-next-line no-template-curly-in-string
|
|
1190
1195
|
cdk.Fn.sub('arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${tablename}', {
|
|
@@ -1228,4 +1233,10 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
1228
1233
|
...options,
|
|
1229
1234
|
};
|
|
1230
1235
|
};
|
|
1236
|
+
|
|
1237
|
+
private ensureValidSubscriptionName = (name: string): string => {
|
|
1238
|
+
if (name.length <= 50) return name;
|
|
1239
|
+
|
|
1240
|
+
return name.slice(0, 45) + md5(name).slice(0, 5);
|
|
1241
|
+
};
|
|
1231
1242
|
}
|
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),
|
package/src/resolvers/query.ts
CHANGED
|
@@ -34,13 +34,18 @@ export const generateGetRequestTemplate = (): string => {
|
|
|
34
34
|
ref('ctx.stash.metadata.modelObjectKey'),
|
|
35
35
|
compoundExpression([
|
|
36
36
|
set(ref('expression'), str('')),
|
|
37
|
+
set(ref('expressionNames'), obj({})),
|
|
37
38
|
set(ref('expressionValues'), obj({})),
|
|
38
39
|
forEach(ref('item'), ref('ctx.stash.metadata.modelObjectKey.entrySet()'), [
|
|
39
|
-
set(ref('expression'), str('$expression$
|
|
40
|
-
qref(methodCall(ref('
|
|
40
|
+
set(ref('expression'), str('$expression#keyCount$velocityCount = :valueCount$velocityCount AND ')),
|
|
41
|
+
qref(methodCall(ref('expressionNames.put'), str('#keyCount$velocityCount'), ref('item.key'))),
|
|
42
|
+
qref(methodCall(ref('expressionValues.put'), str(':valueCount$velocityCount'), ref('item.value'))),
|
|
41
43
|
]),
|
|
42
44
|
set(ref('expression'), methodCall(ref('expression.replaceAll'), str('AND $'), str(''))),
|
|
43
|
-
set(
|
|
45
|
+
set(
|
|
46
|
+
ref('query'),
|
|
47
|
+
obj({ expression: ref('expression'), expressionNames: ref('expressionNames'), expressionValues: ref('expressionValues') }),
|
|
48
|
+
),
|
|
44
49
|
]),
|
|
45
50
|
set(
|
|
46
51
|
ref('query'),
|
|
@@ -109,10 +114,7 @@ export const generateListRequestTemplate = (): string => {
|
|
|
109
114
|
not(isNullOrEmpty(authFilter)),
|
|
110
115
|
compoundExpression([
|
|
111
116
|
set(ref('filter'), authFilter),
|
|
112
|
-
iff(
|
|
113
|
-
not(isNullOrEmpty(ref('ctx.args.filter'))),
|
|
114
|
-
set(ref('filter'), list([obj({ and: list([ref('filter'), ref('ctx.args.filter')]) })])),
|
|
115
|
-
),
|
|
117
|
+
iff(not(isNullOrEmpty(ref('ctx.args.filter'))), set(ref('filter'), obj({ and: list([ref('filter'), ref('ctx.args.filter')]) }))),
|
|
116
118
|
]),
|
|
117
119
|
iff(not(isNullOrEmpty(ref('ctx.args.filter'))), set(ref('filter'), ref('ctx.args.filter'))),
|
|
118
120
|
),
|
|
@@ -164,10 +166,7 @@ export const generateSyncRequestTemplate = (): string => {
|
|
|
164
166
|
not(isNullOrEmpty(authFilter)),
|
|
165
167
|
compoundExpression([
|
|
166
168
|
set(ref('filter'), authFilter),
|
|
167
|
-
iff(
|
|
168
|
-
not(isNullOrEmpty(ref('ctx.args.filter'))),
|
|
169
|
-
set(ref('filter'), list([obj({ and: list([ref('filter'), ref('ctx.args.filter')]) })])),
|
|
170
|
-
),
|
|
169
|
+
iff(not(isNullOrEmpty(ref('ctx.args.filter'))), set(ref('filter'), obj({ and: list([ref('filter'), ref('ctx.args.filter')]) }))),
|
|
171
170
|
]),
|
|
172
171
|
iff(not(isNullOrEmpty(ref('ctx.args.filter'))), set(ref('filter'), ref('ctx.args.filter'))),
|
|
173
172
|
),
|
|
@@ -7,5 +7,5 @@ export const generateSubscriptionRequestTemplate = (): string => {
|
|
|
7
7
|
|
|
8
8
|
export const generateSubscriptionResponseTemplate = (): string => {
|
|
9
9
|
const statements: Expression[] = [toJson(nul())];
|
|
10
|
-
return printBlock('Subscription
|
|
10
|
+
return printBlock('Subscription Response template')(compoundExpression(statements));
|
|
11
11
|
};
|