@aws-amplify/graphql-model-transformer 0.17.0-rds-support.0 → 0.17.0-rdsv2preview.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 +8 -1
- package/lib/graphql-model-transformer.d.ts.map +1 -1
- package/lib/graphql-model-transformer.js +12 -8
- package/lib/graphql-model-transformer.js.map +1 -1
- package/lib/rds-lambda.zip +0 -0
- package/lib/resolvers/generators/rds-vtl-generator.d.ts.map +1 -1
- package/lib/resolvers/generators/rds-vtl-generator.js +1 -1
- package/lib/resolvers/generators/rds-vtl-generator.js.map +1 -1
- package/lib/resolvers/rds/index.d.ts +1 -0
- package/lib/resolvers/rds/index.d.ts.map +1 -1
- package/lib/resolvers/rds/index.js +1 -0
- package/lib/resolvers/rds/index.js.map +1 -1
- package/lib/resolvers/rds/mutation.d.ts.map +1 -1
- package/lib/resolvers/rds/mutation.js +7 -2
- package/lib/resolvers/rds/mutation.js.map +1 -1
- package/lib/resolvers/rds/query.d.ts +2 -0
- package/lib/resolvers/rds/query.d.ts.map +1 -0
- package/lib/resolvers/rds/query.js +25 -0
- package/lib/resolvers/rds/query.js.map +1 -0
- package/lib/resolvers/rds/resolver.d.ts.map +1 -1
- package/lib/resolvers/rds/resolver.js +10 -9
- package/lib/resolvers/rds/resolver.js.map +1 -1
- package/package.json +7 -7
- package/rds-lambda/clients/DBClient.ts +3 -3
- package/rds-lambda/clients/mysql/MySQLClient.ts +54 -15
- package/rds-lambda/clients/mysql/MySQLPasswordClient.ts +4 -3
- package/rds-lambda/interfaces/BaseRequest.ts +2 -2
- package/rds-lambda/interfaces/ListRequest.ts +11 -0
- package/rds-lambda/node_modules/.package-lock.json +399 -391
- package/rds-lambda/node_modules/@aws-sdk/abort-controller/package.json +2 -2
- package/rds-lambda/node_modules/@aws-sdk/client-ssm/package.json +30 -30
- package/rds-lambda/node_modules/@aws-sdk/client-sso/package.json +26 -26
- package/rds-lambda/node_modules/@aws-sdk/client-sso-oidc/package.json +26 -26
- package/rds-lambda/node_modules/@aws-sdk/client-sts/package.json +29 -29
- package/rds-lambda/node_modules/@aws-sdk/config-resolver/package.json +5 -5
- package/rds-lambda/node_modules/@aws-sdk/credential-provider-env/package.json +3 -3
- package/rds-lambda/node_modules/@aws-sdk/credential-provider-imds/package.json +5 -5
- package/rds-lambda/node_modules/@aws-sdk/credential-provider-ini/package.json +9 -9
- package/rds-lambda/node_modules/@aws-sdk/credential-provider-node/package.json +10 -10
- package/rds-lambda/node_modules/@aws-sdk/credential-provider-process/package.json +4 -4
- package/rds-lambda/node_modules/@aws-sdk/credential-provider-sso/package.json +6 -6
- package/rds-lambda/node_modules/@aws-sdk/credential-provider-web-identity/package.json +3 -3
- package/rds-lambda/node_modules/@aws-sdk/fetch-http-handler/package.json +5 -5
- package/rds-lambda/node_modules/@aws-sdk/hash-node/package.json +2 -2
- package/rds-lambda/node_modules/@aws-sdk/invalid-dependency/package.json +2 -2
- package/rds-lambda/node_modules/@aws-sdk/middleware-content-length/package.json +3 -3
- package/rds-lambda/node_modules/@aws-sdk/middleware-endpoint/package.json +7 -7
- package/rds-lambda/node_modules/@aws-sdk/middleware-host-header/package.json +3 -3
- package/rds-lambda/node_modules/@aws-sdk/middleware-logger/package.json +2 -2
- package/rds-lambda/node_modules/@aws-sdk/middleware-recursion-detection/package.json +3 -3
- package/rds-lambda/node_modules/@aws-sdk/middleware-retry/package.json +7 -7
- package/rds-lambda/node_modules/@aws-sdk/middleware-sdk-sts/package.json +6 -6
- package/rds-lambda/node_modules/@aws-sdk/middleware-serde/package.json +2 -2
- package/rds-lambda/node_modules/@aws-sdk/middleware-signing/package.json +6 -6
- package/rds-lambda/node_modules/@aws-sdk/middleware-stack/package.json +2 -2
- package/rds-lambda/node_modules/@aws-sdk/middleware-user-agent/package.json +4 -4
- package/rds-lambda/node_modules/@aws-sdk/node-config-provider/package.json +4 -4
- package/rds-lambda/node_modules/@aws-sdk/node-http-handler/package.json +5 -5
- package/rds-lambda/node_modules/@aws-sdk/property-provider/package.json +2 -2
- package/rds-lambda/node_modules/@aws-sdk/protocol-http/package.json +2 -2
- package/rds-lambda/node_modules/@aws-sdk/querystring-builder/package.json +2 -2
- package/rds-lambda/node_modules/@aws-sdk/querystring-parser/package.json +2 -2
- package/rds-lambda/node_modules/@aws-sdk/service-error-classification/package.json +2 -2
- package/rds-lambda/node_modules/@aws-sdk/shared-ini-file-loader/package.json +2 -2
- package/rds-lambda/node_modules/@aws-sdk/signature-v4/package.json +4 -4
- package/rds-lambda/node_modules/@aws-sdk/smithy-client/package.json +3 -3
- package/rds-lambda/node_modules/@aws-sdk/token-providers/package.json +5 -5
- package/rds-lambda/node_modules/@aws-sdk/types/package.json +1 -1
- package/rds-lambda/node_modules/@aws-sdk/url-parser/package.json +3 -3
- package/rds-lambda/node_modules/@aws-sdk/util-defaults-mode-browser/package.json +4 -4
- package/rds-lambda/node_modules/@aws-sdk/util-defaults-mode-node/package.json +7 -7
- package/rds-lambda/node_modules/@aws-sdk/util-endpoints/package.json +2 -2
- package/rds-lambda/node_modules/@aws-sdk/util-middleware/package.json +2 -2
- package/rds-lambda/node_modules/@aws-sdk/util-retry/package.json +3 -3
- package/rds-lambda/node_modules/@aws-sdk/util-user-agent-browser/package.json +3 -3
- package/rds-lambda/node_modules/@aws-sdk/util-user-agent-node/package.json +4 -4
- package/rds-lambda/node_modules/@aws-sdk/util-waiter/package.json +3 -3
- package/rds-lambda/node_modules/caniuse-lite/README.md +2 -88
- package/rds-lambda/node_modules/caniuse-lite/package.json +2 -6
- package/rds-lambda/node_modules/electron-to-chromium/full-chromium-versions.json +1 -1
- package/rds-lambda/node_modules/electron-to-chromium/full-versions.json +1 -1
- package/rds-lambda/node_modules/electron-to-chromium/package.json +1 -1
- package/rds-lambda/node_modules/long/LICENSE +202 -202
- package/rds-lambda/node_modules/long/README.md +246 -280
- package/rds-lambda/node_modules/long/package.json +32 -43
- package/rds-lambda/node_modules/mysql2/README.md +2 -8
- package/rds-lambda/node_modules/mysql2/node_modules/lru-cache/LICENSE +1 -1
- package/rds-lambda/node_modules/mysql2/node_modules/lru-cache/README.md +102 -775
- package/rds-lambda/node_modules/mysql2/node_modules/lru-cache/package.json +9 -49
- package/rds-lambda/node_modules/mysql2/node_modules/yallist/LICENSE +15 -0
- package/rds-lambda/node_modules/mysql2/node_modules/yallist/README.md +204 -0
- package/rds-lambda/node_modules/mysql2/node_modules/yallist/package.json +29 -0
- package/rds-lambda/node_modules/mysql2/package.json +15 -21
- package/rds-lambda/package-lock.json +798 -782
- package/rds-lambda/package.json +1 -1
- package/rds-lambda/utils/rds_utils.ts +107 -0
- package/src/__tests__/model-transformer.test.ts +89 -1
- package/src/__tests__/test-utils/rds_utils.test.ts +299 -0
- package/src/graphql-model-transformer.ts +5 -1
- package/src/resolvers/generators/rds-vtl-generator.ts +2 -1
- package/src/resolvers/rds/index.ts +1 -0
- package/src/resolvers/rds/mutation.ts +7 -2
- package/src/resolvers/rds/query.ts +33 -0
- package/src/resolvers/rds/resolver.ts +25 -16
- package/tsconfig.tsbuildinfo +1 -1
- package/rds-lambda/node_modules/long/umd/package.json +0 -3
package/rds-lambda/package.json
CHANGED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Util method to convert any GraphQL input filter argument to an AWS RDS query expression
|
|
3
|
+
*/
|
|
4
|
+
export const toRDSQueryExpression = (filter: any) => {
|
|
5
|
+
let rdsExpression = '';
|
|
6
|
+
let isAndAppended = false;
|
|
7
|
+
Object.entries(filter).forEach(([key, value]: any, index) => {
|
|
8
|
+
if(index != 0) {
|
|
9
|
+
rdsExpression += ` AND `;
|
|
10
|
+
isAndAppended = true;
|
|
11
|
+
}
|
|
12
|
+
switch(key) {
|
|
13
|
+
case 'and':
|
|
14
|
+
case 'or':
|
|
15
|
+
rdsExpression += value.map(toRDSQueryExpression).join(` ${key.toUpperCase()} `);
|
|
16
|
+
break;
|
|
17
|
+
case 'not':
|
|
18
|
+
rdsExpression += `NOT ${toRDSQueryExpression(value)}`;
|
|
19
|
+
break;
|
|
20
|
+
default:
|
|
21
|
+
Object.entries(value).forEach(([operator, operand]: any, secondIndex) => {
|
|
22
|
+
if(secondIndex != 0) {
|
|
23
|
+
rdsExpression += ` AND `;
|
|
24
|
+
}
|
|
25
|
+
switch(operator) {
|
|
26
|
+
case 'attributeExists':
|
|
27
|
+
rdsExpression += `${key} IS NOT NULL`;
|
|
28
|
+
break;
|
|
29
|
+
case 'beginsWith':
|
|
30
|
+
rdsExpression += `${key} LIKE '${operand}%'`;
|
|
31
|
+
break;
|
|
32
|
+
case 'between':
|
|
33
|
+
if (!Array.isArray(operand) || operand.length !== 2) {
|
|
34
|
+
throw new Error(`between condition must have two values, but got: ${operand}.length`);
|
|
35
|
+
}
|
|
36
|
+
rdsExpression += `${key} BETWEEN '${operand[0]}' AND '${operand[1]}'`;
|
|
37
|
+
break;
|
|
38
|
+
case 'contains':
|
|
39
|
+
rdsExpression += `${key} LIKE '%${operand}%'`;
|
|
40
|
+
break;
|
|
41
|
+
case 'eq':
|
|
42
|
+
rdsExpression += `${key} = '${operand}'`;
|
|
43
|
+
break;
|
|
44
|
+
case 'ge':
|
|
45
|
+
rdsExpression += `${key} >= '${operand}'`;
|
|
46
|
+
break;
|
|
47
|
+
case 'gt':
|
|
48
|
+
rdsExpression += `${key} > '${operand}'`;
|
|
49
|
+
break;
|
|
50
|
+
case 'le':
|
|
51
|
+
rdsExpression += `${key} <= '${operand}'`;
|
|
52
|
+
break;
|
|
53
|
+
case 'lt':
|
|
54
|
+
rdsExpression += `${key} < '${operand}'`;
|
|
55
|
+
break;
|
|
56
|
+
case 'ne':
|
|
57
|
+
rdsExpression += `${key} != '${operand}'`;
|
|
58
|
+
break;
|
|
59
|
+
case 'notContains':
|
|
60
|
+
// key : name , operand : 'a' , operator : notContains
|
|
61
|
+
rdsExpression += `${key} NOT LIKE '%${operand}%'`;
|
|
62
|
+
break;
|
|
63
|
+
case 'size':
|
|
64
|
+
// size has nested operators:- between, eq, ge, gt, le, lt, ne
|
|
65
|
+
Object.entries(operand).forEach(([sizeOperator, sizeOperand]: any) => {
|
|
66
|
+
if(index != 0 && !isAndAppended) {
|
|
67
|
+
rdsExpression += ` AND `;
|
|
68
|
+
isAndAppended = true;
|
|
69
|
+
}
|
|
70
|
+
switch(sizeOperator) {
|
|
71
|
+
case 'between':
|
|
72
|
+
if (!Array.isArray(sizeOperand) || sizeOperand.length !== 2) {
|
|
73
|
+
throw new Error(`between condition must have two values, but got: ${sizeOperand}.length`);
|
|
74
|
+
}
|
|
75
|
+
rdsExpression += `LENGTH (${key}) BETWEEN '${sizeOperand[0]}' AND '${sizeOperand[1]}'`;
|
|
76
|
+
break;
|
|
77
|
+
case 'eq':
|
|
78
|
+
rdsExpression += `LENGTH (${key}) = '${sizeOperand}'`;
|
|
79
|
+
break;
|
|
80
|
+
case 'ge':
|
|
81
|
+
rdsExpression += `LENGTH (${key}) >= '${sizeOperand}'`;
|
|
82
|
+
break;
|
|
83
|
+
case 'gt':
|
|
84
|
+
rdsExpression += `LENGTH (${key}) > '${sizeOperand}'`;
|
|
85
|
+
break;
|
|
86
|
+
case 'le':
|
|
87
|
+
rdsExpression += `LENGTH (${key}) <= '${sizeOperand}'`;
|
|
88
|
+
break;
|
|
89
|
+
case 'lt':
|
|
90
|
+
rdsExpression += `LENGTH (${key}) < '${sizeOperand}'`;
|
|
91
|
+
break;
|
|
92
|
+
case 'ne':
|
|
93
|
+
rdsExpression += `LENGTH (${key}) != '${sizeOperand}'`;
|
|
94
|
+
break;
|
|
95
|
+
default:
|
|
96
|
+
console.log(`Unsupported operator: ${sizeOperator}`);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
break;
|
|
100
|
+
default:
|
|
101
|
+
console.log(`Unsupported operator: ${operator}`);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
return `(${rdsExpression})`;
|
|
107
|
+
};
|
|
@@ -13,7 +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
|
+
import { expect as cdkExpect, haveResource, haveResourceLike } from '@aws-cdk/assert';
|
|
17
17
|
|
|
18
18
|
const featureFlags = {
|
|
19
19
|
getBoolean: jest.fn(),
|
|
@@ -1170,7 +1170,95 @@ describe('ModelTransformer: ', () => {
|
|
|
1170
1170
|
}),
|
|
1171
1171
|
);
|
|
1172
1172
|
});
|
|
1173
|
+
it("the conflict detection of per model rule should be respected", () => {
|
|
1174
|
+
const validSchema = `
|
|
1175
|
+
type Todo @model {
|
|
1176
|
+
name: String
|
|
1177
|
+
}
|
|
1178
|
+
type Author @model {
|
|
1179
|
+
name: String
|
|
1180
|
+
}
|
|
1181
|
+
`;
|
|
1182
|
+
|
|
1183
|
+
const transformer = new GraphQLTransform({
|
|
1184
|
+
transformConfig: {},
|
|
1185
|
+
resolverConfig: {
|
|
1186
|
+
project: {
|
|
1187
|
+
ConflictDetection: "VERSION",
|
|
1188
|
+
ConflictHandler: ConflictHandlerType.AUTOMERGE
|
|
1189
|
+
},
|
|
1190
|
+
models: {
|
|
1191
|
+
Todo: {
|
|
1192
|
+
ConflictDetection: "VERSION",
|
|
1193
|
+
ConflictHandler: ConflictHandlerType.LAMBDA,
|
|
1194
|
+
LambdaConflictHandler: {
|
|
1195
|
+
name: "myTodoConflictHandler"
|
|
1196
|
+
}
|
|
1197
|
+
},
|
|
1198
|
+
Author: {
|
|
1199
|
+
ConflictDetection: "VERSION",
|
|
1200
|
+
ConflictHandler: ConflictHandlerType.AUTOMERGE
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
},
|
|
1204
|
+
sandboxModeEnabled: true,
|
|
1205
|
+
transformers: [new ModelTransformer()]
|
|
1206
|
+
});
|
|
1207
|
+
const out = transformer.transform(validSchema);
|
|
1208
|
+
expect(out).toBeDefined();
|
|
1209
|
+
const schema = parse(out.schema);
|
|
1210
|
+
validateModelSchema(schema);
|
|
1211
|
+
// nested stacks for models
|
|
1212
|
+
const todoStack = out.stacks["Todo"];
|
|
1213
|
+
const authorStack = out.stacks["Author"];
|
|
1214
|
+
// Todo stack should have lambda for conflict detect rather than auto merge
|
|
1215
|
+
cdkExpect(todoStack).to(
|
|
1216
|
+
haveResourceLike(
|
|
1217
|
+
"AWS::AppSync::FunctionConfiguration",
|
|
1218
|
+
{
|
|
1219
|
+
SyncConfig: {
|
|
1220
|
+
ConflictDetection: "VERSION",
|
|
1221
|
+
ConflictHandler: "LAMBDA",
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
)
|
|
1225
|
+
);
|
|
1226
|
+
cdkExpect(todoStack).notTo(
|
|
1227
|
+
haveResourceLike(
|
|
1228
|
+
"AWS::AppSync::FunctionConfiguration",
|
|
1229
|
+
{
|
|
1230
|
+
SyncConfig: {
|
|
1231
|
+
ConflictDetection: "VERSION",
|
|
1232
|
+
ConflictHandler: "AUTOMERGE",
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
)
|
|
1236
|
+
);
|
|
1237
|
+
// Author stack should have automerge for conflict detect rather than lambda
|
|
1238
|
+
cdkExpect(authorStack).notTo(
|
|
1239
|
+
haveResourceLike(
|
|
1240
|
+
"AWS::AppSync::FunctionConfiguration",
|
|
1241
|
+
{
|
|
1242
|
+
SyncConfig: {
|
|
1243
|
+
ConflictDetection: "VERSION",
|
|
1244
|
+
ConflictHandler: "LAMBDA",
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
)
|
|
1248
|
+
);
|
|
1249
|
+
cdkExpect(authorStack).to(
|
|
1250
|
+
haveResourceLike(
|
|
1251
|
+
"AWS::AppSync::FunctionConfiguration",
|
|
1252
|
+
{
|
|
1253
|
+
SyncConfig: {
|
|
1254
|
+
ConflictDetection: "VERSION",
|
|
1255
|
+
ConflictHandler: "AUTOMERGE",
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
)
|
|
1259
|
+
);
|
|
1173
1260
|
|
|
1261
|
+
});
|
|
1174
1262
|
it('should add the model parameters at the root sack', () => {
|
|
1175
1263
|
const modelParams = {
|
|
1176
1264
|
DynamoDBModelTableReadIOPS: expect.objectContaining({
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import { toRDSQueryExpression } from './../../../rds-lambda/utils/rds_utils';
|
|
2
|
+
|
|
3
|
+
describe('filterToRdsExpression', () => {
|
|
4
|
+
// QueryGroup - and, or
|
|
5
|
+
it('should convert and: QueryGroup ', () => {
|
|
6
|
+
const filter = {
|
|
7
|
+
and : [
|
|
8
|
+
{ id : { eq : '123' } },
|
|
9
|
+
{ name : { eq : 'Amplify' } },
|
|
10
|
+
],
|
|
11
|
+
};
|
|
12
|
+
expect(toRDSQueryExpression(filter)).toEqual("((id = '123') AND (name = 'Amplify'))");
|
|
13
|
+
});
|
|
14
|
+
it('should convert or: QueryGroup ', () => {
|
|
15
|
+
const filter = {
|
|
16
|
+
or : [
|
|
17
|
+
{ id : { eq : '123' } },
|
|
18
|
+
{ name : { eq : 'Amplify' } },
|
|
19
|
+
],
|
|
20
|
+
};
|
|
21
|
+
expect(toRDSQueryExpression(filter)).toEqual("((id = '123') OR (name = 'Amplify'))");
|
|
22
|
+
});
|
|
23
|
+
// Operator - eq, ne, gt, ge, lt, le, contains, notContains, between, beginsWith
|
|
24
|
+
it('should convert eq: Operator ', () => {
|
|
25
|
+
const filter = {
|
|
26
|
+
id : { eq : '123' },
|
|
27
|
+
name: { eq : 'Amplify' },
|
|
28
|
+
org: { eq : 'AWS' },
|
|
29
|
+
};
|
|
30
|
+
expect(toRDSQueryExpression(filter)).toEqual("(id = '123' AND name = 'Amplify' AND org = 'AWS')");
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('should convert ne: , eq: Operator ', () => {
|
|
34
|
+
const filter = {
|
|
35
|
+
id : { ne : '123' },
|
|
36
|
+
name: { eq : 'Amplify' },
|
|
37
|
+
};
|
|
38
|
+
expect(toRDSQueryExpression(filter)).toEqual("(id != '123' AND name = 'Amplify')");
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('should convert gt: , eq: Operator ', () => {
|
|
42
|
+
const filter = {
|
|
43
|
+
id : { gt : '123' },
|
|
44
|
+
name: { eq : 'Amplify' },
|
|
45
|
+
};
|
|
46
|
+
expect(toRDSQueryExpression(filter)).toEqual("(id > '123' AND name = 'Amplify')");
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('should convert ge: , eq: , ne: Operator ', () => {
|
|
50
|
+
const filter = {
|
|
51
|
+
id : { ge : '123' },
|
|
52
|
+
name: { eq : 'Amplify' },
|
|
53
|
+
org: { ne : 'AWS' },
|
|
54
|
+
};
|
|
55
|
+
expect(toRDSQueryExpression(filter)).toEqual("(id >= '123' AND name = 'Amplify' AND org != 'AWS')");
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('should convert lt: , eq: , ne: Operator ', () => {
|
|
59
|
+
const filter = {
|
|
60
|
+
id : { lt : '123' },
|
|
61
|
+
name: { eq : 'Amplify' },
|
|
62
|
+
org: { ne : 'AWS' },
|
|
63
|
+
};
|
|
64
|
+
expect(toRDSQueryExpression(filter)).toEqual("(id < '123' AND name = 'Amplify' AND org != 'AWS')");
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('should convert le: , eq: , ne: Operator ', () => {
|
|
68
|
+
const filter = {
|
|
69
|
+
id : { le : '123' },
|
|
70
|
+
name: { ne : 'Amplify' },
|
|
71
|
+
org: { eq : 'AWS' },
|
|
72
|
+
};
|
|
73
|
+
expect(toRDSQueryExpression(filter)).toEqual("(id <= '123' AND name != 'Amplify' AND org = 'AWS')");
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('should convert contains: , eq: , ne: Operator ', () => {
|
|
77
|
+
const filter = {
|
|
78
|
+
id : { ne : '123' },
|
|
79
|
+
name: { contains : 'Amplify' },
|
|
80
|
+
org: { eq : 'AWS' },
|
|
81
|
+
};
|
|
82
|
+
expect(toRDSQueryExpression(filter)).toEqual("(id != '123' AND name LIKE '%Amplify%' AND org = 'AWS')");
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('should convert eq: , notContains: , ne: Operator ', () => {
|
|
86
|
+
const filter = {
|
|
87
|
+
id : { eq : '123' },
|
|
88
|
+
name: { notContains : 'Amplify' },
|
|
89
|
+
org: { ne : 'AWS' },
|
|
90
|
+
};
|
|
91
|
+
expect(toRDSQueryExpression(filter)).toEqual("(id = '123' AND name NOT LIKE '%Amplify%' AND org != 'AWS')");
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('should convert beginsWith: , eq: , ne: Operator ', () => {
|
|
95
|
+
const filter = {
|
|
96
|
+
id : { eq : '123' },
|
|
97
|
+
name: { beginsWith : 'Amplify' },
|
|
98
|
+
org: { ne : 'AWS' },
|
|
99
|
+
};
|
|
100
|
+
expect(toRDSQueryExpression(filter)).toEqual("(id = '123' AND name LIKE 'Amplify%' AND org != 'AWS')");
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('should convert between: , eq: , ne: Operator ', () => {
|
|
104
|
+
const filter = {
|
|
105
|
+
id : { eq : '123' },
|
|
106
|
+
age: { between : ['18', '60'] },
|
|
107
|
+
org: { ne : 'AWS' },
|
|
108
|
+
};
|
|
109
|
+
expect(toRDSQueryExpression(filter)).toEqual("(id = '123' AND age BETWEEN '18' AND '60' AND org != 'AWS')");
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test('filterToRdsExpression > should throw error if between: doesn\'t have 2 values', () => {
|
|
113
|
+
const filter = {
|
|
114
|
+
id : { eq : '123' },
|
|
115
|
+
age: { between : ['18'] },
|
|
116
|
+
org: { ne : 'AWS' },
|
|
117
|
+
};
|
|
118
|
+
expect(() => {toRDSQueryExpression(filter);}).toThrowError(/between condition must have two values/);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// nested QueryGroup & Operators
|
|
122
|
+
it('should convert nested and: or: with Operators ', () => {
|
|
123
|
+
const filter = {
|
|
124
|
+
and : [
|
|
125
|
+
{ id : { eq : '123' } },
|
|
126
|
+
{ or : [
|
|
127
|
+
{ name : { eq : 'Amplify' } },
|
|
128
|
+
{ org : { eq : 'AWS' } },
|
|
129
|
+
]},
|
|
130
|
+
],
|
|
131
|
+
};
|
|
132
|
+
expect(toRDSQueryExpression(filter)).toEqual("((id = '123') AND ((name = 'Amplify') OR (org = 'AWS')))");
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('should convert nested or: and: with Operators ', () => {
|
|
136
|
+
const filter = {
|
|
137
|
+
or : [
|
|
138
|
+
{ id : { eq : '123' } },
|
|
139
|
+
{ and : [
|
|
140
|
+
{ name : { eq : 'Amplify' } },
|
|
141
|
+
{ org : { eq : 'AWS' } },
|
|
142
|
+
]},
|
|
143
|
+
],
|
|
144
|
+
};
|
|
145
|
+
expect(toRDSQueryExpression(filter)).toEqual("((id = '123') OR ((name = 'Amplify') AND (org = 'AWS')))");
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it('should convert nested and: and: with Operators ', () => {
|
|
149
|
+
const filter = {
|
|
150
|
+
and : [
|
|
151
|
+
{ id : { eq : '123' } },
|
|
152
|
+
{ and : [
|
|
153
|
+
{ name : { eq : 'Amplify' } },
|
|
154
|
+
{ org : { eq : 'AWS' } },
|
|
155
|
+
]},
|
|
156
|
+
],
|
|
157
|
+
};
|
|
158
|
+
expect(toRDSQueryExpression(filter)).toEqual("((id = '123') AND ((name = 'Amplify') AND (org = 'AWS')))");
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it('should convert deep nested query and: or: and: ', () => {
|
|
162
|
+
const filter = {
|
|
163
|
+
and : [
|
|
164
|
+
{ id : { eq : '123' } },
|
|
165
|
+
{ or : [
|
|
166
|
+
{ name : { eq : 'Amplify' } },
|
|
167
|
+
{ and : [
|
|
168
|
+
{ org : { eq : 'AWS' } },
|
|
169
|
+
{ age : { between : [`18`, `60`] } },
|
|
170
|
+
]},
|
|
171
|
+
]},
|
|
172
|
+
],
|
|
173
|
+
};
|
|
174
|
+
expect(toRDSQueryExpression(filter)).toEqual("((id = '123') AND ((name = 'Amplify') OR ((org = 'AWS') AND (age BETWEEN '18' AND '60'))))");
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it(`should convert deep nested query and: or: and: with multiple operators`, () => {
|
|
178
|
+
const filter = {
|
|
179
|
+
id: { eq: '123' },
|
|
180
|
+
and : [
|
|
181
|
+
{ or : [
|
|
182
|
+
{ name : { eq : 'Amplify' } },
|
|
183
|
+
{ and : [
|
|
184
|
+
{ org : { eq : 'AWS' } },
|
|
185
|
+
{ age : { between : [`18`, `60`] } },
|
|
186
|
+
{ name : { beginsWith : 'Amplify' } },
|
|
187
|
+
]},
|
|
188
|
+
]},
|
|
189
|
+
],
|
|
190
|
+
};
|
|
191
|
+
expect(toRDSQueryExpression(filter)).toEqual("(id = '123' AND ((name = 'Amplify') OR ((org = 'AWS') AND (age BETWEEN '18' AND '60') AND (name LIKE 'Amplify%'))))");
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
it(`should convert deep nested query and: or: and: with multiple operators`, () => {
|
|
195
|
+
const filter = {
|
|
196
|
+
id: { ne: '123' },
|
|
197
|
+
and : [
|
|
198
|
+
{ or : [
|
|
199
|
+
{ name : { eq : 'Amplify' } },
|
|
200
|
+
{ and : [
|
|
201
|
+
{ org : { ne : 'AWS' } },
|
|
202
|
+
{ age : { between : [`18`, `60`] } },
|
|
203
|
+
{ name : { beginsWith : 'Amplify' } },
|
|
204
|
+
]},
|
|
205
|
+
]},
|
|
206
|
+
],
|
|
207
|
+
or : [
|
|
208
|
+
{ name : { eq : 'Amplify' } },
|
|
209
|
+
{ org : { eq : 'AWS' } },
|
|
210
|
+
],
|
|
211
|
+
};
|
|
212
|
+
expect(toRDSQueryExpression(filter)).toEqual("(id != '123' AND ((name = 'Amplify') OR ((org != 'AWS') AND (age BETWEEN '18' AND '60') AND (name LIKE 'Amplify%'))) AND (name = 'Amplify') OR (org = 'AWS'))");
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
it(`should convert deep nested query and: or: and: with multiple operators`, () => {
|
|
216
|
+
const filter = {
|
|
217
|
+
name : { beginsWith : 'A' },
|
|
218
|
+
or : [
|
|
219
|
+
{ name : { eq : 'Amplify' } },
|
|
220
|
+
{ and : [
|
|
221
|
+
{ org : { eq : 'AWS' } },
|
|
222
|
+
{ age : { between : [`18`, `60`] } },
|
|
223
|
+
{ name : { eq : 'Amplify' } },
|
|
224
|
+
]},
|
|
225
|
+
],
|
|
226
|
+
and : [
|
|
227
|
+
{ name : { eq : 'Amplify' } },
|
|
228
|
+
{ org : { eq : 'AWS' } },
|
|
229
|
+
],
|
|
230
|
+
};
|
|
231
|
+
expect(toRDSQueryExpression(filter)).toEqual("(name LIKE 'A%' AND (name = 'Amplify') OR ((org = 'AWS') AND (age BETWEEN '18' AND '60') AND (name = 'Amplify')) AND (name = 'Amplify') AND (org = 'AWS'))");
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
// size operator tests
|
|
235
|
+
it(`should work on size: gt: operator`, () => {
|
|
236
|
+
const filter = {
|
|
237
|
+
id : { eq : '123', size : { gt : 1 } },
|
|
238
|
+
}
|
|
239
|
+
expect(toRDSQueryExpression(filter)).toEqual("(id = '123' AND LENGTH (id) > '1')");
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
it(`should work on size: ge: operator`, () => {
|
|
243
|
+
const filter = {
|
|
244
|
+
id : { eq : '123', size : { ge : 1 } },
|
|
245
|
+
}
|
|
246
|
+
expect(toRDSQueryExpression(filter)).toEqual("(id = '123' AND LENGTH (id) >= '1')");
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
it(`should work on size: lt: operator`, () => {
|
|
250
|
+
const filter = {
|
|
251
|
+
id : { eq : '123', size : { lt : 1 } },
|
|
252
|
+
}
|
|
253
|
+
expect(toRDSQueryExpression(filter)).toEqual("(id = '123' AND LENGTH (id) < '1')");
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
it(`should work on size: le: operator`, () => {
|
|
257
|
+
const filter = {
|
|
258
|
+
id : { eq : '123', size : { le : 1 } },
|
|
259
|
+
}
|
|
260
|
+
expect(toRDSQueryExpression(filter)).toEqual("(id = '123' AND LENGTH (id) <= '1')");
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
it(`should work on size: eq: operator along with and: QueryGroup`, () => {
|
|
264
|
+
const filter = {
|
|
265
|
+
and : [
|
|
266
|
+
{ id : { eq : '123', size : { eq : 1 } } },
|
|
267
|
+
],
|
|
268
|
+
}
|
|
269
|
+
expect(toRDSQueryExpression(filter)).toEqual("((id = '123' AND LENGTH (id) = '1'))");
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
it(`should work on size: eq: operator along with or: QueryGroup`, () => {
|
|
273
|
+
const filter = {
|
|
274
|
+
or : [
|
|
275
|
+
{ id : { eq : '123', size : { eq : 2 } } },
|
|
276
|
+
],
|
|
277
|
+
and : [
|
|
278
|
+
{ age : { eq : '30', size : { eq : 3 } } },
|
|
279
|
+
],
|
|
280
|
+
}
|
|
281
|
+
expect(toRDSQueryExpression(filter)).toEqual("((id = '123' AND LENGTH (id) = '2') AND (age = '30' AND LENGTH (age) = '3'))");
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
it(`should work on size: eq: operator along with or: and: QueryGroup`, () => {
|
|
285
|
+
const filter = {
|
|
286
|
+
or : [
|
|
287
|
+
{ id : { eq : '123', size : { eq : 2 } } },
|
|
288
|
+
{ and : [
|
|
289
|
+
{ age : { eq : '30', size : { eq : 3 } } },
|
|
290
|
+
]},
|
|
291
|
+
],
|
|
292
|
+
and : [
|
|
293
|
+
{ age : { eq : '20', size : { eq : 3 } } },
|
|
294
|
+
{ org: { eq : 'AWS', size : { eq : 3 } } },
|
|
295
|
+
],
|
|
296
|
+
}
|
|
297
|
+
expect(toRDSQueryExpression(filter)).toEqual("((id = '123' AND LENGTH (id) = '2') OR ((age = '30' AND LENGTH (age) = '3')) AND (age = '20' AND LENGTH (age) = '3') AND (org = 'AWS' AND LENGTH (org) = '3'))");
|
|
298
|
+
});
|
|
299
|
+
});
|
|
@@ -162,6 +162,7 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
162
162
|
|| definition.name.value === ctx.output.getMutationTypeName()
|
|
163
163
|
|| definition.name.value === ctx.output.getSubscriptionTypeName();
|
|
164
164
|
|
|
165
|
+
const isDynamoDB = (ctx.modelToDatasourceMap.get(definition.name.value) ?? DDB_DATASOURCE_TYPE).dbType === DDB_DB_TYPE;
|
|
165
166
|
if (isTypeNameReserved) {
|
|
166
167
|
throw new InvalidDirectiveError(
|
|
167
168
|
`'${definition.name.value}' is a reserved type name and currently in use within the default schema element.`,
|
|
@@ -192,9 +193,12 @@ export class ModelTransformer extends TransformerModelBase implements Transforme
|
|
|
192
193
|
onDelete: [getFieldNameFor('onDelete', typeName)],
|
|
193
194
|
onUpdate: [getFieldNameFor('onUpdate', typeName)],
|
|
194
195
|
},
|
|
195
|
-
timestamps: {
|
|
196
|
+
timestamps: isDynamoDB ? {
|
|
196
197
|
createdAt: 'createdAt',
|
|
197
198
|
updatedAt: 'updatedAt',
|
|
199
|
+
} : {
|
|
200
|
+
createdAt: undefined,
|
|
201
|
+
updatedAt: undefined,
|
|
198
202
|
},
|
|
199
203
|
}, generateGetArgumentsInput(ctx.featureFlags));
|
|
200
204
|
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
generateUpdateInitSlotTemplate,
|
|
8
8
|
generateLambdaUpdateRequestTemplate,
|
|
9
9
|
generateLambdaDeleteRequestTemplate,
|
|
10
|
+
generateLambdaListRequestTemplate,
|
|
10
11
|
} from '../rds';
|
|
11
12
|
import {
|
|
12
13
|
generateSubscriptionRequestTemplate,
|
|
@@ -45,7 +46,7 @@ export class RDSModelVTLGenerator implements ModelVTLGenerator {
|
|
|
45
46
|
return generateGetLambdaResponseTemplate(false);
|
|
46
47
|
}
|
|
47
48
|
generateListRequestTemplate(config: ModelRequestConfig): string {
|
|
48
|
-
return
|
|
49
|
+
return generateLambdaListRequestTemplate(config.modelName, config.operation, config.operationName);
|
|
49
50
|
}
|
|
50
51
|
generateSyncRequestTemplate(config: ModelRequestConfig): string {
|
|
51
52
|
return generateDefaultLambdaResponseMappingTemplate(false);
|
|
@@ -58,6 +58,9 @@ export const generateLambdaCreateRequestTemplate = (tableName: string, operation
|
|
|
58
58
|
set(ref('lambdaInput.args'), obj({})),
|
|
59
59
|
set(ref('lambdaInput.operation'), str('CREATE')),
|
|
60
60
|
set(ref('lambdaInput.operationName'), str(operationName)),
|
|
61
|
+
set(ref('lambdaInput.args.metadata'), obj({})),
|
|
62
|
+
set(ref('lambdaInput.args.metadata.keys'), list([])),
|
|
63
|
+
qref(methodCall(ref('lambdaInput.args.metadata.keys.addAll'), methodCall(ref('util.defaultIfNull'), ref('ctx.stash.keys'), list([])))),
|
|
61
64
|
comment('Set the default values to put request'),
|
|
62
65
|
set(ref('lambdaInput.args.input'), methodCall(ref('util.defaultIfNull'), ref('ctx.stash.defaultValues'), obj({}))),
|
|
63
66
|
comment('copy the values from input'),
|
|
@@ -115,7 +118,8 @@ export const generateLambdaUpdateRequestTemplate = (tableName: string, operation
|
|
|
115
118
|
set(ref('lambdaInput.operation'), str('UPDATE')),
|
|
116
119
|
set(ref('lambdaInput.operationName'), str(operationName)),
|
|
117
120
|
set(ref('lambdaInput.args.metadata'), obj({})),
|
|
118
|
-
set(ref('lambdaInput.args.metadata.keys'), list(
|
|
121
|
+
set(ref('lambdaInput.args.metadata.keys'), list([])),
|
|
122
|
+
qref(methodCall(ref('lambdaInput.args.metadata.keys.addAll'), methodCall(ref('util.defaultIfNull'), ref('ctx.stash.keys'), list([])))),
|
|
119
123
|
comment('Set the default values to put request'),
|
|
120
124
|
set(ref('lambdaInput.args.input'), methodCall(ref('util.defaultIfNull'), ref('ctx.stash.defaultValues'), obj({}))),
|
|
121
125
|
comment('copy the values from input'),
|
|
@@ -141,7 +145,8 @@ export const generateLambdaDeleteRequestTemplate = (tableName: string, operation
|
|
|
141
145
|
set(ref('lambdaInput.operation'), str('DELETE')),
|
|
142
146
|
set(ref('lambdaInput.operationName'), str(operationName)),
|
|
143
147
|
set(ref('lambdaInput.args.metadata'), obj({})),
|
|
144
|
-
set(ref('lambdaInput.args.metadata.keys'), list(
|
|
148
|
+
set(ref('lambdaInput.args.metadata.keys'), list([])),
|
|
149
|
+
qref(methodCall(ref('lambdaInput.args.metadata.keys.addAll'), methodCall(ref('util.defaultIfNull'), ref('ctx.stash.keys'), list([])))),
|
|
145
150
|
obj({
|
|
146
151
|
version: str('2018-05-29'),
|
|
147
152
|
operation: str('Invoke'),
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import {
|
|
2
|
+
compoundExpression,
|
|
3
|
+
list,
|
|
4
|
+
methodCall,
|
|
5
|
+
obj,
|
|
6
|
+
printBlock,
|
|
7
|
+
qref,
|
|
8
|
+
ref,
|
|
9
|
+
set,
|
|
10
|
+
str,
|
|
11
|
+
} from 'graphql-mapping-template';
|
|
12
|
+
|
|
13
|
+
export const generateLambdaListRequestTemplate = (tableName: string, operation: string, operationName: string): string => {
|
|
14
|
+
return printBlock('Invoke RDS Lambda data source')(
|
|
15
|
+
compoundExpression([
|
|
16
|
+
set(ref('lambdaInput'), obj({})),
|
|
17
|
+
set(ref('lambdaInput.args'), obj({})),
|
|
18
|
+
set(ref('lambdaInput.table'), str(tableName)),
|
|
19
|
+
set(ref('lambdaInput.operation'), str(operation)),
|
|
20
|
+
set(ref('lambdaInput.operationName'), str(operationName)),
|
|
21
|
+
set(ref('lambdaInput.args.metadata'), obj({})),
|
|
22
|
+
set(ref('lambdaInput.args.metadata.keys'), list([])),
|
|
23
|
+
qref(methodCall(ref('lambdaInput.args.metadata.keys.addAll'), methodCall(ref('util.defaultIfNull'), ref('ctx.stash.keys'), list([])))),
|
|
24
|
+
set(ref('lambdaInput.args.input'), methodCall(ref('util.defaultIfNull'), ref('ctx.stash.defaultValues'), obj({}))),
|
|
25
|
+
qref(methodCall(ref('lambdaInput.args.putAll'), methodCall(ref('util.defaultIfNull'), ref('context.arguments'), obj({})))),
|
|
26
|
+
obj({
|
|
27
|
+
version: str('2018-05-29'),
|
|
28
|
+
operation: str('Invoke'),
|
|
29
|
+
payload: methodCall(ref('util.toJson'), ref('lambdaInput')),
|
|
30
|
+
}),
|
|
31
|
+
]),
|
|
32
|
+
);
|
|
33
|
+
};
|