@aws-amplify/graphql-model-transformer 2.1.1 → 2.2.0-rds-1.0
Sign up to get free protection for your applications and to get access to all the features.
- package/API.md +15 -15
- package/CHANGELOG.md +10 -2
- package/lib/graphql-types/mutation.d.ts.map +1 -1
- package/lib/graphql-types/mutation.js +9 -2
- package/lib/graphql-types/mutation.js.map +1 -1
- package/lib/rds-lambda.zip +0 -0
- package/lib/rds-notification-lambda.zip +0 -0
- package/lib/rds-patching-lambda.zip +0 -0
- package/lib/resolvers/generators/dynamodb-vtl-generator.d.ts +6 -5
- package/lib/resolvers/generators/dynamodb-vtl-generator.d.ts.map +1 -1
- package/lib/resolvers/generators/dynamodb-vtl-generator.js +5 -5
- package/lib/resolvers/generators/dynamodb-vtl-generator.js.map +1 -1
- package/lib/resolvers/generators/rds-vtl-generator.d.ts +6 -5
- package/lib/resolvers/generators/rds-vtl-generator.d.ts.map +1 -1
- package/lib/resolvers/generators/rds-vtl-generator.js +10 -10
- package/lib/resolvers/generators/rds-vtl-generator.js.map +1 -1
- package/lib/resolvers/generators/vtl-generator.d.ts +6 -5
- package/lib/resolvers/generators/vtl-generator.d.ts.map +1 -1
- package/lib/resolvers/rds/mutation.d.ts +4 -3
- package/lib/resolvers/rds/mutation.d.ts.map +1 -1
- package/lib/resolvers/rds/mutation.js +7 -3
- package/lib/resolvers/rds/mutation.js.map +1 -1
- package/lib/resolvers/rds/query.d.ts +2 -1
- package/lib/resolvers/rds/query.d.ts.map +1 -1
- package/lib/resolvers/rds/query.js +3 -1
- package/lib/resolvers/rds/query.js.map +1 -1
- package/lib/resolvers/rds/resolver.d.ts +6 -2
- package/lib/resolvers/rds/resolver.d.ts.map +1 -1
- package/lib/resolvers/rds/resolver.js +39 -25
- package/lib/resolvers/rds/resolver.js.map +1 -1
- package/lib/resources/model-resource-generator.js +5 -5
- package/lib/resources/model-resource-generator.js.map +1 -1
- package/package.json +8 -8
- package/rds-lambda/handler.ts +2 -1
- package/src/__tests__/__snapshots__/model-transformer.test.ts.snap +688 -0
- package/src/__tests__/model-transformer.test.ts +57 -1
- package/src/graphql-types/mutation.ts +11 -3
- package/src/resolvers/generators/dynamodb-vtl-generator.ts +7 -5
- package/src/resolvers/generators/rds-vtl-generator.ts +12 -10
- package/src/resolvers/generators/vtl-generator.ts +6 -5
- package/src/resolvers/rds/mutation.ts +18 -3
- package/src/resolvers/rds/query.ts +9 -1
- package/src/resolvers/rds/resolver.ts +45 -26
- package/src/resources/model-resource-generator.ts +5 -5
- package/tsconfig.tsbuildinfo +1 -1
@@ -1,9 +1,9 @@
|
|
1
|
+
import { ModelTransformer } from '@aws-amplify/graphql-model-transformer';
|
1
2
|
import { ConflictHandlerType, DatasourceType, GraphQLTransform, validateModelSchema } from '@aws-amplify/graphql-transformer-core';
|
2
3
|
import { InputObjectTypeDefinitionNode, InputValueDefinitionNode, NamedTypeNode, parse } from 'graphql';
|
3
4
|
import { getBaseType } from 'graphql-transformer-common';
|
4
5
|
import { Template } from 'aws-cdk-lib/assertions';
|
5
6
|
import { testTransform } from '@aws-amplify/graphql-transformer-test-utils';
|
6
|
-
import { ModelTransformer } from '../graphql-model-transformer';
|
7
7
|
import {
|
8
8
|
doNotExpectFields,
|
9
9
|
expectFields,
|
@@ -84,6 +84,29 @@ describe('ModelTransformer: ', () => {
|
|
84
84
|
expect(out.schema).toContain('input NonModelTypeInput');
|
85
85
|
});
|
86
86
|
|
87
|
+
it('id with non string type should require the field on create mutation', async () => {
|
88
|
+
const validSchema = `
|
89
|
+
type Task @model {
|
90
|
+
id: Int!
|
91
|
+
title: String!
|
92
|
+
}
|
93
|
+
`;
|
94
|
+
const out = testTransform({
|
95
|
+
schema: validSchema,
|
96
|
+
transformers: [new ModelTransformer()],
|
97
|
+
});
|
98
|
+
expect(out).toBeDefined();
|
99
|
+
|
100
|
+
validateModelSchema(parse(out.schema));
|
101
|
+
const schema = parse(out.schema);
|
102
|
+
expect(out.schema).toMatchSnapshot();
|
103
|
+
const createTaskInput = getInputType(schema, 'CreateTaskInput');
|
104
|
+
expectFieldsOnInputType(createTaskInput!, ['id', 'title']);
|
105
|
+
const idField = createTaskInput!.fields!.find((f) => f.name.value === 'id');
|
106
|
+
expect(idField).toBeDefined();
|
107
|
+
expect(idField?.type.kind).toEqual('NonNullType');
|
108
|
+
});
|
109
|
+
|
87
110
|
it('should support custom query overrides', () => {
|
88
111
|
const validSchema = `type Post @model(queries: { get: "customGetPost", list: "customListPost" }) {
|
89
112
|
id: ID!
|
@@ -1513,4 +1536,37 @@ describe('ModelTransformer: ', () => {
|
|
1513
1536
|
validateModelSchema(parse(out.schema));
|
1514
1537
|
parse(out.schema);
|
1515
1538
|
});
|
1539
|
+
|
1540
|
+
it('should successfully transform rds schema with array and object fields', async () => {
|
1541
|
+
const validSchema = `
|
1542
|
+
type Note @model {
|
1543
|
+
id: ID!
|
1544
|
+
content: String!
|
1545
|
+
tags: [String!]
|
1546
|
+
attachments: Attachment
|
1547
|
+
}
|
1548
|
+
|
1549
|
+
type Attachment {
|
1550
|
+
report: String!
|
1551
|
+
image: String!
|
1552
|
+
}
|
1553
|
+
`;
|
1554
|
+
|
1555
|
+
const modelToDatasourceMap = new Map<string, DatasourceType>();
|
1556
|
+
modelToDatasourceMap.set('Note', {
|
1557
|
+
dbType: 'MySQL',
|
1558
|
+
provisionDB: false,
|
1559
|
+
});
|
1560
|
+
const out = testTransform({
|
1561
|
+
schema: validSchema,
|
1562
|
+
transformers: [new ModelTransformer()],
|
1563
|
+
modelToDatasourceMap,
|
1564
|
+
});
|
1565
|
+
expect(out).toBeDefined();
|
1566
|
+
|
1567
|
+
validateModelSchema(parse(out.schema));
|
1568
|
+
parse(out.schema);
|
1569
|
+
expect(out.schema).toMatchSnapshot();
|
1570
|
+
expect(out.resolvers).toMatchSnapshot();
|
1571
|
+
});
|
1516
1572
|
});
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { TransformerTransformSchemaStepContextProvider } from '@aws-amplify/graphql-transformer-interfaces';
|
2
2
|
import { DocumentNode, InputObjectTypeDefinitionNode, ObjectTypeDefinitionNode } from 'graphql';
|
3
|
-
import { ModelResourceIDs, toPascalCase } from 'graphql-transformer-common';
|
3
|
+
import { ModelResourceIDs, getBaseType, toPascalCase } from 'graphql-transformer-common';
|
4
4
|
import { InputFieldWrapper, InputObjectDefinitionWrapper, ObjectDefinitionWrapper } from '@aws-amplify/graphql-transformer-core';
|
5
5
|
import { ModelDirectiveConfiguration } from '../directive';
|
6
6
|
import { makeConditionFilterInput } from './common';
|
@@ -104,7 +104,15 @@ export const makeCreateInputField = (
|
|
104
104
|
const typeName = objectWrapped.name;
|
105
105
|
const name = ModelResourceIDs.ModelCreateInputObjectName(typeName);
|
106
106
|
|
107
|
-
const
|
107
|
+
const idFieldName = 'id';
|
108
|
+
const hasIdField = objectWrapped.hasField(idFieldName);
|
109
|
+
let shouldAutogenerateIdField = false;
|
110
|
+
if (hasIdField) {
|
111
|
+
const idField = objectWrapped.getField(idFieldName);
|
112
|
+
const idBaseType = getBaseType(idField.type);
|
113
|
+
shouldAutogenerateIdField = idBaseType === 'ID' || idBaseType === 'String';
|
114
|
+
}
|
115
|
+
|
108
116
|
const fieldsToRemove = objectWrapped
|
109
117
|
.fields!.filter((field) => {
|
110
118
|
if (knownModelTypes.has(field.getTypeName())) {
|
@@ -126,7 +134,7 @@ export const makeCreateInputField = (
|
|
126
134
|
input.addField(InputFieldWrapper.create('id', 'ID', true));
|
127
135
|
} else {
|
128
136
|
const idField = input.fields.find((f) => f.name === 'id');
|
129
|
-
if (idField) {
|
137
|
+
if (idField && shouldAutogenerateIdField) {
|
130
138
|
idField.makeNullable();
|
131
139
|
}
|
132
140
|
}
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import { TransformerContextProvider } from '@aws-amplify/graphql-transformer-interfaces';
|
1
2
|
import {
|
2
3
|
generateUpdateRequestTemplate,
|
3
4
|
generateCreateRequestTemplate,
|
@@ -22,18 +23,19 @@ import {
|
|
22
23
|
} from './vtl-generator';
|
23
24
|
|
24
25
|
export class DynamoDBModelVTLGenerator implements ModelVTLGenerator {
|
25
|
-
generateUpdateRequestTemplate(config: ModelUpdateRequestConfig): string {
|
26
|
+
generateUpdateRequestTemplate(config: ModelUpdateRequestConfig, ctx: TransformerContextProvider): string {
|
26
27
|
return generateUpdateRequestTemplate(config.modelName, config.isSyncEnabled);
|
27
28
|
}
|
28
29
|
|
29
|
-
generateCreateRequestTemplate(config: ModelCreateRequestConfig): string {
|
30
|
+
generateCreateRequestTemplate(config: ModelCreateRequestConfig, ctx: TransformerContextProvider): string {
|
30
31
|
return generateCreateRequestTemplate(config.modelName, config.modelIndexFields);
|
31
32
|
}
|
33
|
+
|
32
34
|
generateCreateInitSlotTemplate(config: ModelCreateInitSlotConfig, initializeIdField: boolean): string {
|
33
35
|
return generateCreateInitSlotTemplate(config.modelConfig, initializeIdField);
|
34
36
|
}
|
35
37
|
|
36
|
-
generateDeleteRequestTemplate(config: ModelUpdateRequestConfig): string {
|
38
|
+
generateDeleteRequestTemplate(config: ModelUpdateRequestConfig, ctx: TransformerContextProvider): string {
|
37
39
|
return generateDeleteRequestTemplate(config.modelName, config.isSyncEnabled);
|
38
40
|
}
|
39
41
|
|
@@ -41,7 +43,7 @@ export class DynamoDBModelVTLGenerator implements ModelVTLGenerator {
|
|
41
43
|
return generateUpdateInitSlotTemplate(config.modelConfig);
|
42
44
|
}
|
43
45
|
|
44
|
-
generateGetRequestTemplate(config: ModelRequestConfig): string {
|
46
|
+
generateGetRequestTemplate(config: ModelRequestConfig, ctx: TransformerContextProvider): string {
|
45
47
|
return generateGetRequestTemplate();
|
46
48
|
}
|
47
49
|
|
@@ -49,7 +51,7 @@ export class DynamoDBModelVTLGenerator implements ModelVTLGenerator {
|
|
49
51
|
return generateGetResponseTemplate(config.isSyncEnabled);
|
50
52
|
}
|
51
53
|
|
52
|
-
generateListRequestTemplate(config: ModelRequestConfig): string {
|
54
|
+
generateListRequestTemplate(config: ModelRequestConfig, ctx: TransformerContextProvider): string {
|
53
55
|
return generateListRequestTemplate();
|
54
56
|
}
|
55
57
|
|
@@ -18,38 +18,40 @@ import {
|
|
18
18
|
ModelUpdateRequestConfig,
|
19
19
|
ModelVTLGenerator,
|
20
20
|
} from './vtl-generator';
|
21
|
+
import { TransformerContextProvider } from '@aws-amplify/graphql-transformer-interfaces';
|
21
22
|
|
22
23
|
// TODO: This class is created only to show the class structure. This needs a revisit to generate correct resolvers for RDS.
|
23
24
|
export class RDSModelVTLGenerator implements ModelVTLGenerator {
|
24
|
-
generateUpdateRequestTemplate(config: ModelUpdateRequestConfig): string {
|
25
|
-
return generateLambdaUpdateRequestTemplate(config.modelName, config.operationName, config.modelIndexFields ?? ['id']);
|
25
|
+
generateUpdateRequestTemplate(config: ModelUpdateRequestConfig, ctx: TransformerContextProvider): string {
|
26
|
+
return generateLambdaUpdateRequestTemplate(config.modelName, config.operationName, config.modelIndexFields ?? ['id'], ctx);
|
26
27
|
}
|
27
28
|
|
28
|
-
generateCreateRequestTemplate(config: ModelCreateRequestConfig): string {
|
29
|
-
return generateLambdaCreateRequestTemplate(config.modelName, config.operationName);
|
29
|
+
generateCreateRequestTemplate(config: ModelCreateRequestConfig, ctx: TransformerContextProvider): string {
|
30
|
+
return generateLambdaCreateRequestTemplate(config.modelName, config.operationName, ctx);
|
30
31
|
}
|
32
|
+
|
31
33
|
generateCreateInitSlotTemplate(config: ModelCreateInitSlotConfig, initializeIdField: boolean): string {
|
32
34
|
return generateCreateInitSlotTemplate(config.modelConfig, initializeIdField);
|
33
35
|
}
|
34
36
|
|
35
|
-
generateDeleteRequestTemplate(config: ModelUpdateRequestConfig): string {
|
36
|
-
return generateLambdaDeleteRequestTemplate(config.modelName, config.operationName, config.modelIndexFields ?? ['id']);
|
37
|
+
generateDeleteRequestTemplate(config: ModelUpdateRequestConfig, ctx: TransformerContextProvider): string {
|
38
|
+
return generateLambdaDeleteRequestTemplate(config.modelName, config.operationName, config.modelIndexFields ?? ['id'], ctx);
|
37
39
|
}
|
38
40
|
|
39
41
|
generateUpdateInitSlotTemplate(config: ModelCreateInitSlotConfig): string {
|
40
42
|
return generateUpdateInitSlotTemplate(config.modelConfig);
|
41
43
|
}
|
42
44
|
|
43
|
-
generateGetRequestTemplate(config: ModelRequestConfig): string {
|
44
|
-
return generateLambdaRequestTemplate(config.modelName, config.operation, config.operationName);
|
45
|
+
generateGetRequestTemplate(config: ModelRequestConfig, ctx: TransformerContextProvider): string {
|
46
|
+
return generateLambdaRequestTemplate(config.modelName, config.operation, config.operationName, ctx);
|
45
47
|
}
|
46
48
|
|
47
49
|
generateGetResponseTemplate(config: ModelUpdateRequestConfig): string {
|
48
50
|
return generateGetLambdaResponseTemplate(false);
|
49
51
|
}
|
50
52
|
|
51
|
-
generateListRequestTemplate(config: ModelRequestConfig): string {
|
52
|
-
return generateLambdaListRequestTemplate(config.modelName, config.operation, config.operationName);
|
53
|
+
generateListRequestTemplate(config: ModelRequestConfig, ctx: TransformerContextProvider): string {
|
54
|
+
return generateLambdaListRequestTemplate(config.modelName, config.operation, config.operationName, ctx);
|
53
55
|
}
|
54
56
|
|
55
57
|
generateSyncRequestTemplate(config: ModelRequestConfig): string {
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import { TransformerContextProvider } from '@aws-amplify/graphql-transformer-interfaces';
|
1
2
|
import { ModelDirectiveConfiguration } from '../../directive';
|
2
3
|
|
3
4
|
export type ModelRequestConfig = {
|
@@ -31,14 +32,14 @@ export type ModelDefaultResponseConfig = ModelRequestConfig & {
|
|
31
32
|
};
|
32
33
|
|
33
34
|
export interface ModelVTLGenerator {
|
34
|
-
generateUpdateRequestTemplate(config: ModelUpdateRequestConfig): string;
|
35
|
-
generateCreateRequestTemplate(config: ModelCreateRequestConfig): string;
|
35
|
+
generateUpdateRequestTemplate(config: ModelUpdateRequestConfig, ctx: TransformerContextProvider): string;
|
36
|
+
generateCreateRequestTemplate(config: ModelCreateRequestConfig, ctx: TransformerContextProvider): string;
|
36
37
|
generateCreateInitSlotTemplate(config: ModelCreateInitSlotConfig, initializeIdField: boolean): string;
|
37
|
-
generateDeleteRequestTemplate(config: ModelDeleteRequestConfig): string;
|
38
|
+
generateDeleteRequestTemplate(config: ModelDeleteRequestConfig, ctx: TransformerContextProvider): string;
|
38
39
|
generateUpdateInitSlotTemplate(config: ModelUpdateInitSlotConfig): string;
|
39
|
-
generateGetRequestTemplate(config: ModelRequestConfig): string;
|
40
|
+
generateGetRequestTemplate(config: ModelRequestConfig, ctx: TransformerContextProvider): string;
|
40
41
|
generateGetResponseTemplate(config: ModelGetResponseConfig): string;
|
41
|
-
generateListRequestTemplate(config: ModelRequestConfig): string;
|
42
|
+
generateListRequestTemplate(config: ModelRequestConfig, ctx: TransformerContextProvider): string;
|
42
43
|
generateSyncRequestTemplate(config: ModelRequestConfig): string;
|
43
44
|
generateSubscriptionRequestTemplate(): string;
|
44
45
|
generateSubscriptionResponseTemplate(): string;
|
@@ -12,7 +12,9 @@ import {
|
|
12
12
|
str,
|
13
13
|
toJson,
|
14
14
|
} from 'graphql-mapping-template';
|
15
|
+
import { TransformerContextProvider } from '@aws-amplify/graphql-transformer-interfaces';
|
15
16
|
import { ModelDirectiveConfiguration } from '../../directive';
|
17
|
+
import { constructNonScalarFieldsStatement } from './resolver';
|
16
18
|
|
17
19
|
/**
|
18
20
|
* Generate mapping template that sets default values for create mutation
|
@@ -53,7 +55,7 @@ export const generateCreateInitSlotTemplate = (modelConfig: ModelDirectiveConfig
|
|
53
55
|
return printBlock('Initialization default values')(compoundExpression(statements));
|
54
56
|
};
|
55
57
|
|
56
|
-
export const generateLambdaCreateRequestTemplate = (tableName: string, operationName: string): string =>
|
58
|
+
export const generateLambdaCreateRequestTemplate = (tableName: string, operationName: string, ctx: TransformerContextProvider): string =>
|
57
59
|
printBlock('Invoke RDS Lambda data source')(
|
58
60
|
compoundExpression([
|
59
61
|
set(ref('lambdaInput'), obj({})),
|
@@ -63,6 +65,7 @@ export const generateLambdaCreateRequestTemplate = (tableName: string, operation
|
|
63
65
|
set(ref('lambdaInput.operationName'), str(operationName)),
|
64
66
|
set(ref('lambdaInput.args.metadata'), obj({})),
|
65
67
|
set(ref('lambdaInput.args.metadata.keys'), list([])),
|
68
|
+
constructNonScalarFieldsStatement(tableName, ctx),
|
66
69
|
qref(
|
67
70
|
methodCall(ref('lambdaInput.args.metadata.keys.addAll'), methodCall(ref('util.defaultIfNull'), ref('ctx.stash.keys'), list([]))),
|
68
71
|
),
|
@@ -115,7 +118,12 @@ export const generateUpdateInitSlotTemplate = (modelConfig: ModelDirectiveConfig
|
|
115
118
|
/**
|
116
119
|
* Generate VTL template that calls the lambda for an Update mutation
|
117
120
|
*/
|
118
|
-
export const generateLambdaUpdateRequestTemplate = (
|
121
|
+
export const generateLambdaUpdateRequestTemplate = (
|
122
|
+
tableName: string,
|
123
|
+
operationName: string,
|
124
|
+
modelIndexFields: string[],
|
125
|
+
ctx: TransformerContextProvider,
|
126
|
+
): string =>
|
119
127
|
printBlock('Invoke RDS Lambda data source')(
|
120
128
|
compoundExpression([
|
121
129
|
set(ref('lambdaInput'), obj({})),
|
@@ -125,6 +133,7 @@ export const generateLambdaUpdateRequestTemplate = (tableName: string, operation
|
|
125
133
|
set(ref('lambdaInput.operationName'), str(operationName)),
|
126
134
|
set(ref('lambdaInput.args.metadata'), obj({})),
|
127
135
|
set(ref('lambdaInput.args.metadata.keys'), list([])),
|
136
|
+
constructNonScalarFieldsStatement(tableName, ctx),
|
128
137
|
qref(
|
129
138
|
methodCall(ref('lambdaInput.args.metadata.keys.addAll'), methodCall(ref('util.defaultIfNull'), ref('ctx.stash.keys'), list([]))),
|
130
139
|
),
|
@@ -146,7 +155,12 @@ export const generateLambdaUpdateRequestTemplate = (tableName: string, operation
|
|
146
155
|
/**
|
147
156
|
* Generate VTL template that calls the lambda for a Delete mutation
|
148
157
|
*/
|
149
|
-
export const generateLambdaDeleteRequestTemplate = (
|
158
|
+
export const generateLambdaDeleteRequestTemplate = (
|
159
|
+
tableName: string,
|
160
|
+
operationName: string,
|
161
|
+
modelIndexFields: string[],
|
162
|
+
ctx: TransformerContextProvider,
|
163
|
+
): string =>
|
150
164
|
printBlock('Invoke RDS Lambda data source')(
|
151
165
|
compoundExpression([
|
152
166
|
set(ref('lambdaInput'), obj({})),
|
@@ -156,6 +170,7 @@ export const generateLambdaDeleteRequestTemplate = (tableName: string, operation
|
|
156
170
|
set(ref('lambdaInput.operationName'), str(operationName)),
|
157
171
|
set(ref('lambdaInput.args.metadata'), obj({})),
|
158
172
|
set(ref('lambdaInput.args.metadata.keys'), list([])),
|
173
|
+
constructNonScalarFieldsStatement(tableName, ctx),
|
159
174
|
qref(
|
160
175
|
methodCall(ref('lambdaInput.args.metadata.keys.addAll'), methodCall(ref('util.defaultIfNull'), ref('ctx.stash.keys'), list([]))),
|
161
176
|
),
|
@@ -1,6 +1,13 @@
|
|
1
|
+
import { TransformerContextProvider } from '@aws-amplify/graphql-transformer-interfaces';
|
1
2
|
import { compoundExpression, list, methodCall, obj, printBlock, qref, ref, set, str } from 'graphql-mapping-template';
|
3
|
+
import { constructNonScalarFieldsStatement } from './resolver';
|
2
4
|
|
3
|
-
export const generateLambdaListRequestTemplate = (
|
5
|
+
export const generateLambdaListRequestTemplate = (
|
6
|
+
tableName: string,
|
7
|
+
operation: string,
|
8
|
+
operationName: string,
|
9
|
+
ctx: TransformerContextProvider,
|
10
|
+
): string => {
|
4
11
|
return printBlock('Invoke RDS Lambda data source')(
|
5
12
|
compoundExpression([
|
6
13
|
set(ref('lambdaInput'), obj({})),
|
@@ -10,6 +17,7 @@ export const generateLambdaListRequestTemplate = (tableName: string, operation:
|
|
10
17
|
set(ref('lambdaInput.operationName'), str(operationName)),
|
11
18
|
set(ref('lambdaInput.args.metadata'), obj({})),
|
12
19
|
set(ref('lambdaInput.args.metadata.keys'), list([])),
|
20
|
+
constructNonScalarFieldsStatement(tableName, ctx),
|
13
21
|
qref(
|
14
22
|
methodCall(ref('lambdaInput.args.metadata.keys.addAll'), methodCall(ref('util.defaultIfNull'), ref('ctx.stash.keys'), list([]))),
|
15
23
|
),
|
@@ -13,14 +13,15 @@ import {
|
|
13
13
|
str,
|
14
14
|
toJson,
|
15
15
|
} from 'graphql-mapping-template';
|
16
|
-
import { ResourceConstants } from 'graphql-transformer-common';
|
16
|
+
import { ResourceConstants, isArrayOrObject } from 'graphql-transformer-common';
|
17
17
|
import { RDSConnectionSecrets, setResourceName } from '@aws-amplify/graphql-transformer-core';
|
18
|
-
import { GraphQLAPIProvider, RDSLayerMapping } from '@aws-amplify/graphql-transformer-interfaces';
|
18
|
+
import { GraphQLAPIProvider, RDSLayerMapping, TransformerContextProvider } from '@aws-amplify/graphql-transformer-interfaces';
|
19
19
|
import { Effect, IRole, Policy, PolicyStatement, Role, ServicePrincipal } from 'aws-cdk-lib/aws-iam';
|
20
20
|
import { IFunction, LayerVersion, Runtime } from 'aws-cdk-lib/aws-lambda';
|
21
21
|
import { Construct } from 'constructs';
|
22
22
|
import path from 'path';
|
23
23
|
import { VpcConfig } from '@aws-amplify/graphql-transformer-interfaces/src';
|
24
|
+
import { EnumTypeDefinitionNode, FieldDefinitionNode, Kind, ObjectTypeDefinitionNode } from 'graphql';
|
24
25
|
|
25
26
|
/**
|
26
27
|
* Define RDS Lambda operations
|
@@ -44,6 +45,7 @@ const getLatestLayers = (latestLayers?: RDSLayerMapping): RDSLayerMapping => {
|
|
44
45
|
if (latestLayers && Object.keys(latestLayers).length > 0) {
|
45
46
|
return latestLayers;
|
46
47
|
}
|
48
|
+
console.warn('Unable to load the latest RDS layer configuration, using local configuration.');
|
47
49
|
const defaultLayerMapping = getDefaultLayerMapping();
|
48
50
|
return defaultLayerMapping;
|
49
51
|
};
|
@@ -52,73 +54,73 @@ const getLatestLayers = (latestLayers?: RDSLayerMapping): RDSLayerMapping => {
|
|
52
54
|
// For prod use account '582037449441', layer name 'AmplifyRDSLayer' and layer version '3' as of 2023-06-20
|
53
55
|
const getDefaultLayerMapping = (): RDSLayerMapping => ({
|
54
56
|
'ap-northeast-1': {
|
55
|
-
layerRegion: 'arn:aws:lambda:ap-northeast-1:582037449441:layer:AmplifyRDSLayer:
|
57
|
+
layerRegion: 'arn:aws:lambda:ap-northeast-1:582037449441:layer:AmplifyRDSLayer:14',
|
56
58
|
},
|
57
59
|
'us-east-1': {
|
58
|
-
layerRegion: 'arn:aws:lambda:us-east-1:582037449441:layer:AmplifyRDSLayer:
|
60
|
+
layerRegion: 'arn:aws:lambda:us-east-1:582037449441:layer:AmplifyRDSLayer:14',
|
59
61
|
},
|
60
62
|
'ap-southeast-1': {
|
61
|
-
layerRegion: 'arn:aws:lambda:ap-southeast-1:582037449441:layer:AmplifyRDSLayer:
|
63
|
+
layerRegion: 'arn:aws:lambda:ap-southeast-1:582037449441:layer:AmplifyRDSLayer:14',
|
62
64
|
},
|
63
65
|
'eu-west-1': {
|
64
|
-
layerRegion: 'arn:aws:lambda:eu-west-1:582037449441:layer:AmplifyRDSLayer:
|
66
|
+
layerRegion: 'arn:aws:lambda:eu-west-1:582037449441:layer:AmplifyRDSLayer:14',
|
65
67
|
},
|
66
68
|
'us-west-1': {
|
67
|
-
layerRegion: 'arn:aws:lambda:us-west-1:582037449441:layer:AmplifyRDSLayer:
|
69
|
+
layerRegion: 'arn:aws:lambda:us-west-1:582037449441:layer:AmplifyRDSLayer:14',
|
68
70
|
},
|
69
71
|
'ap-east-1': {
|
70
|
-
layerRegion: 'arn:aws:lambda:ap-east-1:582037449441:layer:AmplifyRDSLayer:
|
72
|
+
layerRegion: 'arn:aws:lambda:ap-east-1:582037449441:layer:AmplifyRDSLayer:14',
|
71
73
|
},
|
72
74
|
'ap-northeast-2': {
|
73
|
-
layerRegion: 'arn:aws:lambda:ap-northeast-2:582037449441:layer:AmplifyRDSLayer:
|
75
|
+
layerRegion: 'arn:aws:lambda:ap-northeast-2:582037449441:layer:AmplifyRDSLayer:14',
|
74
76
|
},
|
75
77
|
'ap-northeast-3': {
|
76
|
-
layerRegion: 'arn:aws:lambda:ap-northeast-3:582037449441:layer:AmplifyRDSLayer:
|
78
|
+
layerRegion: 'arn:aws:lambda:ap-northeast-3:582037449441:layer:AmplifyRDSLayer:14',
|
77
79
|
},
|
78
80
|
'ap-south-1': {
|
79
|
-
layerRegion: 'arn:aws:lambda:ap-south-1:582037449441:layer:AmplifyRDSLayer:
|
81
|
+
layerRegion: 'arn:aws:lambda:ap-south-1:582037449441:layer:AmplifyRDSLayer:14',
|
80
82
|
},
|
81
83
|
'ap-southeast-2': {
|
82
|
-
layerRegion: 'arn:aws:lambda:ap-southeast-2:582037449441:layer:AmplifyRDSLayer:
|
84
|
+
layerRegion: 'arn:aws:lambda:ap-southeast-2:582037449441:layer:AmplifyRDSLayer:14',
|
83
85
|
},
|
84
86
|
'ca-central-1': {
|
85
|
-
layerRegion: 'arn:aws:lambda:ca-central-1:582037449441:layer:AmplifyRDSLayer:
|
87
|
+
layerRegion: 'arn:aws:lambda:ca-central-1:582037449441:layer:AmplifyRDSLayer:14',
|
86
88
|
},
|
87
89
|
'eu-central-1': {
|
88
|
-
layerRegion: 'arn:aws:lambda:eu-central-1:582037449441:layer:AmplifyRDSLayer:
|
90
|
+
layerRegion: 'arn:aws:lambda:eu-central-1:582037449441:layer:AmplifyRDSLayer:14',
|
89
91
|
},
|
90
92
|
'eu-north-1': {
|
91
|
-
layerRegion: 'arn:aws:lambda:eu-north-1:582037449441:layer:AmplifyRDSLayer:
|
93
|
+
layerRegion: 'arn:aws:lambda:eu-north-1:582037449441:layer:AmplifyRDSLayer:14',
|
92
94
|
},
|
93
95
|
'eu-west-2': {
|
94
|
-
layerRegion: 'arn:aws:lambda:eu-west-2:582037449441:layer:AmplifyRDSLayer:
|
96
|
+
layerRegion: 'arn:aws:lambda:eu-west-2:582037449441:layer:AmplifyRDSLayer:14',
|
95
97
|
},
|
96
98
|
'eu-west-3': {
|
97
|
-
layerRegion: 'arn:aws:lambda:eu-west-3:582037449441:layer:AmplifyRDSLayer:
|
99
|
+
layerRegion: 'arn:aws:lambda:eu-west-3:582037449441:layer:AmplifyRDSLayer:14',
|
98
100
|
},
|
99
101
|
'sa-east-1': {
|
100
|
-
layerRegion: 'arn:aws:lambda:sa-east-1:582037449441:layer:AmplifyRDSLayer:
|
102
|
+
layerRegion: 'arn:aws:lambda:sa-east-1:582037449441:layer:AmplifyRDSLayer:14',
|
101
103
|
},
|
102
104
|
'us-east-2': {
|
103
|
-
layerRegion: 'arn:aws:lambda:us-east-2:582037449441:layer:AmplifyRDSLayer:
|
105
|
+
layerRegion: 'arn:aws:lambda:us-east-2:582037449441:layer:AmplifyRDSLayer:14',
|
104
106
|
},
|
105
107
|
'us-west-2': {
|
106
|
-
layerRegion: 'arn:aws:lambda:us-west-2:582037449441:layer:AmplifyRDSLayer:
|
108
|
+
layerRegion: 'arn:aws:lambda:us-west-2:582037449441:layer:AmplifyRDSLayer:14',
|
107
109
|
},
|
108
110
|
'cn-north-1': {
|
109
|
-
layerRegion: 'arn:aws:lambda:cn-north-1:582037449441:layer:AmplifyRDSLayer:
|
111
|
+
layerRegion: 'arn:aws:lambda:cn-north-1:582037449441:layer:AmplifyRDSLayer:14',
|
110
112
|
},
|
111
113
|
'cn-northwest-1': {
|
112
|
-
layerRegion: 'arn:aws:lambda:cn-northwest-1:582037449441:layer:AmplifyRDSLayer:
|
114
|
+
layerRegion: 'arn:aws:lambda:cn-northwest-1:582037449441:layer:AmplifyRDSLayer:14',
|
113
115
|
},
|
114
116
|
'us-gov-west-1': {
|
115
|
-
layerRegion: 'arn:aws:lambda:us-gov-west-1:582037449441:layer:AmplifyRDSLayer:
|
117
|
+
layerRegion: 'arn:aws:lambda:us-gov-west-1:582037449441:layer:AmplifyRDSLayer:14',
|
116
118
|
},
|
117
119
|
'us-gov-east-1': {
|
118
|
-
layerRegion: 'arn:aws:lambda:us-gov-east-1:582037449441:layer:AmplifyRDSLayer:
|
120
|
+
layerRegion: 'arn:aws:lambda:us-gov-east-1:582037449441:layer:AmplifyRDSLayer:14',
|
119
121
|
},
|
120
122
|
'me-south-1': {
|
121
|
-
layerRegion: 'arn:aws:lambda:me-south-1:582037449441:layer:AmplifyRDSLayer:
|
123
|
+
layerRegion: 'arn:aws:lambda:me-south-1:582037449441:layer:AmplifyRDSLayer:14',
|
122
124
|
},
|
123
125
|
});
|
124
126
|
|
@@ -295,7 +297,12 @@ export const createRdsPatchingLambdaRole = (roleName: string, scope: Construct,
|
|
295
297
|
* @param operation string
|
296
298
|
* @param operationName string
|
297
299
|
*/
|
298
|
-
export const generateLambdaRequestTemplate = (
|
300
|
+
export const generateLambdaRequestTemplate = (
|
301
|
+
tableName: string,
|
302
|
+
operation: string,
|
303
|
+
operationName: string,
|
304
|
+
ctx: TransformerContextProvider,
|
305
|
+
): string =>
|
299
306
|
printBlock('Invoke RDS Lambda data source')(
|
300
307
|
compoundExpression([
|
301
308
|
set(ref('lambdaInput'), obj({})),
|
@@ -305,6 +312,7 @@ export const generateLambdaRequestTemplate = (tableName: string, operation: stri
|
|
305
312
|
set(ref('lambdaInput.operationName'), str(operationName)),
|
306
313
|
set(ref('lambdaInput.args.metadata'), obj({})),
|
307
314
|
set(ref('lambdaInput.args.metadata.keys'), list([])),
|
315
|
+
constructNonScalarFieldsStatement(tableName, ctx),
|
308
316
|
qref(
|
309
317
|
methodCall(ref('lambdaInput.args.metadata.keys.addAll'), methodCall(ref('util.defaultIfNull'), ref('ctx.stash.keys'), list([]))),
|
310
318
|
),
|
@@ -366,3 +374,14 @@ export const generateDefaultLambdaResponseMappingTemplate = (isSyncEnabled: bool
|
|
366
374
|
|
367
375
|
return printBlock('ResponseTemplate')(compoundExpression(statements));
|
368
376
|
};
|
377
|
+
|
378
|
+
export const getNonScalarFields = (object: ObjectTypeDefinitionNode | undefined, ctx: TransformerContextProvider): string[] => {
|
379
|
+
if (!object) {
|
380
|
+
return [];
|
381
|
+
}
|
382
|
+
const enums = ctx.output.getTypeDefinitionsOfKind(Kind.ENUM_TYPE_DEFINITION) as EnumTypeDefinitionNode[];
|
383
|
+
return object.fields?.filter((f: FieldDefinitionNode) => isArrayOrObject(f.type, enums)).map((f) => f.name.value) || [];
|
384
|
+
};
|
385
|
+
|
386
|
+
export const constructNonScalarFieldsStatement = (tableName: string, ctx: TransformerContextProvider): Expression =>
|
387
|
+
set(ref('lambdaInput.args.metadata.nonScalarFields'), list(getNonScalarFields(ctx.output.getObject(tableName), ctx).map(str)));
|
@@ -252,7 +252,7 @@ export abstract class ModelResourceGenerator {
|
|
252
252
|
resolverLogicalId,
|
253
253
|
dataSource,
|
254
254
|
MappingTemplate.s3MappingTemplateFromString(
|
255
|
-
vtlGenerator.generateGetRequestTemplate(requestConfig),
|
255
|
+
vtlGenerator.generateGetRequestTemplate(requestConfig, ctx),
|
256
256
|
`${typeName}.${fieldName}.req.vtl`,
|
257
257
|
),
|
258
258
|
MappingTemplate.s3MappingTemplateFromString(
|
@@ -292,7 +292,7 @@ export abstract class ModelResourceGenerator {
|
|
292
292
|
resolverLogicalId,
|
293
293
|
dataSource,
|
294
294
|
MappingTemplate.s3MappingTemplateFromString(
|
295
|
-
vtlGenerator.generateListRequestTemplate(requestConfig),
|
295
|
+
vtlGenerator.generateListRequestTemplate(requestConfig, ctx),
|
296
296
|
`${typeName}.${fieldName}.req.vtl`,
|
297
297
|
),
|
298
298
|
MappingTemplate.s3MappingTemplateFromString(
|
@@ -338,7 +338,7 @@ export abstract class ModelResourceGenerator {
|
|
338
338
|
resolverLogicalId,
|
339
339
|
dataSource,
|
340
340
|
MappingTemplate.s3MappingTemplateFromString(
|
341
|
-
vtlGenerator.generateCreateRequestTemplate(requestConfig),
|
341
|
+
vtlGenerator.generateCreateRequestTemplate(requestConfig, ctx),
|
342
342
|
`${typeName}.${fieldName}.req.vtl`,
|
343
343
|
),
|
344
344
|
MappingTemplate.s3MappingTemplateFromString(
|
@@ -400,7 +400,7 @@ export abstract class ModelResourceGenerator {
|
|
400
400
|
resolverLogicalId,
|
401
401
|
dataSource,
|
402
402
|
MappingTemplate.s3MappingTemplateFromString(
|
403
|
-
vtlGenerator.generateUpdateRequestTemplate(requestConfig),
|
403
|
+
vtlGenerator.generateUpdateRequestTemplate(requestConfig, ctx),
|
404
404
|
`${typeName}.${fieldName}.req.vtl`,
|
405
405
|
),
|
406
406
|
MappingTemplate.s3MappingTemplateFromString(
|
@@ -461,7 +461,7 @@ export abstract class ModelResourceGenerator {
|
|
461
461
|
resolverLogicalId,
|
462
462
|
dataSource,
|
463
463
|
MappingTemplate.s3MappingTemplateFromString(
|
464
|
-
vtlGenerator.generateDeleteRequestTemplate(requestConfig),
|
464
|
+
vtlGenerator.generateDeleteRequestTemplate(requestConfig, ctx),
|
465
465
|
`${typeName}.${fieldName}.req.vtl`,
|
466
466
|
),
|
467
467
|
MappingTemplate.s3MappingTemplateFromString(
|