Skip to content

Commit d2f2c60

Browse files
authored
feat: Add introspection, resolverCountLImit and queryDepthLImit config (#625)
1 parent 3634639 commit d2f2c60

File tree

7 files changed

+81
-0
lines changed

7 files changed

+81
-0
lines changed

src/__tests__/api.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,38 @@ describe('Api', () => {
5858
`);
5959
});
6060

61+
it('should compile the Api Resource with config', () => {
62+
const api = new Api(
63+
given.appSyncConfig({
64+
introspection: false,
65+
queryDepthLimit: 10,
66+
resolverCountLimit: 20,
67+
}),
68+
plugin,
69+
);
70+
expect(api.compileEndpoint()).toMatchInlineSnapshot(`
71+
Object {
72+
"GraphQlApi": Object {
73+
"Properties": Object {
74+
"AuthenticationType": "API_KEY",
75+
"IntrospectionConfig": "DISABLED",
76+
"Name": "MyApi",
77+
"QueryDepthLimit": 10,
78+
"ResolverCountLimit": 20,
79+
"Tags": Array [
80+
Object {
81+
"Key": "stage",
82+
"Value": "Dev",
83+
},
84+
],
85+
"XrayEnabled": false,
86+
},
87+
"Type": "AWS::AppSync::GraphQLApi",
88+
},
89+
}
90+
`);
91+
});
92+
6193
it('should compile the Api Resource with logs enabled', () => {
6294
const api = new Api(
6395
given.appSyncConfig({

src/__tests__/validation/__snapshots__/base.test.ts.snap

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,13 @@ exports[`Valdiation should validate 1`] = `
5757
/unknownPorp: invalid (unknown) property
5858
/xrayEnabled: must be boolean
5959
/visibility: must be \\"GLOBAL\\" or \\"PRIVATE\\"
60+
/introspection: must be boolean
61+
/queryDepthLimit: must be integer
62+
/resolverCountLimit: must be integer
6063
/esbuild: must be an esbuild config object or false"
6164
`;
65+
66+
exports[`Valdiation should validate 2`] = `
67+
"/queryDepthLimit: must be <= 75
68+
/resolverCountLimit: must be <= 1000"
69+
`;

src/__tests__/validation/base.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ describe('Valdiation', () => {
88
validateConfig({
99
...basicConfig,
1010
visibility: 'GLOBAL',
11+
introspection: true,
12+
queryDepthLimit: 10,
13+
resolverCountLimit: 10,
1114
xrayEnabled: true,
1215
tags: {
1316
foo: 'bar',
@@ -23,11 +26,22 @@ describe('Valdiation', () => {
2326
expect(function () {
2427
validateConfig({
2528
visibility: 'FOO',
29+
introspection: 10,
30+
queryDepthLimit: 'foo',
31+
resolverCountLimit: 'bar',
2632
xrayEnabled: 'BAR',
2733
unknownPorp: 'foo',
2834
esbuild: 'bad',
2935
});
3036
}).toThrowErrorMatchingSnapshot();
37+
38+
expect(function () {
39+
validateConfig({
40+
...basicConfig,
41+
queryDepthLimit: 76,
42+
resolverCountLimit: 1001,
43+
});
44+
}).toThrowErrorMatchingSnapshot();
3145
});
3246

3347
describe('Log', () => {

src/resources/Api.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,24 @@ export class Api {
111111
});
112112
}
113113

114+
if (this.config.introspection !== undefined) {
115+
merge(endpointResource.Properties, {
116+
IntrospectionConfig: this.config.introspection ? 'ENABLED' : 'DISABLED',
117+
});
118+
}
119+
120+
if (this.config.queryDepthLimit !== undefined) {
121+
merge(endpointResource.Properties, {
122+
QueryDepthLimit: this.config.queryDepthLimit,
123+
});
124+
}
125+
126+
if (this.config.resolverCountLimit !== undefined) {
127+
merge(endpointResource.Properties, {
128+
ResolverCountLimit: this.config.resolverCountLimit,
129+
});
130+
}
131+
114132
const resources = {
115133
[logicalId]: endpointResource,
116134
};

src/types/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ export type AppSyncConfig = {
4040
tags?: Record<string, string>;
4141
visibility?: 'GLOBAL' | 'PRIVATE';
4242
esbuild?: BuildOptions | false;
43+
introspection?: boolean;
44+
queryDepthLimit?: number;
45+
resolverCountLimit?: number;
4346
};
4447

4548
export type BaseResolverConfig = {

src/types/plugin.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ export type AppSyncConfig = {
3636
tags?: Record<string, string>;
3737
visibility?: 'GLOBAL' | 'PRIVATE';
3838
esbuild?: BuildOptions | false;
39+
introspection?: boolean;
40+
queryDepthLimit?: number;
41+
resolverCountLimit?: number;
3942
};
4043

4144
export type BaseResolverConfig = {

src/validation.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,9 @@ export const appSyncSchema = {
683683
enum: ['GLOBAL', 'PRIVATE'],
684684
errorMessage: 'must be "GLOBAL" or "PRIVATE"',
685685
},
686+
introspection: { type: 'boolean' },
687+
queryDepthLimit: { type: 'integer', minimum: 1, maximum: 75 },
688+
resolverCountLimit: { type: 'integer', minimum: 1, maximum: 1000 },
686689
substitutions: { $ref: '#/definitions/substitutions' },
687690
waf: {
688691
type: 'object',

0 commit comments

Comments
 (0)