Skip to content

Commit e89240f

Browse files
naedxstocaarojjarvisp
authored
feat(data-schema): accept null to disable queryField for secondary indexes (#567)
Co-authored-by: Aaron S. <94858815+stocaaro@users.noreply.github.com> Co-authored-by: James Jarvis <jjarvisp@amazon.com>
1 parent 57e595b commit e89240f

File tree

5 files changed

+114
-7
lines changed

5 files changed

+114
-7
lines changed

.changeset/crazy-pets-sniff.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@aws-amplify/data-schema': minor
3+
---
4+
5+
Accept null to disable queryField for secondary indexes

packages/data-schema/__tests__/ModelIndex.test.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,4 +128,58 @@ describe('SchemaProcessor validation against secondary indexes', () => {
128128
'The ref field `status` used in the secondary index of `Todo` should refer to an enum type. `TodoStatus` is not a enum type.',
129129
);
130130
});
131+
132+
it('creates a queryField with a default name', () => {
133+
const schema = a
134+
.schema({
135+
Todo: a
136+
.model({
137+
title: a.string().required(),
138+
content: a.string(),
139+
status: a.enum(['open', 'in_progress', 'completed']),
140+
})
141+
.secondaryIndexes((index) => [
142+
index('status').sortKeys(['title'])
143+
]),
144+
})
145+
.authorization((allow) => allow.publicApiKey());
146+
147+
expect(schema.transform().schema).toMatchSnapshot();
148+
});
149+
150+
it('creates a queryField with user-defined name', () => {
151+
const schema = a
152+
.schema({
153+
Todo: a
154+
.model({
155+
title: a.string().required(),
156+
content: a.string(),
157+
status: a.enum(['open', 'in_progress', 'completed']),
158+
})
159+
.secondaryIndexes((index) => [
160+
index('status').sortKeys(['title']).queryField('userDefinedQueryField')
161+
]),
162+
})
163+
.authorization((allow) => allow.publicApiKey());
164+
165+
expect(schema.transform().schema).toMatchSnapshot();
166+
});
167+
168+
it('omits the queryField if null is provided instead of a name', () => {
169+
const schema = a
170+
.schema({
171+
Todo: a
172+
.model({
173+
title: a.string().required(),
174+
content: a.string(),
175+
status: a.enum(['open', 'in_progress', 'completed']),
176+
})
177+
.secondaryIndexes((index) => [
178+
index('status').sortKeys(['title']).queryField(null)
179+
]),
180+
})
181+
.authorization((allow) => allow.publicApiKey());
182+
183+
expect(schema.transform().schema).toMatchSnapshot();
184+
});
131185
});

packages/data-schema/__tests__/__snapshots__/ModelIndex.test.ts.snap

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,50 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`SchemaProcessor validation against secondary indexes creates a queryField with a default name 1`] = `
4+
"type Todo @model @auth(rules: [{allow: public, provider: apiKey}])
5+
{
6+
title: String!
7+
content: String
8+
status: TodoStatus @index(sortKeyFields: ["title"], queryField: "listTodoByStatusAndTitle")
9+
}
10+
11+
enum TodoStatus {
12+
open
13+
in_progress
14+
completed
15+
}"
16+
`;
17+
18+
exports[`SchemaProcessor validation against secondary indexes creates a queryField with user-defined name 1`] = `
19+
"type Todo @model @auth(rules: [{allow: public, provider: apiKey}])
20+
{
21+
title: String!
22+
content: String
23+
status: TodoStatus @index(sortKeyFields: ["title"], queryField: "userDefinedQueryField")
24+
}
25+
26+
enum TodoStatus {
27+
open
28+
in_progress
29+
completed
30+
}"
31+
`;
32+
33+
exports[`SchemaProcessor validation against secondary indexes omits the queryField if null is provided instead of a name 1`] = `
34+
"type Todo @model @auth(rules: [{allow: public, provider: apiKey}])
35+
{
36+
title: String!
37+
content: String
38+
status: TodoStatus @index(sortKeyFields: ["title"], queryField: null)
39+
}
40+
41+
enum TodoStatus {
42+
open
43+
in_progress
44+
completed
45+
}"
46+
`;
47+
348
exports[`secondary index schema generation generates correct schema for using a.enum() as the partition key 1`] = `
449
"type Todo @model @auth(rules: [{allow: public, provider: apiKey}])
550
{

packages/data-schema/src/ModelIndex.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export type ModelIndexData = {
66
partitionKey: string;
77
sortKeys: readonly unknown[];
88
indexName: string;
9-
queryField: string;
9+
queryField: string | null;
1010
};
1111

1212
export type InternalModelIndexType = ModelIndexType<any, any, any, any> & {
@@ -31,7 +31,7 @@ export type ModelIndexType<
3131
name: string,
3232
): ModelIndexType<ModelFieldKeys, PK, SK, QueryField, K | 'name'>;
3333
queryField<
34-
QF extends string = never,
34+
QF extends string | null = never,
3535
MF extends ModelFieldKeys = ModelFieldKeys,
3636
>(
3737
field: QF,

packages/data-schema/src/SchemaProcessor.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ function scalarFieldToGql(
217217
for (const index of secondaryIndexes) {
218218
field += ` ${index}`;
219219
}
220-
220+
221221
// Add validation directives for each validation rule
222222
for (const validationRule of validation) {
223223
const valueStr = typeof validationRule.value === 'number' ? validationRule.value.toString() : validationRule.value;
@@ -227,7 +227,7 @@ function scalarFieldToGql(
227227
field += ` @validate(type: ${validationRule.type}, value: "${valueStr}")`;
228228
}
229229
}
230-
230+
231231
return field;
232232
}
233233

@@ -1116,7 +1116,7 @@ const transformedSecondaryIndexesForModel = (
11161116
partitionKey: string,
11171117
sortKeys: readonly string[],
11181118
indexName: string,
1119-
queryField: string,
1119+
queryField: string | null,
11201120
): string => {
11211121
for (const keyName of [partitionKey, ...sortKeys]) {
11221122
const field = modelFields[keyName];
@@ -1131,7 +1131,7 @@ const transformedSecondaryIndexesForModel = (
11311131
}
11321132
}
11331133

1134-
if (!sortKeys.length && !indexName && !queryField) {
1134+
if (!sortKeys.length && !indexName && !queryField && queryField !== null) {
11351135
return `@index(queryField: "${secondaryIndexDefaultQueryField(
11361136
modelName,
11371137
partitionKey,
@@ -1150,7 +1150,10 @@ const transformedSecondaryIndexesForModel = (
11501150
);
11511151
}
11521152

1153-
if (queryField) {
1153+
if(queryField === null) {
1154+
attributes.push(`queryField: null`);
1155+
}
1156+
else if (queryField) {
11541157
attributes.push(`queryField: "${queryField}"`);
11551158
} else {
11561159
attributes.push(

0 commit comments

Comments
 (0)