@aws-amplify/data-schema 0.16.2 → 0.17.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/dist/cjs/runtime/internals/operations/custom.js +33 -5
- package/dist/cjs/runtime/internals/operations/custom.js.map +1 -1
- package/dist/cjs/runtime/internals/operations/get.js +36 -6
- package/dist/cjs/runtime/internals/operations/get.js.map +1 -1
- package/dist/cjs/runtime/internals/operations/indexQuery.js +39 -11
- package/dist/cjs/runtime/internals/operations/indexQuery.js.map +1 -1
- package/dist/cjs/runtime/internals/operations/list.js +50 -6
- package/dist/cjs/runtime/internals/operations/list.js.map +1 -1
- package/dist/cjs/runtime/internals/operations/utils.js +42 -0
- package/dist/cjs/runtime/internals/operations/utils.js.map +1 -0
- package/dist/esm/Authorization.d.ts +2 -2
- package/dist/esm/ModelRelationalField.d.ts +1 -1
- package/dist/esm/runtime/internals/operations/custom.mjs +33 -5
- package/dist/esm/runtime/internals/operations/custom.mjs.map +1 -1
- package/dist/esm/runtime/internals/operations/get.mjs +36 -6
- package/dist/esm/runtime/internals/operations/get.mjs.map +1 -1
- package/dist/esm/runtime/internals/operations/indexQuery.mjs +39 -11
- package/dist/esm/runtime/internals/operations/indexQuery.mjs.map +1 -1
- package/dist/esm/runtime/internals/operations/list.mjs +50 -6
- package/dist/esm/runtime/internals/operations/list.mjs.map +1 -1
- package/dist/esm/runtime/internals/operations/utils.d.ts +8 -0
- package/dist/esm/runtime/internals/operations/utils.mjs +38 -0
- package/dist/esm/runtime/internals/operations/utils.mjs.map +1 -0
- package/dist/meta/cjs.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/runtime/internals/operations/custom.ts +44 -5
- package/src/runtime/internals/operations/get.ts +47 -7
- package/src/runtime/internals/operations/indexQuery.ts +43 -11
- package/src/runtime/internals/operations/list.ts +63 -7
- package/src/runtime/internals/operations/utils.ts +35 -0
package/package.json
CHANGED
|
@@ -27,6 +27,8 @@ import {
|
|
|
27
27
|
selectionSetIRToString,
|
|
28
28
|
} from '../APIClient';
|
|
29
29
|
|
|
30
|
+
import { handleSingularGraphQlError } from './utils';
|
|
31
|
+
|
|
30
32
|
type CustomOperationOptions = AuthModeParams & ListArgs;
|
|
31
33
|
|
|
32
34
|
// these are the 4 possible sets of arguments custom operations methods can receive
|
|
@@ -417,12 +419,49 @@ async function _op(
|
|
|
417
419
|
return { data: null, extensions };
|
|
418
420
|
}
|
|
419
421
|
} catch (error: any) {
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
422
|
+
/**
|
|
423
|
+
* The `data` type returned by `error` here could be:
|
|
424
|
+
* 1) `null`
|
|
425
|
+
* 2) an empty object
|
|
426
|
+
* 3) "populated" but with a `null` value `{ getPost: null }`
|
|
427
|
+
* 4) an actual record `{ getPost: { id: '1', title: 'Hello, World!' } }`
|
|
428
|
+
*/
|
|
429
|
+
const { data, errors } = error;
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* `data` is not `null`, and is not an empty object:
|
|
433
|
+
*/
|
|
434
|
+
if (data && Object.keys(data).length !== 0 && errors) {
|
|
435
|
+
const [key] = Object.keys(data);
|
|
436
|
+
const flattenedResult = flattenItems(data)[key];
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* `flattenedResult` could be `null` here (e.g. `data: { getPost: null }`)
|
|
440
|
+
* if `flattenedResult`, result is an actual record:
|
|
441
|
+
*/
|
|
442
|
+
if (flattenedResult) {
|
|
443
|
+
// TODO: custom selection set. current selection set is default selection set only
|
|
444
|
+
// custom selection set requires data-schema-type + runtime updates above.
|
|
445
|
+
const [initialized] = returnTypeModelName
|
|
446
|
+
? initializeModel(
|
|
447
|
+
client,
|
|
448
|
+
returnTypeModelName,
|
|
449
|
+
[flattenedResult],
|
|
450
|
+
modelIntrospection,
|
|
451
|
+
auth.authMode,
|
|
452
|
+
auth.authToken,
|
|
453
|
+
!!context,
|
|
454
|
+
)
|
|
455
|
+
: [flattenedResult];
|
|
456
|
+
|
|
457
|
+
return { data: initialized, errors };
|
|
458
|
+
} else {
|
|
459
|
+
// was `data: { getPost: null }`)
|
|
460
|
+
return handleSingularGraphQlError(error);
|
|
461
|
+
}
|
|
423
462
|
} else {
|
|
424
|
-
//
|
|
425
|
-
|
|
463
|
+
// `data` is `null`:
|
|
464
|
+
return handleSingularGraphQlError(error);
|
|
426
465
|
}
|
|
427
466
|
}
|
|
428
467
|
}
|
|
@@ -25,6 +25,8 @@ import {
|
|
|
25
25
|
initializeModel,
|
|
26
26
|
} from '../APIClient';
|
|
27
27
|
|
|
28
|
+
import { handleSingularGraphQlError } from './utils';
|
|
29
|
+
|
|
28
30
|
export function getFactory(
|
|
29
31
|
client: BaseClient,
|
|
30
32
|
modelIntrospection: ModelIntrospectionSchema,
|
|
@@ -90,9 +92,9 @@ async function _get(
|
|
|
90
92
|
modelIntrospection,
|
|
91
93
|
);
|
|
92
94
|
|
|
93
|
-
|
|
94
|
-
const auth = authModeParams(client, getInternals, options);
|
|
95
|
+
const auth = authModeParams(client, getInternals, options);
|
|
95
96
|
|
|
97
|
+
try {
|
|
96
98
|
const headers = getCustomHeaders(client, getInternals, options?.headers);
|
|
97
99
|
|
|
98
100
|
const { data, extensions } = context
|
|
@@ -139,12 +141,50 @@ async function _get(
|
|
|
139
141
|
return { data: null, extensions };
|
|
140
142
|
}
|
|
141
143
|
} catch (error: any) {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
144
|
+
/**
|
|
145
|
+
* The `data` type returned by `error` here could be:
|
|
146
|
+
* 1) `null`
|
|
147
|
+
* 2) an empty object
|
|
148
|
+
* 3) "populated" but with a `null` value `{ getPost: null }`
|
|
149
|
+
* 4) an actual record `{ getPost: { id: '1', title: 'Hello, World!' } }`
|
|
150
|
+
*/
|
|
151
|
+
const { data, errors } = error;
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* `data` is not `null`, and is not an empty object:
|
|
155
|
+
*/
|
|
156
|
+
if (data && Object.keys(data).length !== 0 && errors) {
|
|
157
|
+
const [key] = Object.keys(data);
|
|
158
|
+
const flattenedResult = flattenItems(data)[key];
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* `flattenedResult` could be `null` here (e.g. `data: { getPost: null }`)
|
|
162
|
+
* if `flattenedResult`, result is an actual record:
|
|
163
|
+
*/
|
|
164
|
+
if (flattenedResult) {
|
|
165
|
+
if (options?.selectionSet) {
|
|
166
|
+
return { data: flattenedResult, errors };
|
|
167
|
+
} else {
|
|
168
|
+
// TODO: refactor to avoid destructuring here
|
|
169
|
+
const [initialized] = initializeModel(
|
|
170
|
+
client,
|
|
171
|
+
name,
|
|
172
|
+
[flattenedResult],
|
|
173
|
+
modelIntrospection,
|
|
174
|
+
auth.authMode,
|
|
175
|
+
auth.authToken,
|
|
176
|
+
!!context,
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
return { data: initialized, errors };
|
|
180
|
+
}
|
|
181
|
+
} else {
|
|
182
|
+
// was `data: { getPost: null }`)
|
|
183
|
+
return handleSingularGraphQlError(error);
|
|
184
|
+
}
|
|
145
185
|
} else {
|
|
146
|
-
//
|
|
147
|
-
|
|
186
|
+
// `data` is `null`:
|
|
187
|
+
return handleSingularGraphQlError(error);
|
|
148
188
|
}
|
|
149
189
|
}
|
|
150
190
|
}
|
|
@@ -21,6 +21,8 @@ import {
|
|
|
21
21
|
initializeModel,
|
|
22
22
|
} from '../APIClient';
|
|
23
23
|
|
|
24
|
+
import { handleListGraphQlError } from './utils';
|
|
25
|
+
|
|
24
26
|
export interface IndexMeta {
|
|
25
27
|
queryField: string;
|
|
26
28
|
pk: string;
|
|
@@ -97,16 +99,6 @@ function processGraphQlResponse(
|
|
|
97
99
|
};
|
|
98
100
|
}
|
|
99
101
|
|
|
100
|
-
function handleGraphQlError(error: any) {
|
|
101
|
-
if (error.errors) {
|
|
102
|
-
// graphql errors pass through
|
|
103
|
-
return error as any;
|
|
104
|
-
} else {
|
|
105
|
-
// non-graphql errors re re-thrown
|
|
106
|
-
throw error;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
102
|
async function _indexQuery(
|
|
111
103
|
client: BaseClient,
|
|
112
104
|
modelIntrospection: ModelIntrospectionSchema,
|
|
@@ -173,6 +165,46 @@ async function _indexQuery(
|
|
|
173
165
|
);
|
|
174
166
|
}
|
|
175
167
|
} catch (error: any) {
|
|
176
|
-
|
|
168
|
+
/**
|
|
169
|
+
* The `data` type returned by `error` here could be:
|
|
170
|
+
* 1) `null`
|
|
171
|
+
* 2) an empty object
|
|
172
|
+
* 3) "populated" but with a `null` value:
|
|
173
|
+
* `data: { listByExampleId: null }`
|
|
174
|
+
* 4) an actual record:
|
|
175
|
+
* `data: { listByExampleId: items: [{ id: '1', ...etc } }]`
|
|
176
|
+
*/
|
|
177
|
+
const { data, errors } = error;
|
|
178
|
+
|
|
179
|
+
// `data` is not `null`, and is not an empty object:
|
|
180
|
+
if (data !== undefined && Object.keys(data).length !== 0 && errors) {
|
|
181
|
+
const [key] = Object.keys(data);
|
|
182
|
+
|
|
183
|
+
if (data[key]?.items) {
|
|
184
|
+
const flattenedResult = flattenItems(data)[key];
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Check exists since `flattenedResult` could be `null`.
|
|
188
|
+
* if `flattenedResult` exists, result is an actual record.
|
|
189
|
+
*/
|
|
190
|
+
if (flattenedResult) {
|
|
191
|
+
return {
|
|
192
|
+
data: args?.selectionSet
|
|
193
|
+
? flattenedResult
|
|
194
|
+
: modelInitializer(flattenedResult),
|
|
195
|
+
nextToken: data[key]?.nextToken,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// response is of type `data: { listByExampleId: null }`
|
|
201
|
+
return {
|
|
202
|
+
data: data[key],
|
|
203
|
+
nextToken: data[key]?.nextToken,
|
|
204
|
+
};
|
|
205
|
+
} else {
|
|
206
|
+
// `data` is `null` or an empty object:
|
|
207
|
+
return handleListGraphQlError(error);
|
|
208
|
+
}
|
|
177
209
|
}
|
|
178
210
|
}
|
|
@@ -22,6 +22,8 @@ import {
|
|
|
22
22
|
initializeModel,
|
|
23
23
|
} from '../APIClient';
|
|
24
24
|
|
|
25
|
+
import { handleListGraphQlError } from './utils';
|
|
26
|
+
|
|
25
27
|
export function listFactory(
|
|
26
28
|
client: BaseClient,
|
|
27
29
|
modelIntrospection: ModelIntrospectionSchema,
|
|
@@ -68,9 +70,9 @@ async function _list(
|
|
|
68
70
|
modelIntrospection,
|
|
69
71
|
);
|
|
70
72
|
|
|
71
|
-
|
|
72
|
-
const auth = authModeParams(client, getInternals, args);
|
|
73
|
+
const auth = authModeParams(client, getInternals, args);
|
|
73
74
|
|
|
75
|
+
try {
|
|
74
76
|
const headers = getCustomHeaders(client, getInternals, args?.headers);
|
|
75
77
|
|
|
76
78
|
const { data, extensions } = contextSpec
|
|
@@ -132,12 +134,66 @@ async function _list(
|
|
|
132
134
|
};
|
|
133
135
|
}
|
|
134
136
|
} catch (error: any) {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
137
|
+
/**
|
|
138
|
+
* The `data` type returned by `error` here could be:
|
|
139
|
+
* 1) `null`
|
|
140
|
+
* 2) an empty object
|
|
141
|
+
* 3) "populated" but with a `null` value `data: { listPosts: null }`
|
|
142
|
+
* 4) actual records `data: { listPosts: items: [{ id: '1', ...etc }] }`
|
|
143
|
+
*/
|
|
144
|
+
const { data, errors } = error;
|
|
145
|
+
|
|
146
|
+
// `data` is not `null`, and is not an empty object:
|
|
147
|
+
if (data !== undefined && Object.keys(data).length !== 0 && errors) {
|
|
148
|
+
const [key] = Object.keys(data);
|
|
149
|
+
|
|
150
|
+
if (data[key]?.items) {
|
|
151
|
+
const flattenedResult = flattenItems(data)[key];
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Check exists since `flattenedResult` could be `null`.
|
|
155
|
+
* if `flattenedResult` exists, result is an actual record.
|
|
156
|
+
*/
|
|
157
|
+
if (flattenedResult) {
|
|
158
|
+
// don't init if custom selection set
|
|
159
|
+
if (args?.selectionSet) {
|
|
160
|
+
return {
|
|
161
|
+
data: flattenedResult,
|
|
162
|
+
nextToken: data[key]?.nextToken,
|
|
163
|
+
errors,
|
|
164
|
+
};
|
|
165
|
+
} else {
|
|
166
|
+
const initialized = initializeModel(
|
|
167
|
+
client,
|
|
168
|
+
name,
|
|
169
|
+
flattenedResult,
|
|
170
|
+
modelIntrospection,
|
|
171
|
+
auth.authMode,
|
|
172
|
+
auth.authToken,
|
|
173
|
+
!!contextSpec,
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
// data is full record w/out selection set:
|
|
177
|
+
return {
|
|
178
|
+
data: initialized,
|
|
179
|
+
nextToken: data[key]?.nextToken,
|
|
180
|
+
errors,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return {
|
|
186
|
+
data: data[key],
|
|
187
|
+
nextToken: data[key]?.nextToken,
|
|
188
|
+
errors,
|
|
189
|
+
};
|
|
190
|
+
} else {
|
|
191
|
+
// response is of type `data: { getPost: null }`)
|
|
192
|
+
return handleListGraphQlError(error);
|
|
193
|
+
}
|
|
138
194
|
} else {
|
|
139
|
-
//
|
|
140
|
-
|
|
195
|
+
// `data` is `null` or an empty object:
|
|
196
|
+
return handleListGraphQlError(error);
|
|
141
197
|
}
|
|
142
198
|
}
|
|
143
199
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// import { GraphQLFormattedError } from '@aws-amplify/data-schema-types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Handle errors for list return types (list and index query operations)
|
|
7
|
+
*/
|
|
8
|
+
export function handleListGraphQlError(error: any) {
|
|
9
|
+
if (error?.errors) {
|
|
10
|
+
// graphql errors pass through
|
|
11
|
+
return {
|
|
12
|
+
...error,
|
|
13
|
+
data: [],
|
|
14
|
+
} as any;
|
|
15
|
+
} else {
|
|
16
|
+
// non-graphql errors are re-thrown
|
|
17
|
+
throw error;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Handle errors for singular return types (create, get, update, delete operations)
|
|
23
|
+
*/
|
|
24
|
+
export function handleSingularGraphQlError(error: any) {
|
|
25
|
+
if (error.errors) {
|
|
26
|
+
// graphql errors pass through
|
|
27
|
+
return {
|
|
28
|
+
...error,
|
|
29
|
+
data: null,
|
|
30
|
+
} as any;
|
|
31
|
+
} else {
|
|
32
|
+
// non-graphql errors are re-thrown
|
|
33
|
+
throw error;
|
|
34
|
+
}
|
|
35
|
+
}
|