@aws-amplify/api-graphql 4.0.2-unstable.ff85fa5.0 → 4.0.2
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 +528 -0
- package/dist/cjs/internals/APIClient.js.map +1 -0
- package/dist/cjs/internals/InternalGraphQLAPI.js +14 -23
- package/dist/cjs/internals/InternalGraphQLAPI.js.map +1 -1
- package/dist/cjs/internals/generateClient.js +33 -0
- package/dist/cjs/internals/generateClient.js.map +1 -0
- package/dist/cjs/internals/generateModelsProperty.js +43 -0
- package/dist/cjs/internals/generateModelsProperty.js.map +1 -0
- package/dist/cjs/internals/index.js +3 -1
- package/dist/cjs/internals/index.js.map +1 -1
- package/dist/cjs/internals/operations/get.js +61 -0
- package/dist/cjs/internals/operations/get.js.map +1 -0
- package/dist/cjs/internals/operations/list.js +73 -0
- package/dist/cjs/internals/operations/list.js.map +1 -0
- package/dist/cjs/internals/operations/observeQuery.js +121 -0
- package/dist/cjs/internals/operations/observeQuery.js.map +1 -0
- package/dist/cjs/internals/operations/subscription.js +30 -0
- package/dist/cjs/internals/operations/subscription.js.map +1 -0
- package/dist/cjs/internals/server/generateClient.js +32 -0
- package/dist/cjs/internals/server/generateClient.js.map +1 -0
- package/dist/cjs/internals/server/generateModelsProperty.js +47 -0
- package/dist/cjs/internals/server/generateModelsProperty.js.map +1 -0
- package/dist/cjs/internals/server/index.js +9 -0
- package/dist/cjs/internals/server/index.js.map +1 -0
- package/dist/cjs/internals/types.js +4 -0
- package/dist/cjs/internals/types.js.map +1 -0
- package/dist/cjs/types/index.js +3 -1
- package/dist/cjs/types/index.js.map +1 -1
- package/dist/cjs/utils/findIndexByFields.js +25 -0
- package/dist/cjs/utils/findIndexByFields.js.map +1 -0
- package/dist/cjs/utils/index.js +5 -1
- package/dist/cjs/utils/index.js.map +1 -1
- package/dist/cjs/utils/resolveOwnerFields.js +42 -0
- package/dist/cjs/utils/resolveOwnerFields.js.map +1 -0
- package/dist/cjs/utils/resolvePKFields.js +17 -0
- package/dist/cjs/utils/resolvePKFields.js.map +1 -0
- 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/index.mjs +1 -1
- package/dist/esm/internals/APIClient.d.ts +112 -0
- package/dist/esm/internals/APIClient.mjs +518 -0
- package/dist/esm/internals/APIClient.mjs.map +1 -0
- package/dist/esm/internals/InternalGraphQLAPI.d.ts +0 -11
- package/dist/esm/internals/InternalGraphQLAPI.mjs +14 -22
- package/dist/esm/internals/InternalGraphQLAPI.mjs.map +1 -1
- package/dist/esm/internals/generateClient.d.ts +12 -0
- package/dist/esm/internals/generateClient.mjs +31 -0
- package/dist/esm/internals/generateClient.mjs.map +1 -0
- package/dist/esm/internals/generateModelsProperty.d.ts +4 -0
- package/dist/esm/internals/generateModelsProperty.mjs +41 -0
- package/dist/esm/internals/generateModelsProperty.mjs.map +1 -0
- package/dist/esm/internals/index.d.ts +1 -0
- package/dist/esm/internals/index.mjs +1 -0
- package/dist/esm/internals/index.mjs.map +1 -1
- package/dist/esm/internals/operations/get.d.ts +5 -0
- package/dist/esm/internals/operations/get.mjs +59 -0
- package/dist/esm/internals/operations/get.mjs.map +1 -0
- package/dist/esm/internals/operations/list.d.ts +4 -0
- package/dist/esm/internals/operations/list.mjs +71 -0
- package/dist/esm/internals/operations/list.mjs.map +1 -0
- package/dist/esm/internals/operations/observeQuery.d.ts +3 -0
- package/dist/esm/internals/operations/observeQuery.mjs +122 -0
- package/dist/esm/internals/operations/observeQuery.mjs.map +1 -0
- package/dist/esm/internals/operations/subscription.d.ts +3 -0
- package/dist/esm/internals/operations/subscription.mjs +28 -0
- package/dist/esm/internals/operations/subscription.mjs.map +1 -0
- package/dist/esm/internals/server/generateClient.d.ts +11 -0
- package/dist/esm/internals/server/generateClient.mjs +34 -0
- package/dist/esm/internals/server/generateClient.mjs.map +1 -0
- package/dist/esm/internals/server/generateModelsProperty.d.ts +3 -0
- package/dist/esm/internals/server/generateModelsProperty.mjs +45 -0
- package/dist/esm/internals/server/generateModelsProperty.mjs.map +1 -0
- package/dist/esm/internals/server/index.d.ts +1 -0
- package/dist/esm/internals/server/index.mjs +2 -0
- package/dist/esm/internals/server/index.mjs.map +1 -0
- package/dist/esm/internals/types.d.ts +17 -0
- package/dist/esm/internals/types.mjs +2 -0
- package/dist/esm/internals/types.mjs.map +1 -0
- package/dist/esm/types/index.d.ts +32 -2
- package/dist/esm/types/index.mjs +3 -1
- package/dist/esm/types/index.mjs.map +1 -1
- package/dist/esm/utils/findIndexByFields.d.ts +9 -0
- package/dist/esm/utils/findIndexByFields.mjs +22 -0
- package/dist/esm/utils/findIndexByFields.mjs.map +1 -0
- package/dist/esm/utils/index.d.ts +2 -0
- package/dist/esm/utils/index.mjs +2 -0
- package/dist/esm/utils/index.mjs.map +1 -1
- package/dist/esm/utils/resolveOwnerFields.d.ts +12 -0
- package/dist/esm/utils/resolveOwnerFields.mjs +39 -0
- package/dist/esm/utils/resolveOwnerFields.mjs.map +1 -0
- package/dist/esm/utils/resolvePKFields.d.ts +13 -0
- package/dist/esm/utils/resolvePKFields.mjs +14 -0
- package/dist/esm/utils/resolvePKFields.mjs.map +1 -0
- package/internals/server/package.json +8 -0
- package/package.json +148 -146
- package/src/GraphQLAPI.ts +2 -2
- package/src/Providers/AWSAppSyncRealTimeProvider/index.ts +9 -4
- package/src/internals/APIClient.ts +780 -0
- package/src/internals/InternalGraphQLAPI.ts +21 -31
- package/src/internals/generateClient.ts +33 -0
- package/src/internals/generateModelsProperty.ts +73 -0
- package/src/internals/index.ts +1 -0
- package/src/internals/operations/get.ts +131 -0
- package/src/internals/operations/list.ts +132 -0
- package/src/internals/operations/observeQuery.ts +144 -0
- package/src/internals/operations/subscription.ts +65 -0
- package/src/internals/server/generateClient.ts +45 -0
- package/src/internals/server/generateModelsProperty.ts +80 -0
- package/src/internals/server/index.ts +4 -0
- package/src/internals/types.ts +21 -0
- package/src/types/index.ts +42 -2
- package/src/utils/ConnectionStateMonitor.ts +3 -1
- package/src/utils/findIndexByFields.ts +31 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/resolveOwnerFields.ts +65 -0
- package/src/utils/resolvePKFields.ts +22 -0
|
@@ -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,16 +384,13 @@ 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),
|
|
400
390
|
variables,
|
|
401
391
|
appSyncGraphqlEndpoint: config?.endpoint,
|
|
402
392
|
region: config?.region,
|
|
403
|
-
authenticationType: authMode
|
|
393
|
+
authenticationType: authMode || config?.defaultAuthMode,
|
|
404
394
|
apiKey: config?.apiKey,
|
|
405
395
|
additionalHeaders,
|
|
406
396
|
},
|
|
@@ -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();
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { graphql, cancel, isCancelError } from './v6';
|
|
4
|
+
import { generateModelsProperty } from './generateModelsProperty';
|
|
5
|
+
import { V6Client, __amplify, __authMode, __authToken } from '../types';
|
|
6
|
+
import { ClientGenerationParams } from './types';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @private
|
|
10
|
+
*
|
|
11
|
+
* Creates a client that can be used to make GraphQL requests, using a provided `AmplifyClassV6`
|
|
12
|
+
* compatible context object for config and auth fetching.
|
|
13
|
+
*
|
|
14
|
+
* @param params
|
|
15
|
+
* @returns
|
|
16
|
+
*/
|
|
17
|
+
export function generateClient<T extends Record<any, any> = never>(
|
|
18
|
+
params: ClientGenerationParams
|
|
19
|
+
): V6Client<T> {
|
|
20
|
+
const client = {
|
|
21
|
+
[__amplify]: params.amplify,
|
|
22
|
+
[__authMode]: params.authMode,
|
|
23
|
+
[__authToken]: params.authToken,
|
|
24
|
+
graphql,
|
|
25
|
+
cancel,
|
|
26
|
+
isCancelError,
|
|
27
|
+
models: {},
|
|
28
|
+
} as any;
|
|
29
|
+
|
|
30
|
+
client.models = generateModelsProperty<T>(client, params);
|
|
31
|
+
|
|
32
|
+
return client as V6Client<T>;
|
|
33
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { ModelTypes } from '@aws-amplify/data-schema-types';
|
|
4
|
+
import { graphQLOperationsInfo, ModelOperation } from './APIClient';
|
|
5
|
+
import { ClientGenerationParams } from './types';
|
|
6
|
+
import { V6Client, __authMode, __authToken } from '../types';
|
|
7
|
+
|
|
8
|
+
import { listFactory } from './operations/list';
|
|
9
|
+
import { getFactory } from './operations/get';
|
|
10
|
+
import { subscriptionFactory } from './operations/subscription';
|
|
11
|
+
import { observeQueryFactory } from './operations/observeQuery';
|
|
12
|
+
import { ModelIntrospectionSchema } from '@aws-amplify/core/internals/utils';
|
|
13
|
+
|
|
14
|
+
export function generateModelsProperty<T extends Record<any, any> = never>(
|
|
15
|
+
client: V6Client<Record<string, any>>,
|
|
16
|
+
params: ClientGenerationParams
|
|
17
|
+
): ModelTypes<T> {
|
|
18
|
+
const models = {} as any;
|
|
19
|
+
const config = params.amplify.getConfig();
|
|
20
|
+
|
|
21
|
+
if (!config.API?.GraphQL) {
|
|
22
|
+
throw new Error(
|
|
23
|
+
'The API configuration is missing. This is likely due to Amplify.configure() not being called prior to generateClient().'
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const modelIntrospection: ModelIntrospectionSchema | undefined =
|
|
28
|
+
config.API.GraphQL.modelIntrospection;
|
|
29
|
+
|
|
30
|
+
if (!modelIntrospection) {
|
|
31
|
+
return {} as ModelTypes<never>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const SUBSCRIPTION_OPS = ['ONCREATE', 'ONUPDATE', 'ONDELETE'];
|
|
35
|
+
|
|
36
|
+
for (const model of Object.values(modelIntrospection.models)) {
|
|
37
|
+
const { name } = model;
|
|
38
|
+
|
|
39
|
+
models[name] = {} as Record<string, any>;
|
|
40
|
+
|
|
41
|
+
Object.entries(graphQLOperationsInfo).forEach(
|
|
42
|
+
([key, { operationPrefix }]) => {
|
|
43
|
+
const operation = key as ModelOperation;
|
|
44
|
+
|
|
45
|
+
if (operation === 'LIST') {
|
|
46
|
+
models[name][operationPrefix] = listFactory(
|
|
47
|
+
client,
|
|
48
|
+
modelIntrospection,
|
|
49
|
+
model
|
|
50
|
+
);
|
|
51
|
+
} else if (SUBSCRIPTION_OPS.includes(operation)) {
|
|
52
|
+
models[name][operationPrefix] = subscriptionFactory(
|
|
53
|
+
client,
|
|
54
|
+
modelIntrospection,
|
|
55
|
+
model,
|
|
56
|
+
operation
|
|
57
|
+
);
|
|
58
|
+
} else if (operation === 'OBSERVE_QUERY') {
|
|
59
|
+
models[name][operationPrefix] = observeQueryFactory(models, model);
|
|
60
|
+
} else {
|
|
61
|
+
models[name][operationPrefix] = getFactory(
|
|
62
|
+
client,
|
|
63
|
+
modelIntrospection,
|
|
64
|
+
model,
|
|
65
|
+
operation
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return models;
|
|
73
|
+
}
|
package/src/internals/index.ts
CHANGED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { AmplifyServer } from '@aws-amplify/core/internals/adapter-core';
|
|
4
|
+
import {
|
|
5
|
+
initializeModel,
|
|
6
|
+
generateGraphQLDocument,
|
|
7
|
+
buildGraphQLVariables,
|
|
8
|
+
flattenItems,
|
|
9
|
+
authModeParams,
|
|
10
|
+
ModelOperation,
|
|
11
|
+
} from '../APIClient';
|
|
12
|
+
import {
|
|
13
|
+
AuthModeParams,
|
|
14
|
+
ClientWithModels,
|
|
15
|
+
GraphQLOptionsV6,
|
|
16
|
+
GraphQLResult,
|
|
17
|
+
ListArgs,
|
|
18
|
+
QueryArgs,
|
|
19
|
+
V6Client,
|
|
20
|
+
V6ClientSSRRequest,
|
|
21
|
+
} from '../../types';
|
|
22
|
+
import {
|
|
23
|
+
ModelIntrospectionSchema,
|
|
24
|
+
SchemaModel,
|
|
25
|
+
} from '@aws-amplify/core/internals/utils';
|
|
26
|
+
|
|
27
|
+
export function getFactory(
|
|
28
|
+
client: ClientWithModels,
|
|
29
|
+
modelIntrospection: ModelIntrospectionSchema,
|
|
30
|
+
model: SchemaModel,
|
|
31
|
+
operation: ModelOperation,
|
|
32
|
+
useContext = false
|
|
33
|
+
) {
|
|
34
|
+
const getWithContext = async (
|
|
35
|
+
contextSpec: AmplifyServer.ContextSpec & GraphQLOptionsV6<unknown, string>,
|
|
36
|
+
arg?: any,
|
|
37
|
+
options?: any
|
|
38
|
+
) => {
|
|
39
|
+
return _get(
|
|
40
|
+
client,
|
|
41
|
+
modelIntrospection,
|
|
42
|
+
model,
|
|
43
|
+
arg,
|
|
44
|
+
options,
|
|
45
|
+
operation,
|
|
46
|
+
contextSpec
|
|
47
|
+
);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const get = async (arg?: any, options?: any) => {
|
|
51
|
+
return _get(client, modelIntrospection, model, arg, options, operation);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
return useContext ? getWithContext : get;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async function _get(
|
|
58
|
+
client: ClientWithModels,
|
|
59
|
+
modelIntrospection: ModelIntrospectionSchema,
|
|
60
|
+
model: SchemaModel,
|
|
61
|
+
arg: QueryArgs,
|
|
62
|
+
options: AuthModeParams & ListArgs,
|
|
63
|
+
operation: ModelOperation,
|
|
64
|
+
context?: AmplifyServer.ContextSpec
|
|
65
|
+
) {
|
|
66
|
+
const { name } = model;
|
|
67
|
+
|
|
68
|
+
const query = generateGraphQLDocument(
|
|
69
|
+
modelIntrospection.models,
|
|
70
|
+
name,
|
|
71
|
+
operation,
|
|
72
|
+
options
|
|
73
|
+
);
|
|
74
|
+
const variables = buildGraphQLVariables(
|
|
75
|
+
model,
|
|
76
|
+
operation,
|
|
77
|
+
arg,
|
|
78
|
+
modelIntrospection
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
try {
|
|
82
|
+
const auth = authModeParams(client, options);
|
|
83
|
+
const { data, extensions } = context
|
|
84
|
+
? ((await (client as V6ClientSSRRequest<Record<string, any>>).graphql(
|
|
85
|
+
context,
|
|
86
|
+
{
|
|
87
|
+
...auth,
|
|
88
|
+
query,
|
|
89
|
+
variables,
|
|
90
|
+
}
|
|
91
|
+
)) as GraphQLResult<any>)
|
|
92
|
+
: ((await (client as V6Client<Record<string, any>>).graphql({
|
|
93
|
+
...auth,
|
|
94
|
+
query,
|
|
95
|
+
variables,
|
|
96
|
+
})) as GraphQLResult<any>);
|
|
97
|
+
|
|
98
|
+
// flatten response
|
|
99
|
+
if (data) {
|
|
100
|
+
const [key] = Object.keys(data);
|
|
101
|
+
const flattenedResult = flattenItems(data)[key];
|
|
102
|
+
|
|
103
|
+
if (options?.selectionSet) {
|
|
104
|
+
return { data: flattenedResult, extensions };
|
|
105
|
+
} else {
|
|
106
|
+
// TODO: refactor to avoid destructuring here
|
|
107
|
+
const [initialized] = initializeModel(
|
|
108
|
+
client,
|
|
109
|
+
name,
|
|
110
|
+
[flattenedResult],
|
|
111
|
+
modelIntrospection,
|
|
112
|
+
auth.authMode,
|
|
113
|
+
auth.authToken,
|
|
114
|
+
!!context
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
return { data: initialized, extensions };
|
|
118
|
+
}
|
|
119
|
+
} else {
|
|
120
|
+
return { data: null, extensions };
|
|
121
|
+
}
|
|
122
|
+
} catch (error: any) {
|
|
123
|
+
if (error.errors) {
|
|
124
|
+
// graphql errors pass through
|
|
125
|
+
return error as any;
|
|
126
|
+
} else {
|
|
127
|
+
// non-graphql errors re re-thrown
|
|
128
|
+
throw error;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { AmplifyServer } from '@aws-amplify/core/internals/adapter-core';
|
|
4
|
+
import {
|
|
5
|
+
initializeModel,
|
|
6
|
+
generateGraphQLDocument,
|
|
7
|
+
buildGraphQLVariables,
|
|
8
|
+
flattenItems,
|
|
9
|
+
authModeParams,
|
|
10
|
+
} from '../APIClient';
|
|
11
|
+
import {
|
|
12
|
+
AuthModeParams,
|
|
13
|
+
ClientWithModels,
|
|
14
|
+
ListArgs,
|
|
15
|
+
V6Client,
|
|
16
|
+
V6ClientSSRRequest,
|
|
17
|
+
GraphQLResult,
|
|
18
|
+
} from '../../types';
|
|
19
|
+
import {
|
|
20
|
+
ModelIntrospectionSchema,
|
|
21
|
+
SchemaModel,
|
|
22
|
+
} from '@aws-amplify/core/internals/utils';
|
|
23
|
+
|
|
24
|
+
export function listFactory(
|
|
25
|
+
client: ClientWithModels,
|
|
26
|
+
modelIntrospection: ModelIntrospectionSchema,
|
|
27
|
+
model: SchemaModel,
|
|
28
|
+
context = false
|
|
29
|
+
) {
|
|
30
|
+
const listWithContext = async (
|
|
31
|
+
contextSpec: AmplifyServer.ContextSpec,
|
|
32
|
+
args?: ListArgs
|
|
33
|
+
) => {
|
|
34
|
+
return _list(client, modelIntrospection, model, args, contextSpec);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const list = async (args?: any) => {
|
|
38
|
+
return _list(client, modelIntrospection, model, args);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
return context ? listWithContext : list;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function _list(
|
|
45
|
+
client: ClientWithModels,
|
|
46
|
+
modelIntrospection: ModelIntrospectionSchema,
|
|
47
|
+
model: SchemaModel,
|
|
48
|
+
args?: ListArgs & AuthModeParams,
|
|
49
|
+
contextSpec?: AmplifyServer.ContextSpec
|
|
50
|
+
) {
|
|
51
|
+
const { name } = model;
|
|
52
|
+
|
|
53
|
+
const query = generateGraphQLDocument(
|
|
54
|
+
modelIntrospection.models,
|
|
55
|
+
name,
|
|
56
|
+
'LIST',
|
|
57
|
+
args
|
|
58
|
+
);
|
|
59
|
+
const variables = buildGraphQLVariables(
|
|
60
|
+
model,
|
|
61
|
+
'LIST',
|
|
62
|
+
args,
|
|
63
|
+
modelIntrospection
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
const auth = authModeParams(client, args);
|
|
68
|
+
|
|
69
|
+
const { data, extensions } = !!contextSpec
|
|
70
|
+
? ((await (client as V6ClientSSRRequest<Record<string, any>>).graphql(
|
|
71
|
+
contextSpec,
|
|
72
|
+
{
|
|
73
|
+
...auth,
|
|
74
|
+
query,
|
|
75
|
+
variables,
|
|
76
|
+
}
|
|
77
|
+
)) as GraphQLResult<any>)
|
|
78
|
+
: ((await (client as V6Client<Record<string, any>>).graphql({
|
|
79
|
+
...auth,
|
|
80
|
+
query,
|
|
81
|
+
variables,
|
|
82
|
+
})) as GraphQLResult<any>);
|
|
83
|
+
|
|
84
|
+
// flatten response
|
|
85
|
+
if (data !== undefined) {
|
|
86
|
+
const [key] = Object.keys(data);
|
|
87
|
+
|
|
88
|
+
if (data[key].items) {
|
|
89
|
+
const flattenedResult = flattenItems(data)[key];
|
|
90
|
+
|
|
91
|
+
// don't init if custom selection set
|
|
92
|
+
if (args?.selectionSet) {
|
|
93
|
+
return {
|
|
94
|
+
data: flattenedResult,
|
|
95
|
+
nextToken: data[key].nextToken,
|
|
96
|
+
extensions,
|
|
97
|
+
};
|
|
98
|
+
} else {
|
|
99
|
+
const initialized = initializeModel(
|
|
100
|
+
client,
|
|
101
|
+
name,
|
|
102
|
+
flattenedResult,
|
|
103
|
+
modelIntrospection,
|
|
104
|
+
auth.authMode,
|
|
105
|
+
auth.authToken,
|
|
106
|
+
!!contextSpec
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
return {
|
|
110
|
+
data: initialized,
|
|
111
|
+
nextToken: data[key].nextToken,
|
|
112
|
+
extensions,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return {
|
|
118
|
+
data: data[key],
|
|
119
|
+
nextToken: data[key].nextToken,
|
|
120
|
+
extensions,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
} catch (error: any) {
|
|
124
|
+
if (error.errors) {
|
|
125
|
+
// graphql errors pass through
|
|
126
|
+
return error as any;
|
|
127
|
+
} else {
|
|
128
|
+
// non-graphql errors re re-thrown
|
|
129
|
+
throw error;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { Observable } from 'rxjs';
|
|
4
|
+
import { findIndexByFields, resolvePKFields } from '../../utils';
|
|
5
|
+
import { SchemaModel } from '@aws-amplify/core/internals/utils';
|
|
6
|
+
|
|
7
|
+
export function observeQueryFactory(models: any, model: SchemaModel) {
|
|
8
|
+
const { name } = model;
|
|
9
|
+
|
|
10
|
+
const observeQuery = (arg?: any) =>
|
|
11
|
+
new Observable(subscriber => {
|
|
12
|
+
// what we'll be sending to our subscribers
|
|
13
|
+
const items: object[] = [];
|
|
14
|
+
|
|
15
|
+
// To enqueue subscription messages while we collect our initial
|
|
16
|
+
// result set.
|
|
17
|
+
const messageQueue = [] as {
|
|
18
|
+
type: 'create' | 'update' | 'delete';
|
|
19
|
+
item: object;
|
|
20
|
+
}[];
|
|
21
|
+
|
|
22
|
+
// operation to take when message(s) arrive.
|
|
23
|
+
// this operation will be swapped out once initial "sync" is complete
|
|
24
|
+
// to immediately ingest messsages.
|
|
25
|
+
let receiveMessages = (...messages: typeof messageQueue) => {
|
|
26
|
+
return messageQueue.push(...messages);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// start subscriptions
|
|
30
|
+
const onCreateSub = models[name].onCreate(arg).subscribe({
|
|
31
|
+
next(item: object) {
|
|
32
|
+
receiveMessages({ item, type: 'create' });
|
|
33
|
+
},
|
|
34
|
+
error(error: any) {
|
|
35
|
+
subscriber.error({ type: 'onCreate', error });
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
const onUpdateSub = models[name].onUpdate(arg).subscribe({
|
|
39
|
+
next(item: object) {
|
|
40
|
+
receiveMessages({ item, type: 'update' });
|
|
41
|
+
},
|
|
42
|
+
error(error: any) {
|
|
43
|
+
subscriber.error({ type: 'onUpdate', error });
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
const onDeleteSub = models[name].onDelete(arg).subscribe({
|
|
47
|
+
next(item: object) {
|
|
48
|
+
receiveMessages({ item, type: 'delete' });
|
|
49
|
+
},
|
|
50
|
+
error(error: any) {
|
|
51
|
+
subscriber.error({ type: 'onDelete', error });
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// consumes a list of messages and sends a snapshot
|
|
56
|
+
function ingestMessages(messages: typeof messageQueue) {
|
|
57
|
+
for (const message of messages) {
|
|
58
|
+
const idx = findIndexByFields(message.item, items, pkFields as any);
|
|
59
|
+
switch (message.type) {
|
|
60
|
+
case 'create':
|
|
61
|
+
if (idx < 0) items.push(message.item);
|
|
62
|
+
break;
|
|
63
|
+
case 'update':
|
|
64
|
+
if (idx >= 0) items[idx] = message.item;
|
|
65
|
+
break;
|
|
66
|
+
case 'delete':
|
|
67
|
+
if (idx >= 0) items.splice(idx, 1);
|
|
68
|
+
break;
|
|
69
|
+
default:
|
|
70
|
+
console.error('Unrecognized message in observeQuery.', message);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
subscriber.next({
|
|
74
|
+
items,
|
|
75
|
+
isSynced: true,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const pkFields = resolvePKFields(model);
|
|
80
|
+
|
|
81
|
+
// initial results
|
|
82
|
+
(async () => {
|
|
83
|
+
let firstPage = true;
|
|
84
|
+
let nextToken: string | null = null;
|
|
85
|
+
while (!subscriber.closed && (firstPage || nextToken)) {
|
|
86
|
+
firstPage = false;
|
|
87
|
+
|
|
88
|
+
const {
|
|
89
|
+
data: page,
|
|
90
|
+
errors,
|
|
91
|
+
nextToken: _nextToken,
|
|
92
|
+
}: {
|
|
93
|
+
data: any;
|
|
94
|
+
errors: any;
|
|
95
|
+
nextToken: string | null;
|
|
96
|
+
} = await models[name].list({ ...arg, nextToken });
|
|
97
|
+
nextToken = _nextToken;
|
|
98
|
+
|
|
99
|
+
items.push(...page);
|
|
100
|
+
|
|
101
|
+
// if there are no more pages and no items we already know about
|
|
102
|
+
// that need to be merged in from sub, we're "synced"
|
|
103
|
+
const isSynced =
|
|
104
|
+
messageQueue.length === 0 &&
|
|
105
|
+
(nextToken === null || nextToken === undefined);
|
|
106
|
+
|
|
107
|
+
subscriber.next({
|
|
108
|
+
items,
|
|
109
|
+
isSynced,
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
if (Array.isArray(errors)) {
|
|
113
|
+
for (const error of errors) {
|
|
114
|
+
subscriber.error(error);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// play through the queue
|
|
120
|
+
if (messageQueue.length > 0) {
|
|
121
|
+
ingestMessages(messageQueue);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// switch the queue to write directly to the items collection
|
|
125
|
+
receiveMessages = (...messages: typeof messageQueue) => {
|
|
126
|
+
ingestMessages(messages);
|
|
127
|
+
return items.length;
|
|
128
|
+
};
|
|
129
|
+
})();
|
|
130
|
+
|
|
131
|
+
// when subscriber unsubscribes, tear down internal subs
|
|
132
|
+
return () => {
|
|
133
|
+
// 1. tear down internal subs
|
|
134
|
+
onCreateSub.unsubscribe();
|
|
135
|
+
onUpdateSub.unsubscribe();
|
|
136
|
+
onDeleteSub.unsubscribe();
|
|
137
|
+
|
|
138
|
+
// 2. there is no need to explicitly stop paging. instead, we
|
|
139
|
+
// just check `subscriber.closed` above before fetching each page.
|
|
140
|
+
};
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
return observeQuery;
|
|
144
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { map } from 'rxjs';
|
|
5
|
+
import { V6Client, GraphqlSubscriptionResult } from '../../types';
|
|
6
|
+
import {
|
|
7
|
+
initializeModel,
|
|
8
|
+
generateGraphQLDocument,
|
|
9
|
+
buildGraphQLVariables,
|
|
10
|
+
authModeParams,
|
|
11
|
+
ModelOperation,
|
|
12
|
+
} from '../APIClient';
|
|
13
|
+
import {
|
|
14
|
+
ModelIntrospectionSchema,
|
|
15
|
+
SchemaModel,
|
|
16
|
+
} from '@aws-amplify/core/internals/utils';
|
|
17
|
+
|
|
18
|
+
export function subscriptionFactory(
|
|
19
|
+
client: any,
|
|
20
|
+
modelIntrospection: ModelIntrospectionSchema,
|
|
21
|
+
model: SchemaModel,
|
|
22
|
+
operation: ModelOperation
|
|
23
|
+
) {
|
|
24
|
+
const { name } = model as any;
|
|
25
|
+
|
|
26
|
+
const subscription = (args?: any) => {
|
|
27
|
+
const query = generateGraphQLDocument(
|
|
28
|
+
modelIntrospection.models,
|
|
29
|
+
name,
|
|
30
|
+
operation
|
|
31
|
+
);
|
|
32
|
+
const variables = buildGraphQLVariables(
|
|
33
|
+
model,
|
|
34
|
+
operation,
|
|
35
|
+
args,
|
|
36
|
+
modelIntrospection
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
const auth = authModeParams(client, args);
|
|
40
|
+
|
|
41
|
+
const observable = client.graphql({
|
|
42
|
+
...auth,
|
|
43
|
+
query,
|
|
44
|
+
variables,
|
|
45
|
+
}) as GraphqlSubscriptionResult<object>;
|
|
46
|
+
|
|
47
|
+
return observable.pipe(
|
|
48
|
+
map(value => {
|
|
49
|
+
const [key] = Object.keys(value.data);
|
|
50
|
+
const data = (value.data as any)[key];
|
|
51
|
+
const [initialized] = initializeModel(
|
|
52
|
+
client as V6Client<Record<string, any>>,
|
|
53
|
+
name,
|
|
54
|
+
[data],
|
|
55
|
+
modelIntrospection,
|
|
56
|
+
auth.authMode,
|
|
57
|
+
auth.authToken
|
|
58
|
+
);
|
|
59
|
+
return initialized;
|
|
60
|
+
})
|
|
61
|
+
);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
return subscription;
|
|
65
|
+
}
|