@aws-amplify/data-schema 0.11.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/LICENSE +175 -0
- package/NOTICE +1 -0
- package/lib-esm/index.d.ts +4 -0
- package/lib-esm/index.js +28 -0
- package/lib-esm/src/Authorization.d.ts +262 -0
- package/lib-esm/src/Authorization.js +309 -0
- package/lib-esm/src/ClientSchema.d.ts +27 -0
- package/lib-esm/src/ClientSchema.js +3 -0
- package/lib-esm/src/CustomType.d.ts +33 -0
- package/lib-esm/src/CustomType.js +14 -0
- package/lib-esm/src/EnumType.d.ts +15 -0
- package/lib-esm/src/EnumType.js +17 -0
- package/lib-esm/src/MappedTypes/ExtractNonModelTypes.d.ts +32 -0
- package/lib-esm/src/MappedTypes/ExtractNonModelTypes.js +2 -0
- package/lib-esm/src/MappedTypes/ForeignKeys.d.ts +83 -0
- package/lib-esm/src/MappedTypes/ForeignKeys.js +2 -0
- package/lib-esm/src/MappedTypes/ImplicitFieldInjector.d.ts +37 -0
- package/lib-esm/src/MappedTypes/ImplicitFieldInjector.js +2 -0
- package/lib-esm/src/MappedTypes/ModelMetadata.d.ts +20 -0
- package/lib-esm/src/MappedTypes/ModelMetadata.js +2 -0
- package/lib-esm/src/MappedTypes/ResolveFieldProperties.d.ts +58 -0
- package/lib-esm/src/MappedTypes/ResolveFieldProperties.js +2 -0
- package/lib-esm/src/MappedTypes/ResolveSchema.d.ts +35 -0
- package/lib-esm/src/MappedTypes/ResolveSchema.js +2 -0
- package/lib-esm/src/ModelField.d.ts +158 -0
- package/lib-esm/src/ModelField.js +206 -0
- package/lib-esm/src/ModelRelationalField.d.ts +106 -0
- package/lib-esm/src/ModelRelationalField.js +113 -0
- package/lib-esm/src/ModelSchema.d.ts +39 -0
- package/lib-esm/src/ModelSchema.js +34 -0
- package/lib-esm/src/ModelType.d.ts +107 -0
- package/lib-esm/src/ModelType.js +32 -0
- package/lib-esm/src/RefType.d.ts +45 -0
- package/lib-esm/src/RefType.js +29 -0
- package/lib-esm/src/SchemaProcessor.d.ts +10 -0
- package/lib-esm/src/SchemaProcessor.js +408 -0
- package/lib-esm/src/index.d.ts +9 -0
- package/lib-esm/src/index.js +35 -0
- package/lib-esm/src/types.d.ts +18 -0
- package/lib-esm/src/types.js +8 -0
- package/lib-esm/tsconfig.tsbuildinfo +1 -0
- package/package.json +39 -0
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.accessData = exports.allow = exports.Operations = exports.Strategies = exports.CustomProviders = exports.GroupProviders = exports.OwnerProviders = exports.PrivateProviders = exports.PublicProviders = exports.Providers = void 0;
|
|
4
|
+
const __data = Symbol('data');
|
|
5
|
+
/**
|
|
6
|
+
* All possible providers.
|
|
7
|
+
*
|
|
8
|
+
* This list should not be used if you need to restrict available providers
|
|
9
|
+
* according to an auth strategcy. E.g., `public` auth can only be facilitated
|
|
10
|
+
* by `apiKey` and `iam` providers.
|
|
11
|
+
*/
|
|
12
|
+
exports.Providers = [
|
|
13
|
+
'apiKey',
|
|
14
|
+
'iam',
|
|
15
|
+
'userPools',
|
|
16
|
+
'oidc',
|
|
17
|
+
'function',
|
|
18
|
+
];
|
|
19
|
+
/**
|
|
20
|
+
* The subset of auth providers that can facilitate `public` auth.
|
|
21
|
+
*/
|
|
22
|
+
exports.PublicProviders = ['apiKey', 'iam'];
|
|
23
|
+
/**
|
|
24
|
+
* The subset of auth providers that can facilitate `private` auth.
|
|
25
|
+
*/
|
|
26
|
+
exports.PrivateProviders = ['userPools', 'oidc', 'iam'];
|
|
27
|
+
/**
|
|
28
|
+
* The subset of auth providers that can facilitate `owner` auth.
|
|
29
|
+
*/
|
|
30
|
+
exports.OwnerProviders = ['userPools', 'oidc'];
|
|
31
|
+
/**
|
|
32
|
+
* The subset of auth providers that can facilitate `group` auth.
|
|
33
|
+
*/
|
|
34
|
+
exports.GroupProviders = ['userPools', 'oidc'];
|
|
35
|
+
/**
|
|
36
|
+
* The subset of auth providers that can facilitate `custom` auth.
|
|
37
|
+
*/
|
|
38
|
+
exports.CustomProviders = ['function'];
|
|
39
|
+
exports.Strategies = [
|
|
40
|
+
'public',
|
|
41
|
+
'private',
|
|
42
|
+
'owner',
|
|
43
|
+
'groups',
|
|
44
|
+
'custom',
|
|
45
|
+
];
|
|
46
|
+
/**
|
|
47
|
+
* The operations that can be performed against an API.
|
|
48
|
+
*/
|
|
49
|
+
exports.Operations = [
|
|
50
|
+
'create',
|
|
51
|
+
'update',
|
|
52
|
+
'delete',
|
|
53
|
+
'read',
|
|
54
|
+
'get',
|
|
55
|
+
'list',
|
|
56
|
+
'sync',
|
|
57
|
+
'listen',
|
|
58
|
+
'search',
|
|
59
|
+
];
|
|
60
|
+
/**
|
|
61
|
+
* Creates a shallow copy of an object with an individual field pruned away.
|
|
62
|
+
*
|
|
63
|
+
* @param original The original object to prune.
|
|
64
|
+
* @param without The field to prune.
|
|
65
|
+
* @returns The pruned object.
|
|
66
|
+
*/
|
|
67
|
+
function omit(original, without) {
|
|
68
|
+
const pruned = { ...original };
|
|
69
|
+
delete pruned[without];
|
|
70
|
+
return pruned;
|
|
71
|
+
}
|
|
72
|
+
function to(operations) {
|
|
73
|
+
this[__data].operations = operations;
|
|
74
|
+
return omit(this, 'to');
|
|
75
|
+
}
|
|
76
|
+
function inField(field) {
|
|
77
|
+
this[__data].groupOrOwnerField = field;
|
|
78
|
+
const built = omit(this, 'inField');
|
|
79
|
+
return built;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Specifies a property of the identity JWT to use in place of `sub::username`
|
|
83
|
+
* as the value to match against the owner field for authorization.
|
|
84
|
+
*
|
|
85
|
+
* @param this Authorization object to operate against.
|
|
86
|
+
* @param property A property of identity JWT.
|
|
87
|
+
* @returns A copy of the Authorization object with the claim attached.
|
|
88
|
+
*/
|
|
89
|
+
function identityClaim(property) {
|
|
90
|
+
this[__data].identityClaim = property;
|
|
91
|
+
return omit(this, 'identityClaim');
|
|
92
|
+
}
|
|
93
|
+
function withClaimIn(property) {
|
|
94
|
+
this[__data].groupClaim = property;
|
|
95
|
+
return omit(this, 'withClaimIn');
|
|
96
|
+
}
|
|
97
|
+
function validateProvider(needle, haystack) {
|
|
98
|
+
if (needle && !haystack.includes(needle)) {
|
|
99
|
+
throw new Error(`Invalid provider (${needle}) given!`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function authData(defaults, builderMethods) {
|
|
103
|
+
return {
|
|
104
|
+
[__data]: {
|
|
105
|
+
strategy: 'public',
|
|
106
|
+
provider: undefined,
|
|
107
|
+
operations: undefined,
|
|
108
|
+
groupOrOwnerField: undefined,
|
|
109
|
+
multiOwner: false,
|
|
110
|
+
identityClaim: undefined,
|
|
111
|
+
groups: undefined,
|
|
112
|
+
...defaults,
|
|
113
|
+
// might not even be needed ...
|
|
114
|
+
// dependencies: {
|
|
115
|
+
// owner: {},
|
|
116
|
+
// },
|
|
117
|
+
},
|
|
118
|
+
...builderMethods,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Defines an authorization rule for your data models and fields. First choose an authorization strategy (`public`,
|
|
123
|
+
* `private`, `owner`, `group`, or `custom`), then choose an auth provider (`apiKey`, `iam`, `userPools`, `oidc`, or `function`)
|
|
124
|
+
* and optionally use `.to(...)` to specify the operations that can be performed against your data models and fields.
|
|
125
|
+
*/
|
|
126
|
+
exports.allow = {
|
|
127
|
+
/**
|
|
128
|
+
* Authorize unauthenticated users. By default, `.public()` uses an API key based authorization. You can additionally
|
|
129
|
+
* use `.public('iam')` to use IAM based authorization for unauthenticated users.
|
|
130
|
+
* @param provider the authentication provider - supports "apiKey" or "iam" as valid providers
|
|
131
|
+
* @returns an authorization rule for unauthenticated users
|
|
132
|
+
*/
|
|
133
|
+
public(provider) {
|
|
134
|
+
validateProvider(provider, exports.PublicProviders);
|
|
135
|
+
return authData({
|
|
136
|
+
strategy: 'public',
|
|
137
|
+
provider,
|
|
138
|
+
}, {
|
|
139
|
+
to,
|
|
140
|
+
});
|
|
141
|
+
},
|
|
142
|
+
/**
|
|
143
|
+
* Authorize authenticated users. By default, `.private()` uses an Amazon Cognito user pool based authorization. You can additionally
|
|
144
|
+
* use `.private("iam")` or `.private("oidc")` to use IAM or OIDC based authorization for authenticated users.
|
|
145
|
+
* @param provider the authentication provider - supports "userPools", "iam", or "oidc"
|
|
146
|
+
* @returns an authorization rule for authenticated users
|
|
147
|
+
*/
|
|
148
|
+
private(provider) {
|
|
149
|
+
validateProvider(provider, exports.PrivateProviders);
|
|
150
|
+
return authData({
|
|
151
|
+
strategy: 'private',
|
|
152
|
+
provider,
|
|
153
|
+
}, {
|
|
154
|
+
to,
|
|
155
|
+
});
|
|
156
|
+
},
|
|
157
|
+
/**
|
|
158
|
+
* Authorize access on a per-user (owner) basis. By setting owner-based authorization, a new `owner: a.string()`
|
|
159
|
+
* field will be added to the model to store which user "owns" the item. Upon item creation, the "owner field" is
|
|
160
|
+
* auto-populated with the authenticated user's information. You can which field should be used as the owner field
|
|
161
|
+
* by chaining the * `.inField(...)` method.
|
|
162
|
+
*
|
|
163
|
+
* By default, `.owner()` uses an Amazon Cognito user pool based authorization. You can additionally
|
|
164
|
+
* use `.owner("oidc")` to use OIDC based authentication to designate the owner.
|
|
165
|
+
*
|
|
166
|
+
* To change the specific claim that should be used as the user identifier within the owner field, chain the
|
|
167
|
+
* `.identityClaim(...)` method.
|
|
168
|
+
*
|
|
169
|
+
* @param provider the authentication provider - supports "userPools", "iam", or "oidc"
|
|
170
|
+
* @returns an authorization rule for authenticated users
|
|
171
|
+
*/
|
|
172
|
+
owner(provider) {
|
|
173
|
+
validateProvider(provider, exports.OwnerProviders);
|
|
174
|
+
return authData({
|
|
175
|
+
strategy: 'owner',
|
|
176
|
+
provider,
|
|
177
|
+
groupOrOwnerField: 'owner',
|
|
178
|
+
}, {
|
|
179
|
+
to,
|
|
180
|
+
inField,
|
|
181
|
+
identityClaim,
|
|
182
|
+
});
|
|
183
|
+
},
|
|
184
|
+
/**
|
|
185
|
+
* Authorize access for multi-user / multi-owner access. By setting multi-owner-based authorization, a new `owners: a.string().array()`
|
|
186
|
+
* field will be added to the model to store which users "own" the item. Upon item creation, the "owners field" is
|
|
187
|
+
* auto-populated with the authenticated user's information. To grant other users access to the item, append their user identifier into the `owners` array.
|
|
188
|
+
* You can which field should be used as the owners field by chaining the * `.inField(...)` method.
|
|
189
|
+
*
|
|
190
|
+
* By default, `.multipleOwners()` uses an Amazon Cognito user pool based authorization. You can additionally
|
|
191
|
+
* use `.multipleOwners("oidc")` to use OIDC based authentication to designate the owner.
|
|
192
|
+
*
|
|
193
|
+
* To change the specific claim that should be used as the user identifier within the owners field, chain the
|
|
194
|
+
* `.identityClaim(...)` method.
|
|
195
|
+
*
|
|
196
|
+
* @param provider the authentication provider - supports "userPools", "iam", or "oidc"
|
|
197
|
+
* @returns an authorization rule for authenticated users
|
|
198
|
+
*/
|
|
199
|
+
multipleOwners(provider) {
|
|
200
|
+
validateProvider(provider, exports.OwnerProviders);
|
|
201
|
+
return authData({
|
|
202
|
+
strategy: 'owner',
|
|
203
|
+
multiOwner: true,
|
|
204
|
+
provider,
|
|
205
|
+
groupOrOwnerField: 'owner',
|
|
206
|
+
}, {
|
|
207
|
+
to,
|
|
208
|
+
inField,
|
|
209
|
+
identityClaim,
|
|
210
|
+
});
|
|
211
|
+
},
|
|
212
|
+
/**
|
|
213
|
+
* Authorize a specific user group. Provide the name of the specific user group to have access.
|
|
214
|
+
*
|
|
215
|
+
* By default, `.specificGroup()` uses an Amazon Cognito user pool based authorization. You can additionally
|
|
216
|
+
* use `.specificGroup("oidc")` to use OIDC based authentication to designate the user group.
|
|
217
|
+
*
|
|
218
|
+
* To change the specific claim that should be used as the user group identifier, chain the
|
|
219
|
+
* `.groupClaim(...)` method.
|
|
220
|
+
* @param group the name of the group to authorize
|
|
221
|
+
* @param provider the authentication provider - supports "userPools" or "oidc"
|
|
222
|
+
* @returns an authorization rule to grant access by a specific group
|
|
223
|
+
*/
|
|
224
|
+
specificGroup(group, provider) {
|
|
225
|
+
return authData({
|
|
226
|
+
strategy: 'groups',
|
|
227
|
+
provider,
|
|
228
|
+
groups: [group],
|
|
229
|
+
}, {
|
|
230
|
+
to,
|
|
231
|
+
withClaimIn,
|
|
232
|
+
});
|
|
233
|
+
},
|
|
234
|
+
/**
|
|
235
|
+
* Authorize multiple specific user groups. Provide the names of the specific user groups to have access.
|
|
236
|
+
*
|
|
237
|
+
* By default, `.specificGroups()` uses an Amazon Cognito user pool based authorization. You can additionally
|
|
238
|
+
* use `.specificGroups("oidc")` to use OIDC based authentication to designate the user group.
|
|
239
|
+
*
|
|
240
|
+
* To change the specific claim that should be used as the user group identifier, chain the
|
|
241
|
+
* `.groupClaim(...)` method.
|
|
242
|
+
* @param groups the names of the group to authorize defined as an array
|
|
243
|
+
* @param provider the authentication provider - supports "userPools" or "oidc"
|
|
244
|
+
* @returns an authorization rule to grant access by a specific group
|
|
245
|
+
*/
|
|
246
|
+
specificGroups(groups, provider) {
|
|
247
|
+
return authData({
|
|
248
|
+
strategy: 'groups',
|
|
249
|
+
provider,
|
|
250
|
+
groups,
|
|
251
|
+
}, {
|
|
252
|
+
to,
|
|
253
|
+
withClaimIn,
|
|
254
|
+
});
|
|
255
|
+
},
|
|
256
|
+
/**
|
|
257
|
+
* Authorize if a user is part of a group defined in a data model field.
|
|
258
|
+
*
|
|
259
|
+
* By default, `.groupDefinedIn()` uses an Amazon Cognito user pool based authorization. You can additionally
|
|
260
|
+
* use `.groupDefinedIn("oidc")` to use OIDC based authentication to designate the user group.
|
|
261
|
+
*
|
|
262
|
+
* To change the specific claim that should be used as the user group identifier within the groups field, chain the
|
|
263
|
+
* `.groupClaim(...)` method.
|
|
264
|
+
* @param groupsField the field that should store the authorized user group information
|
|
265
|
+
* @param provider the authentication provider - supports "userPools" or "oidc"
|
|
266
|
+
* @returns an authorization rule to grant access by a specific group
|
|
267
|
+
*/
|
|
268
|
+
groupDefinedIn(groupsField, provider) {
|
|
269
|
+
return authData({
|
|
270
|
+
strategy: 'groups',
|
|
271
|
+
provider,
|
|
272
|
+
groupOrOwnerField: groupsField,
|
|
273
|
+
}, {
|
|
274
|
+
to,
|
|
275
|
+
});
|
|
276
|
+
},
|
|
277
|
+
/**
|
|
278
|
+
* Authorize if a user is part of a one of the groups defined in a data model field.
|
|
279
|
+
*
|
|
280
|
+
* By default, `.groupsDefinedIn()` uses an Amazon Cognito user pool based authorization. You can additionally
|
|
281
|
+
* use `.groupsDefinedIn("oidc")` to use OIDC based authentication to designate the user group.
|
|
282
|
+
*
|
|
283
|
+
* To change the specific claim that should be used as the user group identifier within the groups field, chain the
|
|
284
|
+
* `.groupClaim(...)` method.
|
|
285
|
+
* @param groupsField the field that should store the list of authorized user groups
|
|
286
|
+
* @param provider the authentication provider - supports "userPools" or "oidc"
|
|
287
|
+
* @returns an authorization rule to grant access by a specific group
|
|
288
|
+
*/
|
|
289
|
+
groupsDefinedIn(groupsField, provider) {
|
|
290
|
+
return authData({
|
|
291
|
+
strategy: 'groups',
|
|
292
|
+
provider,
|
|
293
|
+
groupOrOwnerField: groupsField,
|
|
294
|
+
multiOwner: true,
|
|
295
|
+
}, {
|
|
296
|
+
to,
|
|
297
|
+
});
|
|
298
|
+
},
|
|
299
|
+
custom(provider) {
|
|
300
|
+
return authData({
|
|
301
|
+
strategy: 'custom',
|
|
302
|
+
provider,
|
|
303
|
+
}, {
|
|
304
|
+
to,
|
|
305
|
+
});
|
|
306
|
+
},
|
|
307
|
+
};
|
|
308
|
+
const accessData = (authorization) => authorization[__data];
|
|
309
|
+
exports.accessData = accessData;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type Prettify, __modelMeta__ } from '@aws-amplify/data-schema-types';
|
|
2
|
+
import type { ModelSchema } from './ModelSchema';
|
|
3
|
+
import type { ResolveSchema, SchemaTypes } from './MappedTypes/ResolveSchema';
|
|
4
|
+
import type { ResolveFieldProperties } from './MappedTypes/ResolveFieldProperties';
|
|
5
|
+
import type { ModelIdentifier, RelationalMetadata } from './MappedTypes/ModelMetadata';
|
|
6
|
+
import type { ExtractNonModelTypes, NonModelTypesShape } from './MappedTypes/ExtractNonModelTypes';
|
|
7
|
+
export type ClientSchema<Schema extends ModelSchema<any>> = InternalClientSchema<Schema>;
|
|
8
|
+
/**
|
|
9
|
+
* Types for unwrapping generic type args into client-consumable types
|
|
10
|
+
*
|
|
11
|
+
* @typeParam Schema - Type Beast schema type
|
|
12
|
+
*
|
|
13
|
+
* The following params are used solely as variables in order to simplify mapped type usage.
|
|
14
|
+
* They should not receive external type args.
|
|
15
|
+
*
|
|
16
|
+
* @internal @typeParam ResolvedSchema - Schema/Models/Fields structure with generic type args extracted
|
|
17
|
+
* @internal @typeParam IdentifierMeta - Stores model identifier
|
|
18
|
+
* @internal @typeParam ResolvedFields - optionality enforced on nullable types (+?); These are the client-facing types used for CRUDL response shapes
|
|
19
|
+
*
|
|
20
|
+
* @internal @typeParam Meta - Stores schema metadata: identifier, relationship metadata;
|
|
21
|
+
* used by `API.generateClient` to craft strongly typed mutation inputs; hidden from customer-facing types behind __modelMeta__ symbol
|
|
22
|
+
*
|
|
23
|
+
*/
|
|
24
|
+
type InternalClientSchema<Schema extends ModelSchema<any>, NonModelTypes extends NonModelTypesShape = ExtractNonModelTypes<Schema>, ResolvedSchema = ResolveSchema<Schema>, IdentifierMeta extends Record<string, any> = ModelIdentifier<SchemaTypes<Schema>>, ResolvedFields extends Record<string, unknown> = ResolveFieldProperties<Schema, NonModelTypes>, RelationshipMeta = RelationalMetadata<ResolvedSchema, ResolvedFields, IdentifierMeta>, Meta = IdentifierMeta & RelationshipMeta & NonModelTypes> = Prettify<ResolvedFields & {
|
|
25
|
+
[__modelMeta__]: Meta;
|
|
26
|
+
}>;
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Brand } from '@aws-amplify/data-schema-types';
|
|
2
|
+
import { ModelField, InternalField, ModelFieldTypeParamOuter } from './ModelField';
|
|
3
|
+
/**
|
|
4
|
+
* Custom Types
|
|
5
|
+
*
|
|
6
|
+
* can be defined in-line to strongly type object types
|
|
7
|
+
*
|
|
8
|
+
*/
|
|
9
|
+
export type CustomTypeAllowedModifiers = 'authorization' | 'array' | 'required';
|
|
10
|
+
type ModelFields = Record<string, ModelField<ModelFieldTypeParamOuter, CustomTypeAllowedModifiers, any>>;
|
|
11
|
+
type InternalModelFields = Record<string, InternalField>;
|
|
12
|
+
type CustomTypeData = {
|
|
13
|
+
fields: ModelFields;
|
|
14
|
+
type: 'customType';
|
|
15
|
+
};
|
|
16
|
+
type InternalCustomTypeData = CustomTypeData & {
|
|
17
|
+
fields: InternalModelFields;
|
|
18
|
+
};
|
|
19
|
+
export type CustomTypeParamShape = {
|
|
20
|
+
fields: ModelFields;
|
|
21
|
+
};
|
|
22
|
+
export type CustomType<T extends CustomTypeParamShape> = Brand<T, 'customType'>;
|
|
23
|
+
/**
|
|
24
|
+
* Internal representation of CustomType that exposes the `data` property.
|
|
25
|
+
* Used at buildtime.
|
|
26
|
+
*/
|
|
27
|
+
export type InternalCustomType = CustomType<any> & {
|
|
28
|
+
data: InternalCustomTypeData;
|
|
29
|
+
};
|
|
30
|
+
export declare function customType<T extends ModelFields>(fields: T): CustomType<{
|
|
31
|
+
fields: T;
|
|
32
|
+
}>;
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.customType = void 0;
|
|
4
|
+
function _customType(fields) {
|
|
5
|
+
const data = {
|
|
6
|
+
fields,
|
|
7
|
+
type: 'customType',
|
|
8
|
+
};
|
|
9
|
+
return { data };
|
|
10
|
+
}
|
|
11
|
+
function customType(fields) {
|
|
12
|
+
return _customType(fields);
|
|
13
|
+
}
|
|
14
|
+
exports.customType = customType;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Brand } from '@aws-amplify/data-schema-types';
|
|
2
|
+
export type EnumTypeParamShape = {
|
|
3
|
+
type: 'enum';
|
|
4
|
+
values: readonly string[];
|
|
5
|
+
};
|
|
6
|
+
export type EnumType<T extends EnumTypeParamShape> = Brand<T, 'enum'>;
|
|
7
|
+
type EnumTypeArgFactory<Values extends readonly string[]> = {
|
|
8
|
+
type: 'enum';
|
|
9
|
+
values: Values;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* this type param pattern allows us to infer literal type values from the array without using the `as const` suffix
|
|
13
|
+
*/
|
|
14
|
+
export declare function enumType<Value extends string, T extends readonly Value[]>(values: T): EnumType<EnumTypeArgFactory<T>>;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.enumType = void 0;
|
|
4
|
+
function _enum(values) {
|
|
5
|
+
const data = {
|
|
6
|
+
type: 'enum',
|
|
7
|
+
values,
|
|
8
|
+
};
|
|
9
|
+
return data;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* this type param pattern allows us to infer literal type values from the array without using the `as const` suffix
|
|
13
|
+
*/
|
|
14
|
+
function enumType(values) {
|
|
15
|
+
return _enum(values);
|
|
16
|
+
}
|
|
17
|
+
exports.enumType = enumType;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { CustomType, CustomTypeParamShape } from '../CustomType';
|
|
2
|
+
import type { EnumType, EnumTypeParamShape } from '../EnumType';
|
|
3
|
+
import type { SchemaTypes, ModelTypes } from './ResolveSchema';
|
|
4
|
+
import type { ModelField } from '../ModelField';
|
|
5
|
+
export type NonModelTypesShape = {
|
|
6
|
+
enums: Record<string, EnumType<any>>;
|
|
7
|
+
customTypes: Record<string, any>;
|
|
8
|
+
};
|
|
9
|
+
export type ExtractNonModelTypes<Schema> = ResolveNonModelFields<ResolveNonModelTypes<Schema, ExtractImplicitNonModelTypes<Schema>>>;
|
|
10
|
+
/**
|
|
11
|
+
* Pulls out implicit, i.e. field-level non-model types from Schema
|
|
12
|
+
*/
|
|
13
|
+
type ExtractImplicitNonModelTypes<Schema, ResolvedModels = ModelTypes<SchemaTypes<Schema>>, ResolvedModelKeys extends keyof ResolvedModels = keyof ResolvedModels> = {
|
|
14
|
+
[Field in keyof ResolvedModels[ResolvedModelKeys] as ResolvedModels[ResolvedModelKeys][Field] extends EnumType<EnumTypeParamShape> ? `${Capitalize<Field & string>}` : ResolvedModels[ResolvedModelKeys][Field] extends CustomType<CustomTypeParamShape> ? `${Capitalize<Field & string>}` : never]: ResolvedModels[ResolvedModelKeys][Field];
|
|
15
|
+
};
|
|
16
|
+
type ResolveNonModelTypes<Schema, Extracted, ResolvedSchema = SchemaTypes<Schema> & Extracted> = {
|
|
17
|
+
enums: {
|
|
18
|
+
[Model in keyof ResolvedSchema as ResolvedSchema[Model] extends EnumType<EnumTypeParamShape> ? Model : never]: ResolvedSchema[Model] extends EnumType<infer R extends EnumTypeParamShape> ? R['values'][number] : never;
|
|
19
|
+
};
|
|
20
|
+
customTypes: {
|
|
21
|
+
[Model in keyof ResolvedSchema as ResolvedSchema[Model] extends CustomType<CustomTypeParamShape> ? Model : never]: ResolvedSchema[Model] extends CustomType<infer R extends CustomTypeParamShape> ? R['fields'] : never;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
type ResolveNonModelFields<T extends NonModelTypesShape, CustomTypes = T['customTypes']> = {
|
|
25
|
+
enums: T['enums'];
|
|
26
|
+
customTypes: {
|
|
27
|
+
[CustomType in keyof CustomTypes]: {
|
|
28
|
+
[FieldProp in keyof CustomTypes[CustomType]]: CustomTypes[CustomType][FieldProp] extends ModelField<infer R, any, any> ? R : never;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { ResolveSchema } from './ResolveSchema';
|
|
2
|
+
import { Prettify, UnionToIntersection } from '@aws-amplify/data-schema-types';
|
|
3
|
+
import { ModelRelationalFieldParamShape, ModelRelationshipTypes } from '../ModelRelationalField';
|
|
4
|
+
export type AllImpliedFKs<ResolvedSchema, Identifiers extends Record<string, {
|
|
5
|
+
identifier: string;
|
|
6
|
+
}>, Schema extends Record<any, any> = ResolvedSchema extends ResolveSchema<any> ? ResolvedSchema : object, DenormalizedSchema extends Denormalized<Schema, Identifiers> = Denormalized<Schema, Identifiers>, AllModels = DenormalizedSchema['model'] | DenormalizedSchema['relationName']> = {
|
|
7
|
+
[K in Extract<AllModels, string>]: ImpliedFKs<ResolvedSchema, Identifiers, K> extends never ? object : ImpliedFKs<ResolvedSchema, Identifiers, K>;
|
|
8
|
+
};
|
|
9
|
+
export type Denormalized<Schema extends Record<any, any>, Identifiers extends Record<string, {
|
|
10
|
+
identifier: string;
|
|
11
|
+
}>> = {
|
|
12
|
+
[ModelName in keyof Schema]: {
|
|
13
|
+
[FieldName in keyof Schema[ModelName]]: Prettify<{
|
|
14
|
+
model: ModelName;
|
|
15
|
+
identifier: IdentifierFields<Identifiers, ModelName>;
|
|
16
|
+
field: FieldName;
|
|
17
|
+
type: Schema[ModelName][FieldName];
|
|
18
|
+
} & RelatedModelFields<Schema[ModelName][FieldName], Identifiers>>;
|
|
19
|
+
}[keyof Schema[ModelName]];
|
|
20
|
+
}[keyof Schema];
|
|
21
|
+
export type ImpliedFKs<ResolvedSchema, Identifiers extends Record<string, {
|
|
22
|
+
identifier: string;
|
|
23
|
+
}>, ModelName, Schema extends Record<any, any> = ResolvedSchema extends ResolveSchema<any> ? ResolvedSchema : object, DenormalizedSchema = Denormalized<Schema, Identifiers>, HasMany_Model = Extract<DenormalizedSchema, {
|
|
24
|
+
relatedModel: ModelName;
|
|
25
|
+
relationshipType: ModelRelationshipTypes.hasMany;
|
|
26
|
+
}>, HasOne_Model = Extract<DenormalizedSchema, {
|
|
27
|
+
model: ModelName;
|
|
28
|
+
relationshipType: ModelRelationshipTypes.hasOne;
|
|
29
|
+
}>, Model_BelongsTo = Exclude<Extract<DenormalizedSchema, {
|
|
30
|
+
model: ModelName;
|
|
31
|
+
relationshipType: ModelRelationshipTypes.belongsTo;
|
|
32
|
+
}>, ImpliedHasManyBelongsTos<HasMany_Model>>, ManyToManys = Extract<DenormalizedSchema, {
|
|
33
|
+
relationName: ModelName;
|
|
34
|
+
relationshipType: ModelRelationshipTypes.manyToMany;
|
|
35
|
+
}>, InferredFields = HasMany_Model_Keys<Schema, HasMany_Model> | HasOne_Model_Keys<Schema, HasOne_Model> | Model_BelongsTo_Keys<Schema, Model_BelongsTo> | ManyToManyKeys<Schema, ManyToManys>> = unknown extends UnionToIntersection<InferredFields> ? never : Prettify<UnionToIntersection<InferredFields>>;
|
|
36
|
+
type IdentifierFields<Identifiers extends Record<string, {
|
|
37
|
+
identifier: string;
|
|
38
|
+
}>, ModelName> = ModelName extends keyof Identifiers ? Identifiers[ModelName]['identifier'] : 'id';
|
|
39
|
+
type RelatedModelFields<ModelField, Identifiers extends Record<string, {
|
|
40
|
+
identifier: string;
|
|
41
|
+
}>> = ModelField extends ModelRelationalFieldParamShape ? {
|
|
42
|
+
relatedModel: ModelField['relatedModel'];
|
|
43
|
+
relationshipType: ModelField['relationshipType'];
|
|
44
|
+
relationName: ModelField['relationName'];
|
|
45
|
+
relatedModelIdentifier: IdentifierFields<Identifiers, ModelField['relatedModel']>;
|
|
46
|
+
} : {
|
|
47
|
+
relatedModel: undefined;
|
|
48
|
+
relationshipType: undefined;
|
|
49
|
+
relationName: undefined;
|
|
50
|
+
relatedModelIdentifier: never;
|
|
51
|
+
};
|
|
52
|
+
type FieldWithRelationship = {
|
|
53
|
+
model: string;
|
|
54
|
+
identifier: string;
|
|
55
|
+
field: string;
|
|
56
|
+
relatedModel: string;
|
|
57
|
+
relatedModelIdentifier: string;
|
|
58
|
+
relationName: string | undefined;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* I.e., creates a "matcher" to identify the belongsTo entries that correspond with
|
|
62
|
+
* the given hasMany relationship.
|
|
63
|
+
*
|
|
64
|
+
* The `belongsTo` side of these relationships can be ignored. The FK comes from the
|
|
65
|
+
* `hasMany` side of the relationship.
|
|
66
|
+
*/
|
|
67
|
+
type ImpliedHasManyBelongsTos<Relationship> = Relationship extends FieldWithRelationship ? {
|
|
68
|
+
model: Relationship['relatedModel'];
|
|
69
|
+
} : never;
|
|
70
|
+
type FKName<Model extends string, Field extends string, Identifier extends string> = `${Uncapitalize<Model>}${Capitalize<Field>}${Capitalize<Identifier>}`;
|
|
71
|
+
type HasMany_Model_Keys<Schema extends Record<any, any>, RelDef> = RelDef extends FieldWithRelationship ? {
|
|
72
|
+
[IDField in RelDef['identifier'] as FKName<RelDef['model'], RelDef['field'], IDField>]?: IDField extends keyof Schema[RelDef['model']] ? Schema[RelDef['model']][IDField] : string;
|
|
73
|
+
} : never;
|
|
74
|
+
type HasOne_Model_Keys<Schema extends Record<any, any>, RelDef> = RelDef extends FieldWithRelationship ? {
|
|
75
|
+
[IDField in RelDef['relatedModelIdentifier'] as FKName<RelDef['model'], RelDef['field'], IDField>]?: IDField extends keyof Schema[RelDef['relatedModel']] ? Schema[RelDef['relatedModel']][IDField] : string;
|
|
76
|
+
} : never;
|
|
77
|
+
type Model_BelongsTo_Keys<Schema extends Record<any, any>, RelDef> = RelDef extends FieldWithRelationship ? {
|
|
78
|
+
[IDField in RelDef['relatedModelIdentifier'] as FKName<RelDef['model'], RelDef['field'], IDField>]?: IDField extends keyof Schema[RelDef['model']] ? Schema[RelDef['model']][IDField] : string;
|
|
79
|
+
} : never;
|
|
80
|
+
type ManyToManyKeys<Schema extends Record<any, any>, RelDef> = RelDef extends FieldWithRelationship ? {
|
|
81
|
+
[IDField in RelDef['identifier'] as FKName<RelDef['model'], '', IDField>]?: IDField extends keyof Schema[RelDef['model']] ? Schema[RelDef['model']][IDField] : string;
|
|
82
|
+
} : never;
|
|
83
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
type DefaultIdentifierFields = {
|
|
2
|
+
readonly id: string;
|
|
3
|
+
};
|
|
4
|
+
type DefaultTimestampFields = {
|
|
5
|
+
readonly createdAt: string;
|
|
6
|
+
readonly updatedAt: string;
|
|
7
|
+
};
|
|
8
|
+
type InitialImplicitFields<Identifier> = Identifier extends 'id' ? DefaultIdentifierFields & DefaultTimestampFields : DefaultTimestampFields;
|
|
9
|
+
/**
|
|
10
|
+
* @returns true if a string union `ExplicitFieldNames` contains a given string `FieldName`
|
|
11
|
+
*/
|
|
12
|
+
type FieldExists<ExplicitFieldNames extends string, FieldName extends string> = Extract<ExplicitFieldNames, FieldName> extends never ? false : true;
|
|
13
|
+
/**
|
|
14
|
+
* @returns union of explicitly defined field names for a model
|
|
15
|
+
*/
|
|
16
|
+
type GetModelFieldNames<FlatModel> = FlatModel extends Record<infer R, any> ? R : never;
|
|
17
|
+
/**
|
|
18
|
+
* Generate Record type containing all implicit fields for a given model
|
|
19
|
+
*/
|
|
20
|
+
type ImplicitFields<FlatModel, Identifier, ModelFieldNames = GetModelFieldNames<FlatModel>> = {
|
|
21
|
+
[ImplicitField in keyof InitialImplicitFields<Identifier> as FieldExists<ModelFieldNames & string, ImplicitField & string> extends true ? never : ImplicitField]: InitialImplicitFields<Identifier>[ImplicitField];
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* @returns intersection of explicit and implicit model fields
|
|
25
|
+
*/
|
|
26
|
+
type InjectDefaultFieldsForModel<FlatModel, ModelIdentifier> = FlatModel & ImplicitFields<FlatModel, 'identifier' extends keyof ModelIdentifier ? ModelIdentifier['identifier'] : never>;
|
|
27
|
+
/**
|
|
28
|
+
* Mapped type that injects default implicit fields for a model
|
|
29
|
+
* 1. Add "id" field to models with neither an explicit field named "id" nor a custom identifier (`.identifier(['some-field'])`)
|
|
30
|
+
* 2. Add default timestamp fields ("createdAt", "updatedAt") unless they're already explicitly defined
|
|
31
|
+
*
|
|
32
|
+
* @typeParam FlattenedSchema - resolved schema type (TODO: add detail/example/link to type)
|
|
33
|
+
*/
|
|
34
|
+
export type InjectImplicitModelFields<FlattenedSchema, IdentifierMeta> = {
|
|
35
|
+
[ModelName in keyof FlattenedSchema]: InjectDefaultFieldsForModel<FlattenedSchema[ModelName], ModelName extends keyof IdentifierMeta ? IdentifierMeta[ModelName] : object>;
|
|
36
|
+
};
|
|
37
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type UnionToIntersection, type ExcludeEmpty } from '@aws-amplify/data-schema-types';
|
|
2
|
+
import type { ModelType } from '../ModelType';
|
|
3
|
+
import type { ModelRelationalFieldParamShape } from '../ModelRelationalField';
|
|
4
|
+
export type ModelIdentifier<T> = {
|
|
5
|
+
[Property in keyof T]: T[Property] extends ModelType<infer R, any> ? R['identifier'] extends any[] ? {
|
|
6
|
+
identifier: R['identifier'][number];
|
|
7
|
+
} : never : never;
|
|
8
|
+
};
|
|
9
|
+
export type RelationalMetadata<ResolvedSchema, ResolvedFields extends Record<string, unknown>, IdentifierMeta extends Record<string, any>> = UnionToIntersection<ExcludeEmpty<{
|
|
10
|
+
[ModelName in keyof ResolvedSchema]: {
|
|
11
|
+
[Field in keyof ResolvedSchema[ModelName] as ResolvedSchema[ModelName][Field] extends ModelRelationalFieldParamShape ? ResolvedSchema[ModelName][Field]['relationshipType'] extends 'hasMany' ? ResolvedSchema[ModelName][Field]['relatedModel'] : ResolvedSchema[ModelName][Field]['relationshipType'] extends 'hasOne' | 'belongsTo' ? ModelName : ResolvedSchema[ModelName][Field]['relationshipType'] extends 'manyToMany' ? ResolvedSchema[ModelName][Field]['relationName'] extends string ? ResolvedSchema[ModelName][Field]['relationName'] : never : never : never]: ResolvedSchema[ModelName][Field] extends ModelRelationalFieldParamShape ? ResolvedSchema[ModelName][Field] extends ModelRelationalFieldParamShape ? ResolvedSchema[ModelName][Field]['relationshipType'] extends 'manyToMany' | 'hasMany' ? {
|
|
12
|
+
relationalInputFields: Partial<Record<`${Uncapitalize<ModelName & string>}`, NormalizeInputFields<ResolvedFields[ModelName & string], ExtractModelIdentifier<ModelName, IdentifierMeta>>>>;
|
|
13
|
+
} : {
|
|
14
|
+
relationalInputFields: Partial<Record<Field, NormalizeInputFields<ResolvedFields[ResolvedSchema[ModelName][Field]['relatedModel']], ExtractModelIdentifier<`${Capitalize<Field & string>}`, IdentifierMeta>>>>;
|
|
15
|
+
} : never : never;
|
|
16
|
+
};
|
|
17
|
+
}[keyof ResolvedSchema]>>;
|
|
18
|
+
type ExtractModelIdentifier<ModelName, IdentifierMeta> = ModelName extends keyof IdentifierMeta ? IdentifierMeta[ModelName] : never;
|
|
19
|
+
type NormalizeInputFields<ModelFields, IdentifierMeta extends Record<string, any>> = Partial<Omit<ModelFields, IdentifierMeta['identifier']>> & Required<Pick<ModelFields, IdentifierMeta['identifier']>>;
|
|
20
|
+
export {};
|