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