@aws-amplify/api-graphql 4.0.1-console-preview.be08038.0 → 4.0.1-server-generate-client.1e317a1.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/lib/GraphQLAPI.d.ts +2 -2
- package/lib/GraphQLAPI.js +4 -6
- package/lib/Providers/AWSAppSyncRealTimeProvider/index.d.ts +1 -1
- package/lib/Providers/AWSAppSyncRealTimeProvider/index.js +36 -36
- package/lib/Providers/constants.js +5 -4
- package/lib/index.js +5 -4
- package/lib/internals/APIClient.d.ts +101 -0
- package/lib/internals/APIClient.js +443 -0
- package/lib/internals/InternalGraphQLAPI.d.ts +2 -2
- package/lib/internals/InternalGraphQLAPI.js +35 -17
- package/lib/internals/generateClient.d.ts +12 -0
- package/lib/internals/generateClient.js +30 -0
- package/lib/internals/generateModelsProperty.d.ts +4 -0
- package/lib/internals/generateModelsProperty.js +169 -0
- package/lib/internals/index.d.ts +1 -0
- package/lib/internals/index.js +8 -5
- package/lib/internals/types.d.ts +10 -0
- package/lib/internals/types.js +2 -0
- package/lib/internals/v6.js +1 -0
- package/lib/tsconfig.tsbuildinfo +1 -6619
- package/lib/types/PubSub.d.ts +2 -2
- package/lib/types/PubSub.js +3 -2
- package/lib/types/index.d.ts +25 -22
- package/lib/types/index.js +4 -3
- package/lib/utils/ConnectionStateMonitor.d.ts +3 -3
- package/lib/utils/ConnectionStateMonitor.js +7 -6
- package/lib/utils/ReachabilityMonitor/index.d.ts +1 -1
- package/lib/utils/ReachabilityMonitor/index.js +3 -1
- package/lib/utils/ReachabilityMonitor/index.native.d.ts +1 -1
- package/lib/utils/ReachabilityMonitor/index.native.js +3 -1
- package/lib/utils/ReconnectionMonitor.js +2 -1
- package/lib/utils/errors/APIError.js +1 -0
- package/lib/utils/errors/assertValidationError.js +1 -0
- package/lib/utils/errors/index.js +5 -4
- package/lib/utils/errors/validation.js +2 -1
- package/lib/utils/index.js +3 -2
- package/lib/utils/resolveConfig.d.ts +1 -1
- package/lib/utils/resolveConfig.js +4 -2
- package/lib/utils/resolveLibraryOptions.d.ts +1 -1
- package/lib/utils/resolveLibraryOptions.js +3 -1
- package/lib/utils/resolveOwnerFields.d.ts +12 -0
- package/lib/utils/resolveOwnerFields.js +63 -0
- package/lib-esm/GraphQLAPI.d.ts +2 -2
- package/lib-esm/GraphQLAPI.js +1 -5
- package/lib-esm/Providers/AWSAppSyncRealTimeProvider/index.d.ts +1 -1
- package/lib-esm/Providers/AWSAppSyncRealTimeProvider/index.js +28 -29
- package/lib-esm/internals/APIClient.d.ts +101 -0
- package/lib-esm/internals/APIClient.js +432 -0
- package/lib-esm/internals/InternalGraphQLAPI.d.ts +2 -2
- package/lib-esm/internals/InternalGraphQLAPI.js +21 -5
- package/lib-esm/internals/generateClient.d.ts +12 -0
- package/lib-esm/internals/generateClient.js +26 -0
- package/lib-esm/internals/generateModelsProperty.d.ts +4 -0
- package/lib-esm/internals/generateModelsProperty.js +165 -0
- package/lib-esm/internals/index.d.ts +1 -0
- package/lib-esm/internals/index.js +1 -0
- package/lib-esm/internals/types.d.ts +10 -0
- package/lib-esm/internals/types.js +1 -0
- package/lib-esm/tsconfig.tsbuildinfo +1 -6619
- package/lib-esm/types/PubSub.d.ts +2 -2
- package/lib-esm/types/index.d.ts +25 -22
- package/lib-esm/utils/ConnectionStateMonitor.d.ts +3 -3
- package/lib-esm/utils/ConnectionStateMonitor.js +2 -2
- package/lib-esm/utils/ReachabilityMonitor/index.d.ts +1 -1
- package/lib-esm/utils/ReachabilityMonitor/index.native.d.ts +1 -1
- package/lib-esm/utils/resolveConfig.d.ts +1 -1
- package/lib-esm/utils/resolveLibraryOptions.d.ts +1 -1
- package/lib-esm/utils/resolveOwnerFields.d.ts +12 -0
- package/lib-esm/utils/resolveOwnerFields.js +59 -0
- package/package.json +12 -6
- package/src/GraphQLAPI.ts +2 -6
- package/src/Providers/AWSAppSyncRealTimeProvider/index.ts +2 -3
- package/src/internals/APIClient.ts +583 -0
- package/src/internals/InternalGraphQLAPI.ts +35 -9
- package/src/internals/generateClient.ts +30 -0
- package/src/internals/generateModelsProperty.ts +192 -0
- package/src/internals/index.ts +1 -0
- package/src/internals/types.ts +15 -0
- package/src/types/index.ts +7 -1
- package/src/utils/resolveOwnerFields.ts +65 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { ModelTypes } from '@aws-amplify/amplify-api-next-types-alpha';
|
|
4
|
+
import {
|
|
5
|
+
initializeModel,
|
|
6
|
+
generateGraphQLDocument,
|
|
7
|
+
buildGraphQLVariables,
|
|
8
|
+
graphQLOperationsInfo,
|
|
9
|
+
ModelOperation,
|
|
10
|
+
flattenItems,
|
|
11
|
+
} from './APIClient';
|
|
12
|
+
import { ClientGenerationParams } from './types';
|
|
13
|
+
import { V6Client, GraphqlSubscriptionResult } from '../types';
|
|
14
|
+
import { Observable, map } from 'rxjs';
|
|
15
|
+
import { Amplify } from '@aws-amplify/core';
|
|
16
|
+
|
|
17
|
+
export function generateModelsProperty<T extends Record<any, any> = never>(
|
|
18
|
+
client: V6Client,
|
|
19
|
+
params: ClientGenerationParams
|
|
20
|
+
): ModelTypes<T> {
|
|
21
|
+
const models = {} as any;
|
|
22
|
+
// params.config gets populated in SSR only; otherwise we get it from the singleton
|
|
23
|
+
const config: any = params.config ?? Amplify.getConfig();
|
|
24
|
+
|
|
25
|
+
const modelIntrospection = config.API?.GraphQL?.modelIntrospection;
|
|
26
|
+
if (!modelIntrospection) {
|
|
27
|
+
return {} as any;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// TODO: refactor this to use separate methods for each CRUDL.
|
|
31
|
+
// Doesn't make sense to gen the methods dynamically given the different args and return values
|
|
32
|
+
for (const model of Object.values(modelIntrospection.models)) {
|
|
33
|
+
const { name } = model as any;
|
|
34
|
+
|
|
35
|
+
models[name] = {} as any;
|
|
36
|
+
|
|
37
|
+
Object.entries(graphQLOperationsInfo).forEach(
|
|
38
|
+
([key, { operationPrefix }]) => {
|
|
39
|
+
const operation = key as ModelOperation;
|
|
40
|
+
|
|
41
|
+
if (operation === 'LIST') {
|
|
42
|
+
models[name][operationPrefix] = async (args?: any) => {
|
|
43
|
+
const query = generateGraphQLDocument(
|
|
44
|
+
modelIntrospection.models,
|
|
45
|
+
name,
|
|
46
|
+
'LIST',
|
|
47
|
+
args
|
|
48
|
+
);
|
|
49
|
+
const variables = buildGraphQLVariables(
|
|
50
|
+
model,
|
|
51
|
+
'LIST',
|
|
52
|
+
args,
|
|
53
|
+
modelIntrospection
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
try {
|
|
57
|
+
const { data, nextToken, extensions } = (await client.graphql({
|
|
58
|
+
query,
|
|
59
|
+
variables,
|
|
60
|
+
})) as any;
|
|
61
|
+
|
|
62
|
+
// flatten response
|
|
63
|
+
if (data !== undefined) {
|
|
64
|
+
const [key] = Object.keys(data);
|
|
65
|
+
|
|
66
|
+
if (data[key].items) {
|
|
67
|
+
const flattenedResult = flattenItems(data)[key];
|
|
68
|
+
|
|
69
|
+
// don't init if custom selection set
|
|
70
|
+
if (args?.selectionSet) {
|
|
71
|
+
return {
|
|
72
|
+
data: flattenedResult,
|
|
73
|
+
nextToken,
|
|
74
|
+
extensions,
|
|
75
|
+
};
|
|
76
|
+
} else {
|
|
77
|
+
const initialized = initializeModel(
|
|
78
|
+
client,
|
|
79
|
+
name,
|
|
80
|
+
flattenedResult,
|
|
81
|
+
modelIntrospection
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
data: initialized,
|
|
86
|
+
nextToken,
|
|
87
|
+
extensions,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return {
|
|
93
|
+
data: data[key],
|
|
94
|
+
nextToken,
|
|
95
|
+
extensions,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
} catch (error) {
|
|
99
|
+
if (error.errors) {
|
|
100
|
+
// graphql errors pass through
|
|
101
|
+
return error as any;
|
|
102
|
+
} else {
|
|
103
|
+
// non-graphql errors re re-thrown
|
|
104
|
+
throw error;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
} else if (['ONCREATE', 'ONUPDATE', 'ONDELETE'].includes(operation)) {
|
|
109
|
+
models[name][operationPrefix] = (arg?: any, options?: any) => {
|
|
110
|
+
const query = generateGraphQLDocument(
|
|
111
|
+
modelIntrospection.models,
|
|
112
|
+
name,
|
|
113
|
+
operation
|
|
114
|
+
);
|
|
115
|
+
const variables = buildGraphQLVariables(
|
|
116
|
+
model,
|
|
117
|
+
operation,
|
|
118
|
+
arg,
|
|
119
|
+
modelIntrospection
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
const observable = client.graphql({
|
|
123
|
+
query,
|
|
124
|
+
variables,
|
|
125
|
+
}) as GraphqlSubscriptionResult<object>;
|
|
126
|
+
|
|
127
|
+
return observable.pipe(
|
|
128
|
+
map(value => {
|
|
129
|
+
const [key] = Object.keys(value.data);
|
|
130
|
+
return value.data[key];
|
|
131
|
+
})
|
|
132
|
+
);
|
|
133
|
+
};
|
|
134
|
+
} else {
|
|
135
|
+
models[name][operationPrefix] = async (arg?: any, options?: any) => {
|
|
136
|
+
const query = generateGraphQLDocument(
|
|
137
|
+
modelIntrospection.models,
|
|
138
|
+
name,
|
|
139
|
+
operation,
|
|
140
|
+
options
|
|
141
|
+
);
|
|
142
|
+
const variables = buildGraphQLVariables(
|
|
143
|
+
model,
|
|
144
|
+
operation,
|
|
145
|
+
arg,
|
|
146
|
+
modelIntrospection
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
try {
|
|
150
|
+
const { data, extensions } = (await client.graphql({
|
|
151
|
+
query,
|
|
152
|
+
variables,
|
|
153
|
+
})) as any;
|
|
154
|
+
|
|
155
|
+
// flatten response
|
|
156
|
+
if (data !== undefined) {
|
|
157
|
+
const [key] = Object.keys(data);
|
|
158
|
+
const flattenedResult = flattenItems(data)[key];
|
|
159
|
+
|
|
160
|
+
if (options?.selectionSet) {
|
|
161
|
+
return { data: flattenedResult, extensions };
|
|
162
|
+
} else {
|
|
163
|
+
// TODO: refactor to avoid destructuring here
|
|
164
|
+
const [initialized] = initializeModel(
|
|
165
|
+
client,
|
|
166
|
+
name,
|
|
167
|
+
[flattenedResult],
|
|
168
|
+
modelIntrospection
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
return { data: initialized, extensions };
|
|
172
|
+
}
|
|
173
|
+
} else {
|
|
174
|
+
return { data: null, extensions };
|
|
175
|
+
}
|
|
176
|
+
} catch (error) {
|
|
177
|
+
if (error.errors) {
|
|
178
|
+
// graphql errors pass through
|
|
179
|
+
return error as any;
|
|
180
|
+
} else {
|
|
181
|
+
// non-graphql errors re re-thrown
|
|
182
|
+
throw error;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return models;
|
|
192
|
+
}
|
package/src/internals/index.ts
CHANGED
|
@@ -0,0 +1,15 @@
|
|
|
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
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @private
|
|
7
|
+
*
|
|
8
|
+
* The knobs available for configuring `generateClient` internally.
|
|
9
|
+
*/
|
|
10
|
+
export type ClientGenerationParams = {
|
|
11
|
+
amplify:
|
|
12
|
+
| AmplifyClassV6
|
|
13
|
+
| ((fn: (amplify: any) => Promise<any>) => Promise<AmplifyClassV6>);
|
|
14
|
+
config?: object;
|
|
15
|
+
};
|
package/src/types/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
import { AmplifyClassV6 } from '@aws-amplify/core';
|
|
4
|
+
import { ModelTypes } from '@aws-amplify/amplify-api-next-types-alpha';
|
|
4
5
|
import { Source, DocumentNode, GraphQLError } from 'graphql';
|
|
5
6
|
export { OperationTypeNode } from 'graphql';
|
|
6
7
|
import { Observable } from 'rxjs';
|
|
@@ -10,6 +11,9 @@ import {
|
|
|
10
11
|
DocumentType,
|
|
11
12
|
} from '@aws-amplify/core/internals/utils';
|
|
12
13
|
export { CONTROL_MSG, ConnectionState } from './PubSub';
|
|
14
|
+
|
|
15
|
+
export { SelectionSet } from '@aws-amplify/amplify-api-next-types-alpha';
|
|
16
|
+
|
|
13
17
|
/**
|
|
14
18
|
* Loose/Unknown options for raw GraphQLAPICategory `graphql()`.
|
|
15
19
|
*/
|
|
@@ -347,6 +351,7 @@ export type GeneratedSubscription<InputType, OutputType> = string & {
|
|
|
347
351
|
type FilteredKeys<T> = {
|
|
348
352
|
[P in keyof T]: T[P] extends never ? never : P;
|
|
349
353
|
}[keyof T];
|
|
354
|
+
|
|
350
355
|
type ExcludeNeverFields<O> = {
|
|
351
356
|
[K in FilteredKeys<O>]: O[K];
|
|
352
357
|
};
|
|
@@ -354,7 +359,7 @@ type ExcludeNeverFields<O> = {
|
|
|
354
359
|
export const __amplify = Symbol('amplify');
|
|
355
360
|
|
|
356
361
|
export type V6Client<T extends Record<any, any> = never> = ExcludeNeverFields<{
|
|
357
|
-
[__amplify]: AmplifyClassV6;
|
|
362
|
+
[__amplify]: AmplifyClassV6 | (() => Promise<AmplifyClassV6>);
|
|
358
363
|
graphql: <FALLBACK_TYPES = unknown, TYPED_GQL_STRING extends string = string>(
|
|
359
364
|
options: GraphQLOptionsV6<FALLBACK_TYPES, TYPED_GQL_STRING>,
|
|
360
365
|
additionalHeaders?:
|
|
@@ -365,4 +370,5 @@ export type V6Client<T extends Record<any, any> = never> = ExcludeNeverFields<{
|
|
|
365
370
|
) => GraphQLResponseV6<FALLBACK_TYPES, TYPED_GQL_STRING>;
|
|
366
371
|
cancel: (promise: Promise<any>, message?: string) => boolean;
|
|
367
372
|
isCancelError: (error: any) => boolean;
|
|
373
|
+
models: ModelTypes<T>;
|
|
368
374
|
}>;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { ResourcesConfig } from '@aws-amplify/core';
|
|
4
|
+
|
|
5
|
+
type GraphQLConfig = Exclude<ResourcesConfig['API'], undefined>['GraphQL'];
|
|
6
|
+
type ModelIntrospectionSchema = Exclude<
|
|
7
|
+
Exclude<GraphQLConfig, undefined>['modelIntrospection'],
|
|
8
|
+
undefined
|
|
9
|
+
>;
|
|
10
|
+
type Model = ModelIntrospectionSchema['models'][string];
|
|
11
|
+
|
|
12
|
+
type AuthAttribute = {
|
|
13
|
+
type: 'auth';
|
|
14
|
+
properties: {
|
|
15
|
+
rules: AuthRule[];
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Only the portions of an Auth rule we care about.
|
|
21
|
+
*/
|
|
22
|
+
type AuthRule = {
|
|
23
|
+
allow: string;
|
|
24
|
+
ownerField?: string;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Given an introspection schema model, returns all owner fields.
|
|
29
|
+
*
|
|
30
|
+
* @param model Model from an introspection schema
|
|
31
|
+
* @returns List of owner field names
|
|
32
|
+
*/
|
|
33
|
+
export function resolveOwnerFields(model: Model): string[] {
|
|
34
|
+
const ownerFields = new Set<string>();
|
|
35
|
+
for (const attr of model.attributes || []) {
|
|
36
|
+
if (isAuthAttribute(attr)) {
|
|
37
|
+
for (const rule of attr.properties.rules) {
|
|
38
|
+
if (rule.allow === 'owner') {
|
|
39
|
+
ownerFields.add(rule.ownerField || 'owner');
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return Array.from(ownerFields);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Type guard that identifies an auth attribute with an attached rules list that
|
|
49
|
+
* specifies an `allow` attribute at a minimum.
|
|
50
|
+
*
|
|
51
|
+
* @param attribute Any object. Ideally a model introspection schema model attribute
|
|
52
|
+
* @returns True if given object is an auth attribute
|
|
53
|
+
*/
|
|
54
|
+
function isAuthAttribute(attribute: any): attribute is AuthAttribute {
|
|
55
|
+
if (attribute?.type === 'auth') {
|
|
56
|
+
if (typeof attribute?.properties === 'object') {
|
|
57
|
+
if (Array.isArray(attribute?.properties?.rules)) {
|
|
58
|
+
return (attribute?.properties?.rules as Array<any>).every(
|
|
59
|
+
rule => !!rule.allow
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return false;
|
|
65
|
+
}
|