@aws-amplify/api-graphql 4.0.2-unstable.51ed7b4.0 → 4.0.2-unstable.a5eb335.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/GraphQLAPI.js +1 -1
- package/dist/cjs/GraphQLAPI.js.map +1 -1
- package/dist/cjs/Providers/AWSAppSyncRealTimeProvider/index.js +1 -1
- package/dist/cjs/Providers/AWSAppSyncRealTimeProvider/index.js.map +1 -1
- package/dist/cjs/internals/APIClient.js +70 -45
- package/dist/cjs/internals/APIClient.js.map +1 -1
- package/dist/cjs/internals/InternalGraphQLAPI.js +13 -22
- package/dist/cjs/internals/InternalGraphQLAPI.js.map +1 -1
- package/dist/cjs/internals/generateModelsProperty.js +1 -1
- package/dist/cjs/internals/generateModelsProperty.js.map +1 -1
- package/dist/cjs/internals/operations/get.js +5 -5
- package/dist/cjs/internals/operations/get.js.map +1 -1
- package/dist/cjs/internals/operations/list.js +5 -5
- package/dist/cjs/internals/operations/list.js.map +1 -1
- package/dist/cjs/internals/operations/observeQuery.js +2 -2
- package/dist/cjs/internals/operations/observeQuery.js.map +1 -1
- package/dist/cjs/internals/operations/subscription.js +2 -1
- package/dist/cjs/internals/operations/subscription.js.map +1 -1
- package/dist/cjs/internals/server/generateModelsProperty.js +4 -4
- package/dist/cjs/internals/server/generateModelsProperty.js.map +1 -1
- package/dist/esm/GraphQLAPI.mjs +1 -1
- package/dist/esm/GraphQLAPI.mjs.map +1 -1
- package/dist/esm/Providers/AWSAppSyncRealTimeProvider/index.mjs +1 -1
- package/dist/esm/Providers/AWSAppSyncRealTimeProvider/index.mjs.map +1 -1
- package/dist/esm/internals/APIClient.d.ts +10 -19
- package/dist/esm/internals/APIClient.mjs +70 -45
- package/dist/esm/internals/APIClient.mjs.map +1 -1
- package/dist/esm/internals/InternalGraphQLAPI.d.ts +0 -11
- package/dist/esm/internals/InternalGraphQLAPI.mjs +13 -21
- package/dist/esm/internals/InternalGraphQLAPI.mjs.map +1 -1
- package/dist/esm/internals/generateModelsProperty.d.ts +1 -1
- package/dist/esm/internals/generateModelsProperty.mjs +1 -1
- package/dist/esm/internals/generateModelsProperty.mjs.map +1 -1
- package/dist/esm/internals/operations/get.d.ts +4 -1
- package/dist/esm/internals/operations/get.mjs +5 -5
- package/dist/esm/internals/operations/get.mjs.map +1 -1
- package/dist/esm/internals/operations/list.d.ts +3 -1
- package/dist/esm/internals/operations/list.mjs +5 -5
- package/dist/esm/internals/operations/list.mjs.map +1 -1
- package/dist/esm/internals/operations/observeQuery.d.ts +2 -1
- package/dist/esm/internals/operations/subscription.d.ts +3 -1
- package/dist/esm/internals/operations/subscription.mjs +2 -1
- package/dist/esm/internals/operations/subscription.mjs.map +1 -1
- package/dist/esm/internals/server/generateModelsProperty.d.ts +1 -1
- package/dist/esm/internals/server/generateModelsProperty.mjs +4 -4
- package/dist/esm/internals/server/generateModelsProperty.mjs.map +1 -1
- package/dist/esm/types/index.d.ts +10 -0
- package/package.json +8 -12
- package/src/GraphQLAPI.ts +2 -2
- package/src/Providers/AWSAppSyncRealTimeProvider/index.ts +9 -4
- package/src/internals/APIClient.ts +160 -104
- package/src/internals/InternalGraphQLAPI.ts +20 -30
- package/src/internals/generateModelsProperty.ts +8 -5
- package/src/internals/operations/get.ts +44 -34
- package/src/internals/operations/list.ts +38 -17
- package/src/internals/operations/observeQuery.ts +14 -10
- package/src/internals/operations/subscription.ts +13 -7
- package/src/internals/server/generateClient.ts +1 -1
- package/src/internals/server/generateModelsProperty.ts +18 -8
- package/src/types/index.ts +14 -0
- package/src/utils/ConnectionStateMonitor.ts +3 -1
- package/src/utils/findIndexByFields.ts +3 -1
|
@@ -1,12 +1,27 @@
|
|
|
1
1
|
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
import { resolveOwnerFields } from '../utils/resolveOwnerFields';
|
|
4
|
-
import {
|
|
5
|
-
|
|
4
|
+
import {
|
|
5
|
+
GraphQLAuthMode,
|
|
6
|
+
ModelIntrospectionSchema,
|
|
7
|
+
ModelFieldType,
|
|
8
|
+
SchemaModel,
|
|
9
|
+
SchemaModels,
|
|
10
|
+
AssociationHasOne,
|
|
11
|
+
AssociationBelongsTo,
|
|
12
|
+
} from '@aws-amplify/core/internals/utils';
|
|
13
|
+
import {
|
|
14
|
+
AuthModeParams,
|
|
15
|
+
ClientWithModels,
|
|
16
|
+
ListArgs,
|
|
17
|
+
QueryArgs,
|
|
18
|
+
V6Client,
|
|
19
|
+
V6ClientSSRRequest,
|
|
20
|
+
__authMode,
|
|
21
|
+
__authToken,
|
|
22
|
+
} from '../types';
|
|
6
23
|
import { AmplifyServer } from '@aws-amplify/core/internals/adapter-core';
|
|
7
24
|
|
|
8
|
-
type ListArgs = { selectionSet?: string[]; filter?: {} };
|
|
9
|
-
|
|
10
25
|
type LazyLoadOptions = {
|
|
11
26
|
authMode?: GraphQLAuthMode;
|
|
12
27
|
authToken?: string | undefined;
|
|
@@ -48,10 +63,10 @@ export const flattenItems = (obj: Record<string, any>): Record<string, any> => {
|
|
|
48
63
|
|
|
49
64
|
// TODO: this should accept single result to support CRUD methods; create helper for array/list
|
|
50
65
|
export function initializeModel(
|
|
51
|
-
client:
|
|
66
|
+
client: ClientWithModels,
|
|
52
67
|
modelName: string,
|
|
53
68
|
result: any[],
|
|
54
|
-
modelIntrospection:
|
|
69
|
+
modelIntrospection: ModelIntrospectionSchema,
|
|
55
70
|
authMode: GraphQLAuthMode | undefined,
|
|
56
71
|
authToken: string | undefined,
|
|
57
72
|
context = false
|
|
@@ -64,12 +79,14 @@ export function initializeModel(
|
|
|
64
79
|
.map(([fieldName]) => fieldName);
|
|
65
80
|
|
|
66
81
|
return result.map(record => {
|
|
67
|
-
const initializedRelationalFields = {};
|
|
82
|
+
const initializedRelationalFields: Record<string, any> = {};
|
|
68
83
|
|
|
69
|
-
for (const
|
|
70
|
-
const
|
|
84
|
+
for (const fieldName of modelFields) {
|
|
85
|
+
const modelField = introModelFields[fieldName];
|
|
86
|
+
const modelFieldType = modelField?.type as ModelFieldType;
|
|
71
87
|
|
|
72
|
-
const
|
|
88
|
+
const relatedModelName = modelFieldType.model;
|
|
89
|
+
const relatedModel = modelIntrospection.models[relatedModelName!];
|
|
73
90
|
|
|
74
91
|
const relatedModelPKFieldName =
|
|
75
92
|
relatedModel.primaryKeyInfo.primaryKeyFieldName;
|
|
@@ -77,18 +94,26 @@ export function initializeModel(
|
|
|
77
94
|
const relatedModelSKFieldNames =
|
|
78
95
|
relatedModel.primaryKeyInfo.sortKeyFieldNames;
|
|
79
96
|
|
|
80
|
-
const relationType =
|
|
81
|
-
const connectionFields =
|
|
82
|
-
introModelFields[field].association.associatedWith;
|
|
97
|
+
const relationType = modelField.association?.connectionType;
|
|
83
98
|
|
|
84
|
-
|
|
85
|
-
|
|
99
|
+
let connectionFields: string[] = [];
|
|
100
|
+
if (
|
|
101
|
+
modelField.association &&
|
|
102
|
+
'associatedWith' in modelField.association
|
|
103
|
+
) {
|
|
104
|
+
connectionFields = modelField.association.associatedWith;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
let targetNames: string[] = [];
|
|
108
|
+
if (modelField.association && 'targetNames' in modelField.association) {
|
|
109
|
+
targetNames = modelField.association.targetNames;
|
|
110
|
+
}
|
|
86
111
|
|
|
87
112
|
switch (relationType) {
|
|
88
113
|
case connectionType.HAS_ONE:
|
|
89
114
|
case connectionType.BELONGS_TO:
|
|
90
115
|
const sortKeyValues = relatedModelSKFieldNames.reduce(
|
|
91
|
-
(acc, curVal) => {
|
|
116
|
+
(acc: Record<string, any>, curVal) => {
|
|
92
117
|
if (record[curVal]) {
|
|
93
118
|
return (acc[curVal] = record[curVal]);
|
|
94
119
|
}
|
|
@@ -97,12 +122,14 @@ export function initializeModel(
|
|
|
97
122
|
);
|
|
98
123
|
|
|
99
124
|
if (context) {
|
|
100
|
-
initializedRelationalFields[
|
|
125
|
+
initializedRelationalFields[fieldName] = (
|
|
101
126
|
contextSpec: AmplifyServer.ContextSpec,
|
|
102
127
|
options?: LazyLoadOptions
|
|
103
128
|
) => {
|
|
104
129
|
if (record[targetNames[0]]) {
|
|
105
|
-
return
|
|
130
|
+
return (
|
|
131
|
+
client as V6ClientSSRRequest<Record<string, any>>
|
|
132
|
+
).models[relatedModelName].get(
|
|
106
133
|
contextSpec,
|
|
107
134
|
{
|
|
108
135
|
[relatedModelPKFieldName]: record[targetNames[0]],
|
|
@@ -117,11 +144,13 @@ export function initializeModel(
|
|
|
117
144
|
return undefined;
|
|
118
145
|
};
|
|
119
146
|
} else {
|
|
120
|
-
initializedRelationalFields[
|
|
147
|
+
initializedRelationalFields[fieldName] = (
|
|
121
148
|
options?: LazyLoadOptions
|
|
122
149
|
) => {
|
|
123
150
|
if (record[targetNames[0]]) {
|
|
124
|
-
return client.models[
|
|
151
|
+
return (client as V6Client<Record<string, any>>).models[
|
|
152
|
+
relatedModelName
|
|
153
|
+
].get(
|
|
125
154
|
{
|
|
126
155
|
[relatedModelPKFieldName]: record[targetNames[0]],
|
|
127
156
|
...sortKeyValues,
|
|
@@ -142,25 +171,37 @@ export function initializeModel(
|
|
|
142
171
|
const parentSK = introModel.primaryKeyInfo.sortKeyFieldNames;
|
|
143
172
|
|
|
144
173
|
// M:N check - TODO: refactor
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
174
|
+
const relatedModelField = relatedModel.fields[connectionFields[0]];
|
|
175
|
+
const relatedModelFieldType =
|
|
176
|
+
relatedModelField.type as ModelFieldType;
|
|
177
|
+
if (relatedModelFieldType.model) {
|
|
178
|
+
let relatedTargetNames: string[] = [];
|
|
179
|
+
if (
|
|
180
|
+
relatedModelField.association &&
|
|
181
|
+
'targetNames' in relatedModelField.association
|
|
182
|
+
) {
|
|
183
|
+
relatedTargetNames = relatedModelField.association?.targetNames;
|
|
184
|
+
}
|
|
148
185
|
|
|
149
|
-
const hasManyFilter = relatedTargetNames.map(
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
186
|
+
const hasManyFilter: Record<string, any> = relatedTargetNames.map(
|
|
187
|
+
(field, idx) => {
|
|
188
|
+
if (idx === 0) {
|
|
189
|
+
return { [field]: { eq: record[parentPk] } };
|
|
190
|
+
}
|
|
153
191
|
|
|
154
|
-
|
|
155
|
-
|
|
192
|
+
return { [field]: { eq: record[parentSK[idx - 1]] } };
|
|
193
|
+
}
|
|
194
|
+
);
|
|
156
195
|
|
|
157
196
|
if (context) {
|
|
158
|
-
initializedRelationalFields[
|
|
197
|
+
initializedRelationalFields[fieldName] = (
|
|
159
198
|
contextSpec: AmplifyServer.ContextSpec,
|
|
160
199
|
options?: LazyLoadOptions
|
|
161
200
|
) => {
|
|
162
201
|
if (record[parentPk]) {
|
|
163
|
-
return
|
|
202
|
+
return (
|
|
203
|
+
client as V6ClientSSRRequest<Record<string, any>>
|
|
204
|
+
).models[relatedModelName].list(contextSpec, {
|
|
164
205
|
filter: { and: hasManyFilter },
|
|
165
206
|
limit: options?.limit,
|
|
166
207
|
nextToken: options?.nextToken,
|
|
@@ -171,11 +212,13 @@ export function initializeModel(
|
|
|
171
212
|
return [];
|
|
172
213
|
};
|
|
173
214
|
} else {
|
|
174
|
-
initializedRelationalFields[
|
|
215
|
+
initializedRelationalFields[fieldName] = (
|
|
175
216
|
options?: LazyLoadOptions
|
|
176
217
|
) => {
|
|
177
218
|
if (record[parentPk]) {
|
|
178
|
-
return client.models[
|
|
219
|
+
return (client as V6Client<Record<string, any>>).models[
|
|
220
|
+
relatedModelName
|
|
221
|
+
].list({
|
|
179
222
|
filter: { and: hasManyFilter },
|
|
180
223
|
limit: options?.limit,
|
|
181
224
|
nextToken: options?.nextToken,
|
|
@@ -190,21 +233,25 @@ export function initializeModel(
|
|
|
190
233
|
break;
|
|
191
234
|
}
|
|
192
235
|
|
|
193
|
-
const hasManyFilter = connectionFields.map(
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
236
|
+
const hasManyFilter: Record<string, any> = connectionFields.map(
|
|
237
|
+
(field, idx) => {
|
|
238
|
+
if (idx === 0) {
|
|
239
|
+
return { [field]: { eq: record[parentPk] } };
|
|
240
|
+
}
|
|
197
241
|
|
|
198
|
-
|
|
199
|
-
|
|
242
|
+
return { [field]: { eq: record[parentSK[idx - 1]] } };
|
|
243
|
+
}
|
|
244
|
+
);
|
|
200
245
|
|
|
201
246
|
if (context) {
|
|
202
|
-
initializedRelationalFields[
|
|
247
|
+
initializedRelationalFields[fieldName] = (
|
|
203
248
|
contextSpec: AmplifyServer.ContextSpec,
|
|
204
249
|
options?: LazyLoadOptions
|
|
205
250
|
) => {
|
|
206
251
|
if (record[parentPk]) {
|
|
207
|
-
return
|
|
252
|
+
return (
|
|
253
|
+
client as V6ClientSSRRequest<Record<string, any>>
|
|
254
|
+
).models[relatedModelName].list(contextSpec, {
|
|
208
255
|
filter: { and: hasManyFilter },
|
|
209
256
|
limit: options?.limit,
|
|
210
257
|
nextToken: options?.nextToken,
|
|
@@ -215,11 +262,13 @@ export function initializeModel(
|
|
|
215
262
|
return [];
|
|
216
263
|
};
|
|
217
264
|
} else {
|
|
218
|
-
initializedRelationalFields[
|
|
265
|
+
initializedRelationalFields[fieldName] = (
|
|
219
266
|
options?: LazyLoadOptions
|
|
220
267
|
) => {
|
|
221
268
|
if (record[parentPk]) {
|
|
222
|
-
return client.models[
|
|
269
|
+
return (client as V6Client<Record<string, any>>).models[
|
|
270
|
+
relatedModelName
|
|
271
|
+
].list({
|
|
223
272
|
filter: { and: hasManyFilter },
|
|
224
273
|
limit: options?.limit,
|
|
225
274
|
nextToken: options?.nextToken,
|
|
@@ -260,7 +309,7 @@ type OperationPrefix =
|
|
|
260
309
|
const graphQLDocumentsCache = new Map<string, Map<ModelOperation, string>>();
|
|
261
310
|
const SELECTION_SET_WILDCARD = '*';
|
|
262
311
|
|
|
263
|
-
function defaultSelectionSetForModel(modelDefinition:
|
|
312
|
+
function defaultSelectionSetForModel(modelDefinition: SchemaModel): string[] {
|
|
264
313
|
// fields that are explicitly part of the graphql schema; not
|
|
265
314
|
// inferred from owner auth rules.
|
|
266
315
|
const { fields } = modelDefinition;
|
|
@@ -280,7 +329,7 @@ const FIELD_IR = '';
|
|
|
280
329
|
/**
|
|
281
330
|
* Generates nested Custom Selection Set IR from path
|
|
282
331
|
*
|
|
283
|
-
* @param
|
|
332
|
+
* @param modelDefinitions
|
|
284
333
|
* @param modelName
|
|
285
334
|
* @param selectionSet - array of object paths
|
|
286
335
|
* @example
|
|
@@ -297,31 +346,32 @@ const FIELD_IR = '';
|
|
|
297
346
|
* ```
|
|
298
347
|
*/
|
|
299
348
|
export function customSelectionSetToIR(
|
|
300
|
-
|
|
349
|
+
modelDefinitions: SchemaModels,
|
|
301
350
|
modelName: string,
|
|
302
351
|
selectionSet: string[]
|
|
303
352
|
): Record<string, string | object> {
|
|
304
|
-
const modelDefinition =
|
|
353
|
+
const modelDefinition = modelDefinitions[modelName];
|
|
305
354
|
const { fields: modelFields } = modelDefinition;
|
|
306
355
|
|
|
307
|
-
return selectionSet.reduce((resultObj, path) => {
|
|
356
|
+
return selectionSet.reduce((resultObj: Record<string, any>, path) => {
|
|
308
357
|
const [fieldName, nested, ...rest] = path.split('.');
|
|
309
358
|
|
|
310
359
|
if (nested) {
|
|
311
|
-
const
|
|
360
|
+
const fieldType = modelFields[fieldName]?.type as ModelFieldType;
|
|
361
|
+
const relatedModel = fieldType.model;
|
|
312
362
|
|
|
313
363
|
if (!relatedModel) {
|
|
314
364
|
// TODO: may need to change this to support custom types
|
|
315
365
|
throw Error(`${fieldName} is not a model field`);
|
|
316
366
|
}
|
|
317
367
|
|
|
318
|
-
const relatedModelDefinition =
|
|
368
|
+
const relatedModelDefinition = modelDefinitions[relatedModel];
|
|
319
369
|
|
|
320
370
|
const selectionSet =
|
|
321
371
|
nested === SELECTION_SET_WILDCARD
|
|
322
372
|
? defaultSelectionSetIR(relatedModelDefinition)
|
|
323
373
|
: // if we have a path like 'field.anotherField' recursively build up selection set IR
|
|
324
|
-
customSelectionSetToIR(
|
|
374
|
+
customSelectionSetToIR(modelDefinitions, relatedModel, [
|
|
325
375
|
[nested, ...rest].join('.'),
|
|
326
376
|
]);
|
|
327
377
|
|
|
@@ -353,15 +403,18 @@ export function customSelectionSetToIR(
|
|
|
353
403
|
}, {});
|
|
354
404
|
}
|
|
355
405
|
|
|
356
|
-
const defaultSelectionSetIR = relatedModelDefinition => {
|
|
406
|
+
const defaultSelectionSetIR = (relatedModelDefinition: SchemaModel) => {
|
|
357
407
|
const defaultSelectionSet = defaultSelectionSetForModel(
|
|
358
408
|
relatedModelDefinition
|
|
359
409
|
);
|
|
360
410
|
|
|
361
|
-
const reduced = defaultSelectionSet.reduce(
|
|
362
|
-
acc
|
|
363
|
-
|
|
364
|
-
|
|
411
|
+
const reduced = defaultSelectionSet.reduce(
|
|
412
|
+
(acc: Record<string, any>, curVal) => {
|
|
413
|
+
acc[curVal] = FIELD_IR;
|
|
414
|
+
return acc;
|
|
415
|
+
},
|
|
416
|
+
{}
|
|
417
|
+
);
|
|
365
418
|
|
|
366
419
|
return reduced;
|
|
367
420
|
};
|
|
@@ -410,18 +463,18 @@ export function selectionSetIRToString(
|
|
|
410
463
|
}
|
|
411
464
|
|
|
412
465
|
export function generateSelectionSet(
|
|
413
|
-
|
|
466
|
+
modelDefinitions: SchemaModels,
|
|
414
467
|
modelName: string,
|
|
415
468
|
selectionSet?: string[]
|
|
416
469
|
) {
|
|
417
|
-
const modelDefinition =
|
|
470
|
+
const modelDefinition = modelDefinitions[modelName];
|
|
418
471
|
|
|
419
472
|
if (!selectionSet) {
|
|
420
473
|
return defaultSelectionSetForModel(modelDefinition).join(' ');
|
|
421
474
|
}
|
|
422
475
|
|
|
423
476
|
const selSetIr = customSelectionSetToIR(
|
|
424
|
-
|
|
477
|
+
modelDefinitions,
|
|
425
478
|
modelName,
|
|
426
479
|
selectionSet
|
|
427
480
|
);
|
|
@@ -431,12 +484,12 @@ export function generateSelectionSet(
|
|
|
431
484
|
}
|
|
432
485
|
|
|
433
486
|
export function generateGraphQLDocument(
|
|
434
|
-
|
|
487
|
+
modelDefinitions: SchemaModels,
|
|
435
488
|
modelName: string,
|
|
436
489
|
modelOperation: ModelOperation,
|
|
437
490
|
listArgs?: ListArgs
|
|
438
491
|
): string {
|
|
439
|
-
const modelDefinition =
|
|
492
|
+
const modelDefinition = modelDefinitions[modelName];
|
|
440
493
|
|
|
441
494
|
const {
|
|
442
495
|
name,
|
|
@@ -469,7 +522,7 @@ export function generateGraphQLDocument(
|
|
|
469
522
|
let graphQLArguments: Record<string, any> | undefined;
|
|
470
523
|
|
|
471
524
|
const selectionSetFields = generateSelectionSet(
|
|
472
|
-
|
|
525
|
+
modelDefinitions,
|
|
473
526
|
modelName,
|
|
474
527
|
selectionSet
|
|
475
528
|
);
|
|
@@ -490,7 +543,7 @@ export function generateGraphQLDocument(
|
|
|
490
543
|
graphQLArguments ??
|
|
491
544
|
(graphQLArguments = isCustomPrimaryKey
|
|
492
545
|
? [primaryKeyFieldName, ...sortKeyFieldNames].reduce(
|
|
493
|
-
(acc, fieldName) => {
|
|
546
|
+
(acc: Record<string, any>, fieldName) => {
|
|
494
547
|
acc[fieldName] = fields[fieldName].type;
|
|
495
548
|
|
|
496
549
|
return acc;
|
|
@@ -548,10 +601,10 @@ export function generateGraphQLDocument(
|
|
|
548
601
|
}
|
|
549
602
|
|
|
550
603
|
export function buildGraphQLVariables(
|
|
551
|
-
modelDefinition:
|
|
604
|
+
modelDefinition: SchemaModel,
|
|
552
605
|
operation: ModelOperation,
|
|
553
|
-
arg:
|
|
554
|
-
modelIntrospection
|
|
606
|
+
arg: QueryArgs | undefined,
|
|
607
|
+
modelIntrospection: ModelIntrospectionSchema
|
|
555
608
|
): object {
|
|
556
609
|
const {
|
|
557
610
|
fields,
|
|
@@ -568,36 +621,42 @@ export function buildGraphQLVariables(
|
|
|
568
621
|
switch (operation) {
|
|
569
622
|
case 'CREATE':
|
|
570
623
|
variables = {
|
|
571
|
-
input:
|
|
624
|
+
input: arg
|
|
625
|
+
? normalizeMutationInput(arg, modelDefinition, modelIntrospection)
|
|
626
|
+
: {},
|
|
572
627
|
};
|
|
573
628
|
break;
|
|
574
629
|
case 'UPDATE':
|
|
575
630
|
// readonly fields are not updated
|
|
576
631
|
variables = {
|
|
577
|
-
input:
|
|
578
|
-
Object.
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
632
|
+
input: arg
|
|
633
|
+
? Object.fromEntries(
|
|
634
|
+
Object.entries(
|
|
635
|
+
normalizeMutationInput(arg, modelDefinition, modelIntrospection)
|
|
636
|
+
).filter(([fieldName]) => {
|
|
637
|
+
const { isReadOnly } = fields[fieldName];
|
|
638
|
+
|
|
639
|
+
return !isReadOnly;
|
|
640
|
+
})
|
|
641
|
+
)
|
|
642
|
+
: {},
|
|
586
643
|
};
|
|
587
644
|
break;
|
|
588
645
|
case 'READ':
|
|
589
646
|
case 'DELETE':
|
|
590
647
|
// only identifiers are sent
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
acc
|
|
648
|
+
if (arg) {
|
|
649
|
+
variables = isCustomPrimaryKey
|
|
650
|
+
? [primaryKeyFieldName, ...sortKeyFieldNames].reduce(
|
|
651
|
+
(acc: Record<string, any>, fieldName) => {
|
|
652
|
+
acc[fieldName] = arg[fieldName];
|
|
595
653
|
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
654
|
+
return acc;
|
|
655
|
+
},
|
|
656
|
+
{}
|
|
657
|
+
)
|
|
658
|
+
: { [primaryKeyFieldName]: arg[primaryKeyFieldName] };
|
|
659
|
+
}
|
|
601
660
|
|
|
602
661
|
if (operation === 'DELETE') {
|
|
603
662
|
variables = { input: variables };
|
|
@@ -649,34 +708,36 @@ export function buildGraphQLVariables(
|
|
|
649
708
|
*
|
|
650
709
|
*/
|
|
651
710
|
export function normalizeMutationInput(
|
|
652
|
-
mutationInput:
|
|
653
|
-
model:
|
|
654
|
-
|
|
655
|
-
):
|
|
711
|
+
mutationInput: QueryArgs,
|
|
712
|
+
model: SchemaModel,
|
|
713
|
+
modelIntrospection: ModelIntrospectionSchema
|
|
714
|
+
): QueryArgs {
|
|
656
715
|
const { fields } = model;
|
|
657
716
|
|
|
658
|
-
const normalized = {};
|
|
717
|
+
const normalized: Record<string, unknown> = {};
|
|
659
718
|
|
|
660
719
|
Object.entries(mutationInput).forEach(([inputFieldName, inputValue]) => {
|
|
661
|
-
const
|
|
662
|
-
|
|
720
|
+
const fieldType = fields[inputFieldName]?.type as ModelFieldType;
|
|
721
|
+
const relatedModelName = fieldType?.model;
|
|
663
722
|
|
|
664
723
|
if (relatedModelName) {
|
|
665
724
|
const association = fields[inputFieldName]?.association;
|
|
666
|
-
const relatedModelDef =
|
|
725
|
+
const relatedModelDef = modelIntrospection.models[relatedModelName];
|
|
667
726
|
const relatedModelPkInfo = relatedModelDef.primaryKeyInfo;
|
|
668
727
|
|
|
669
|
-
if (association
|
|
670
|
-
association
|
|
671
|
-
|
|
728
|
+
if (association?.connectionType === connectionType.HAS_ONE) {
|
|
729
|
+
const associationHasOne = association as AssociationHasOne;
|
|
730
|
+
associationHasOne.targetNames.forEach((targetName, idx) => {
|
|
731
|
+
const associatedFieldName = associationHasOne.associatedWith[idx];
|
|
672
732
|
normalized[targetName] = (inputValue as Record<string, unknown>)[
|
|
673
733
|
associatedFieldName
|
|
674
734
|
];
|
|
675
735
|
});
|
|
676
736
|
}
|
|
677
737
|
|
|
678
|
-
if (association
|
|
679
|
-
association
|
|
738
|
+
if (association?.connectionType === connectionType.BELONGS_TO) {
|
|
739
|
+
const associationBelongsTo = association as AssociationBelongsTo;
|
|
740
|
+
associationBelongsTo.targetNames.forEach((targetName, idx) => {
|
|
680
741
|
if (idx === 0) {
|
|
681
742
|
const associatedFieldName = relatedModelPkInfo.primaryKeyFieldName;
|
|
682
743
|
normalized[targetName] = (inputValue as Record<string, unknown>)[
|
|
@@ -699,11 +760,6 @@ export function normalizeMutationInput(
|
|
|
699
760
|
return normalized;
|
|
700
761
|
}
|
|
701
762
|
|
|
702
|
-
type AuthModeParams = {
|
|
703
|
-
authMode?: GraphQLAuthMode;
|
|
704
|
-
authToken?: string;
|
|
705
|
-
};
|
|
706
|
-
|
|
707
763
|
/**
|
|
708
764
|
* Produces a parameter object that can contains auth mode/token overrides
|
|
709
765
|
* only if present in either `options` (first) or configured on the `client`
|
|
@@ -714,7 +770,7 @@ type AuthModeParams = {
|
|
|
714
770
|
* @returns
|
|
715
771
|
*/
|
|
716
772
|
export function authModeParams(
|
|
717
|
-
client:
|
|
773
|
+
client: ClientWithModels,
|
|
718
774
|
options: AuthModeParams = {}
|
|
719
775
|
): AuthModeParams {
|
|
720
776
|
return {
|
|
@@ -35,17 +35,11 @@ const USER_AGENT_HEADER = 'x-amz-user-agent';
|
|
|
35
35
|
|
|
36
36
|
const logger = new ConsoleLogger('GraphQLAPI');
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
) =>
|
|
43
|
-
query,
|
|
44
|
-
variables,
|
|
45
|
-
authToken,
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
const isAmplifyInstance = (amplify): amplify is AmplifyClassV6 => {
|
|
38
|
+
const isAmplifyInstance = (
|
|
39
|
+
amplify:
|
|
40
|
+
| AmplifyClassV6
|
|
41
|
+
| ((fn: (amplify: any) => Promise<any>) => Promise<AmplifyClassV6>)
|
|
42
|
+
): amplify is AmplifyClassV6 => {
|
|
49
43
|
return typeof amplify !== 'function';
|
|
50
44
|
};
|
|
51
45
|
|
|
@@ -56,8 +50,7 @@ export class InternalGraphQLAPIClass {
|
|
|
56
50
|
/**
|
|
57
51
|
* @private
|
|
58
52
|
*/
|
|
59
|
-
private
|
|
60
|
-
private appSyncRealTime: AWSAppSyncRealTimeProvider | null;
|
|
53
|
+
private appSyncRealTime = new AWSAppSyncRealTimeProvider();
|
|
61
54
|
|
|
62
55
|
private _api = {
|
|
63
56
|
post,
|
|
@@ -66,15 +59,6 @@ export class InternalGraphQLAPIClass {
|
|
|
66
59
|
updateRequestToBeCancellable,
|
|
67
60
|
};
|
|
68
61
|
|
|
69
|
-
/**
|
|
70
|
-
* Initialize GraphQL API with AWS configuration
|
|
71
|
-
* @param {Object} options - Configuration object for API
|
|
72
|
-
*/
|
|
73
|
-
constructor(options) {
|
|
74
|
-
this._options = options;
|
|
75
|
-
logger.debug('API Options', this._options);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
62
|
public getModuleName() {
|
|
79
63
|
return 'InternalGraphQLAPI';
|
|
80
64
|
}
|
|
@@ -208,7 +192,7 @@ export class InternalGraphQLAPIClass {
|
|
|
208
192
|
customUserAgentDetails
|
|
209
193
|
);
|
|
210
194
|
} else {
|
|
211
|
-
const wrapper = amplifyInstance =>
|
|
195
|
+
const wrapper = (amplifyInstance: AmplifyClassV6) =>
|
|
212
196
|
this._graphql<T>(
|
|
213
197
|
amplifyInstance,
|
|
214
198
|
{ query, variables, authMode },
|
|
@@ -307,7 +291,7 @@ export class InternalGraphQLAPIClass {
|
|
|
307
291
|
authMode !== 'iam' &&
|
|
308
292
|
authMode !== 'lambda')
|
|
309
293
|
) {
|
|
310
|
-
signingServiceInfo =
|
|
294
|
+
signingServiceInfo = undefined;
|
|
311
295
|
} else {
|
|
312
296
|
signingServiceInfo = {
|
|
313
297
|
service: !customEndpointRegion ? 'appsync' : 'execute-api',
|
|
@@ -326,7 +310,7 @@ export class InternalGraphQLAPIClass {
|
|
|
326
310
|
};
|
|
327
311
|
}
|
|
328
312
|
|
|
329
|
-
let response;
|
|
313
|
+
let response: any;
|
|
330
314
|
try {
|
|
331
315
|
const { body: responseBody } = await this._api.post({
|
|
332
316
|
url: new AmplifyUrl(endpoint),
|
|
@@ -352,7 +336,16 @@ export class InternalGraphQLAPIClass {
|
|
|
352
336
|
|
|
353
337
|
response = {
|
|
354
338
|
data: {},
|
|
355
|
-
errors: [
|
|
339
|
+
errors: [
|
|
340
|
+
new GraphQLError(
|
|
341
|
+
(err as any).message,
|
|
342
|
+
null,
|
|
343
|
+
null,
|
|
344
|
+
null,
|
|
345
|
+
null,
|
|
346
|
+
err as any
|
|
347
|
+
),
|
|
348
|
+
],
|
|
356
349
|
};
|
|
357
350
|
}
|
|
358
351
|
|
|
@@ -391,9 +384,6 @@ export class InternalGraphQLAPIClass {
|
|
|
391
384
|
): Observable<any> {
|
|
392
385
|
const config = resolveConfig(amplify);
|
|
393
386
|
|
|
394
|
-
if (!this.appSyncRealTime) {
|
|
395
|
-
this.appSyncRealTime = new AWSAppSyncRealTimeProvider();
|
|
396
|
-
}
|
|
397
387
|
return this.appSyncRealTime.subscribe(
|
|
398
388
|
{
|
|
399
389
|
query: print(query as DocumentNode),
|
|
@@ -409,4 +399,4 @@ export class InternalGraphQLAPIClass {
|
|
|
409
399
|
}
|
|
410
400
|
}
|
|
411
401
|
|
|
412
|
-
export const InternalGraphQLAPI = new InternalGraphQLAPIClass(
|
|
402
|
+
export const InternalGraphQLAPI = new InternalGraphQLAPIClass();
|
|
@@ -9,9 +9,10 @@ import { listFactory } from './operations/list';
|
|
|
9
9
|
import { getFactory } from './operations/get';
|
|
10
10
|
import { subscriptionFactory } from './operations/subscription';
|
|
11
11
|
import { observeQueryFactory } from './operations/observeQuery';
|
|
12
|
+
import { ModelIntrospectionSchema } from '@aws-amplify/core/internals/utils';
|
|
12
13
|
|
|
13
14
|
export function generateModelsProperty<T extends Record<any, any> = never>(
|
|
14
|
-
client: V6Client,
|
|
15
|
+
client: V6Client<Record<string, any>>,
|
|
15
16
|
params: ClientGenerationParams
|
|
16
17
|
): ModelTypes<T> {
|
|
17
18
|
const models = {} as any;
|
|
@@ -23,17 +24,19 @@ export function generateModelsProperty<T extends Record<any, any> = never>(
|
|
|
23
24
|
);
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
const modelIntrospection =
|
|
27
|
+
const modelIntrospection: ModelIntrospectionSchema | undefined =
|
|
28
|
+
config.API.GraphQL.modelIntrospection;
|
|
29
|
+
|
|
27
30
|
if (!modelIntrospection) {
|
|
28
|
-
return {} as
|
|
31
|
+
return {} as ModelTypes<never>;
|
|
29
32
|
}
|
|
30
33
|
|
|
31
34
|
const SUBSCRIPTION_OPS = ['ONCREATE', 'ONUPDATE', 'ONDELETE'];
|
|
32
35
|
|
|
33
36
|
for (const model of Object.values(modelIntrospection.models)) {
|
|
34
|
-
const { name } = model
|
|
37
|
+
const { name } = model;
|
|
35
38
|
|
|
36
|
-
models[name] = {} as any
|
|
39
|
+
models[name] = {} as Record<string, any>;
|
|
37
40
|
|
|
38
41
|
Object.entries(graphQLOperationsInfo).forEach(
|
|
39
42
|
([key, { operationPrefix }]) => {
|