@aws-amplify/data-schema 1.1.5 → 1.2.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/ModelSchema.js +19 -0
- package/dist/cjs/ModelSchema.js.map +1 -1
- package/dist/cjs/SchemaProcessor.js +1 -4
- package/dist/cjs/SchemaProcessor.js.map +1 -1
- package/dist/cjs/util/Brand.js +4 -4
- package/dist/cjs/util/Brand.js.map +1 -1
- package/dist/cjs/util/usedMethods.js +4 -0
- package/dist/cjs/util/usedMethods.js.map +1 -0
- package/dist/esm/CustomOperation.d.ts +3 -3
- package/dist/esm/CustomType.d.ts +3 -3
- package/dist/esm/EnumType.d.ts +7 -9
- package/dist/esm/MappedTypes/CustomOperations.d.ts +3 -3
- package/dist/esm/MappedTypes/ExtractNonModelTypes.d.ts +4 -4
- package/dist/esm/MappedTypes/ResolveFieldProperties.d.ts +2 -2
- package/dist/esm/MappedTypes/ResolveSchema.d.ts +6 -6
- package/dist/esm/ModelField.d.ts +15 -12
- package/dist/esm/ModelSchema.d.ts +17 -5
- package/dist/esm/ModelSchema.mjs +20 -1
- package/dist/esm/ModelSchema.mjs.map +1 -1
- package/dist/esm/ModelType.d.ts +16 -12
- package/dist/esm/SchemaProcessor.mjs +1 -4
- package/dist/esm/SchemaProcessor.mjs.map +1 -1
- package/dist/esm/util/Brand.d.ts +1 -2
- package/dist/esm/util/Brand.mjs +1 -1
- package/dist/esm/util/Brand.mjs.map +1 -1
- package/dist/esm/util/usedMethods.d.ts +4 -0
- package/dist/esm/util/usedMethods.mjs +2 -0
- package/dist/esm/util/usedMethods.mjs.map +1 -0
- package/dist/meta/cjs.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/CustomOperation.ts +3 -7
- package/src/CustomType.ts +4 -8
- package/src/EnumType.ts +16 -22
- package/src/MappedTypes/CustomOperations.ts +4 -6
- package/src/MappedTypes/ExtractNonModelTypes.ts +39 -40
- package/src/MappedTypes/ResolveFieldProperties.ts +2 -2
- package/src/MappedTypes/ResolveSchema.ts +18 -21
- package/src/ModelField.ts +33 -18
- package/src/ModelSchema.ts +51 -13
- package/src/ModelType.ts +30 -34
- package/src/SchemaProcessor.ts +23 -48
- package/src/util/Brand.ts +1 -1
- package/src/util/usedMethods.ts +5 -0
package/src/ModelType.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { SetTypeSubArg } from '@aws-amplify/data-schema-types';
|
|
2
2
|
import type { PrimaryIndexIrShape, SecondaryIndexIrShape } from './runtime';
|
|
3
|
-
import {
|
|
4
|
-
import type {
|
|
3
|
+
import { brand } from './util';
|
|
4
|
+
import type { InternalField, BaseModelField } from './ModelField';
|
|
5
5
|
import type {
|
|
6
6
|
ModelRelationalField,
|
|
7
7
|
InternalRelationalField,
|
|
@@ -9,7 +9,7 @@ import type {
|
|
|
9
9
|
} from './ModelRelationalField';
|
|
10
10
|
import { type AllowModifier, type Authorization, allow } from './Authorization';
|
|
11
11
|
import type { RefType, RefTypeParamShape } from './RefType';
|
|
12
|
-
import type { EnumType
|
|
12
|
+
import type { EnumType } from './EnumType';
|
|
13
13
|
import type { CustomType, CustomTypeParamShape } from './CustomType';
|
|
14
14
|
import {
|
|
15
15
|
type ModelIndexType,
|
|
@@ -20,16 +20,18 @@ import type {
|
|
|
20
20
|
PrimaryIndexFieldsToIR,
|
|
21
21
|
SecondaryIndexToIR,
|
|
22
22
|
} from './MappedTypes/MapIndexes';
|
|
23
|
+
import type { brandSymbol } from './util/Brand.js';
|
|
24
|
+
import type { methodKeyOf } from './util/usedMethods.js';
|
|
23
25
|
|
|
24
26
|
const brandName = 'modelType';
|
|
25
27
|
export type deferredRefResolvingPrefix = 'deferredRefResolving:';
|
|
26
28
|
|
|
27
29
|
type ModelFields = Record<
|
|
28
30
|
string,
|
|
29
|
-
|
|
|
31
|
+
| BaseModelField
|
|
30
32
|
| ModelRelationalField<any, string, any, any>
|
|
31
33
|
| RefType<any, any, any>
|
|
32
|
-
| EnumType
|
|
34
|
+
| EnumType
|
|
33
35
|
| CustomType<CustomTypeParamShape>
|
|
34
36
|
>;
|
|
35
37
|
|
|
@@ -78,10 +80,8 @@ export type ExtractSecondaryIndexIRFields<
|
|
|
78
80
|
T extends ModelTypeParamShape,
|
|
79
81
|
RequiredOnly extends boolean = false,
|
|
80
82
|
> = {
|
|
81
|
-
[FieldProp in keyof T['fields'] as T['fields'][FieldProp] extends
|
|
82
|
-
infer R
|
|
83
|
-
any,
|
|
84
|
-
any
|
|
83
|
+
[FieldProp in keyof T['fields'] as T['fields'][FieldProp] extends BaseModelField<
|
|
84
|
+
infer R
|
|
85
85
|
>
|
|
86
86
|
? NonNullable<R> extends string | number
|
|
87
87
|
? RequiredOnly extends false
|
|
@@ -91,26 +91,22 @@ export type ExtractSecondaryIndexIRFields<
|
|
|
91
91
|
: FieldProp
|
|
92
92
|
: never
|
|
93
93
|
: T['fields'][FieldProp] extends
|
|
94
|
-
| EnumType
|
|
94
|
+
| EnumType
|
|
95
95
|
| RefType<RefTypeParamShape, any, any>
|
|
96
96
|
? FieldProp
|
|
97
|
-
: never]: T['fields'][FieldProp] extends
|
|
97
|
+
: never]: T['fields'][FieldProp] extends BaseModelField<infer R>
|
|
98
98
|
? R
|
|
99
|
-
: T['fields'][FieldProp] extends EnumType<infer
|
|
100
|
-
?
|
|
99
|
+
: T['fields'][FieldProp] extends EnumType<infer values>
|
|
100
|
+
? values[number]
|
|
101
101
|
: T['fields'][FieldProp] extends RefType<infer R, any, any>
|
|
102
102
|
? `${deferredRefResolvingPrefix}${R['link']}`
|
|
103
103
|
: never;
|
|
104
104
|
};
|
|
105
105
|
|
|
106
106
|
type ExtractType<T extends ModelTypeParamShape> = {
|
|
107
|
-
[FieldProp in keyof T['fields'] as T['fields'][FieldProp] extends
|
|
108
|
-
any,
|
|
109
|
-
any,
|
|
110
|
-
any
|
|
111
|
-
>
|
|
107
|
+
[FieldProp in keyof T['fields'] as T['fields'][FieldProp] extends BaseModelField
|
|
112
108
|
? FieldProp
|
|
113
|
-
: never]: T['fields'][FieldProp] extends
|
|
109
|
+
: never]: T['fields'][FieldProp] extends BaseModelField<infer R>
|
|
114
110
|
? R
|
|
115
111
|
: never;
|
|
116
112
|
};
|
|
@@ -197,11 +193,17 @@ export type AddRelationshipFieldsToModelTypeFields<
|
|
|
197
193
|
type _ConflictingAuthRules<T extends ModelTypeParamShape> =
|
|
198
194
|
ConflictingAuthRulesMap<T>[keyof ConflictingAuthRulesMap<T>];
|
|
199
195
|
|
|
196
|
+
export type BaseModelType<T extends ModelTypeParamShape = ModelTypeParamShape> =
|
|
197
|
+
ModelType<T, UsableModelTypeKey>;
|
|
198
|
+
|
|
199
|
+
export type UsableModelTypeKey = methodKeyOf<ModelType>;
|
|
200
|
+
|
|
200
201
|
export type ModelType<
|
|
201
|
-
T extends ModelTypeParamShape,
|
|
202
|
-
|
|
202
|
+
T extends ModelTypeParamShape = ModelTypeParamShape,
|
|
203
|
+
UsedMethod extends UsableModelTypeKey = never,
|
|
203
204
|
> = Omit<
|
|
204
205
|
{
|
|
206
|
+
[brandSymbol]: typeof brandName;
|
|
205
207
|
identifier<
|
|
206
208
|
PrimaryIndexFields = ExtractSecondaryIndexIRFields<T, true>,
|
|
207
209
|
PrimaryIndexPool extends string = keyof PrimaryIndexFields & string,
|
|
@@ -214,7 +216,7 @@ export type ModelType<
|
|
|
214
216
|
identifier: ID,
|
|
215
217
|
): ModelType<
|
|
216
218
|
SetTypeSubArg<T, 'identifier', PrimaryIndexIR>,
|
|
217
|
-
|
|
219
|
+
UsedMethod | 'identifier'
|
|
218
220
|
>;
|
|
219
221
|
secondaryIndexes<
|
|
220
222
|
const SecondaryIndexFields = ExtractSecondaryIndexIRFields<T>,
|
|
@@ -243,7 +245,7 @@ export type ModelType<
|
|
|
243
245
|
) => Indexes,
|
|
244
246
|
): ModelType<
|
|
245
247
|
SetTypeSubArg<T, 'secondaryIndexes', IndexesIR>,
|
|
246
|
-
|
|
248
|
+
UsedMethod | 'secondaryIndexes'
|
|
247
249
|
>;
|
|
248
250
|
authorization<AuthRuleType extends Authorization<any, any, any>>(
|
|
249
251
|
callback: (
|
|
@@ -251,22 +253,18 @@ export type ModelType<
|
|
|
251
253
|
) => AuthRuleType | AuthRuleType[],
|
|
252
254
|
): ModelType<
|
|
253
255
|
SetTypeSubArg<T, 'authorization', AuthRuleType[]>,
|
|
254
|
-
|
|
256
|
+
UsedMethod | 'authorization'
|
|
255
257
|
>;
|
|
256
258
|
},
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
Brand<typeof brandName>;
|
|
259
|
+
UsedMethod
|
|
260
|
+
>;
|
|
260
261
|
|
|
261
262
|
/**
|
|
262
263
|
* External representation of Model Type that exposes the `relationships` modifier.
|
|
263
264
|
* Used on the complete schema object.
|
|
264
265
|
*/
|
|
265
266
|
export type SchemaModelType<
|
|
266
|
-
T extends ModelType<ModelTypeParamShape,
|
|
267
|
-
ModelTypeParamShape,
|
|
268
|
-
never | 'identifier'
|
|
269
|
-
>,
|
|
267
|
+
T extends BaseModelType = ModelType<ModelTypeParamShape, 'identifier'>,
|
|
270
268
|
ModelName extends string = string,
|
|
271
269
|
IsRDS extends boolean = false,
|
|
272
270
|
> = IsRDS extends true
|
|
@@ -279,9 +277,7 @@ export type SchemaModelType<
|
|
|
279
277
|
>(
|
|
280
278
|
relationships: Param,
|
|
281
279
|
): Record<ModelName, Param>;
|
|
282
|
-
fields: T extends ModelType<infer R
|
|
283
|
-
? R['fields']
|
|
284
|
-
: never;
|
|
280
|
+
fields: T extends ModelType<infer R, any> ? R['fields'] : never;
|
|
285
281
|
}
|
|
286
282
|
: T;
|
|
287
283
|
|
package/src/SchemaProcessor.ts
CHANGED
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
type ModelField,
|
|
4
4
|
type InternalField,
|
|
5
5
|
string,
|
|
6
|
-
|
|
6
|
+
type BaseModelField,
|
|
7
7
|
} from './ModelField';
|
|
8
8
|
import { type InternalRelationalField } from './ModelRelationalField';
|
|
9
|
-
import type {
|
|
9
|
+
import type { InternalModel } from './ModelType';
|
|
10
10
|
import type { InternalModelIndexType } from './ModelIndex';
|
|
11
11
|
import {
|
|
12
12
|
type Authorization,
|
|
@@ -25,11 +25,7 @@ import {
|
|
|
25
25
|
} from '@aws-amplify/data-schema-types';
|
|
26
26
|
import type { InternalRef, RefType } from './RefType';
|
|
27
27
|
import type { EnumType } from './EnumType';
|
|
28
|
-
import type {
|
|
29
|
-
CustomType,
|
|
30
|
-
CustomTypeAllowedModifiers,
|
|
31
|
-
CustomTypeParamShape,
|
|
32
|
-
} from './CustomType';
|
|
28
|
+
import type { CustomType, CustomTypeParamShape } from './CustomType';
|
|
33
29
|
import { type InternalCustom, CustomOperationNames } from './CustomOperation';
|
|
34
30
|
import { Brand, getBrand } from './util';
|
|
35
31
|
import {
|
|
@@ -57,7 +53,7 @@ type CustomOperationFields = {
|
|
|
57
53
|
subscriptions: string[];
|
|
58
54
|
};
|
|
59
55
|
|
|
60
|
-
function isInternalModel(model:
|
|
56
|
+
function isInternalModel(model: unknown): model is InternalModel {
|
|
61
57
|
if (
|
|
62
58
|
(model as any).data &&
|
|
63
59
|
!isCustomType(model) &&
|
|
@@ -68,9 +64,7 @@ function isInternalModel(model: ModelType<any, any>): model is InternalModel {
|
|
|
68
64
|
return false;
|
|
69
65
|
}
|
|
70
66
|
|
|
71
|
-
function isEnumType(
|
|
72
|
-
data: any,
|
|
73
|
-
): data is EnumType<{ type: 'enum'; values: string[] }> {
|
|
67
|
+
function isEnumType(data: any): data is EnumType {
|
|
74
68
|
if (data?.type === 'enum') {
|
|
75
69
|
return true;
|
|
76
70
|
}
|
|
@@ -120,13 +114,13 @@ function dataSourceIsRef(
|
|
|
120
114
|
}
|
|
121
115
|
|
|
122
116
|
function isScalarField(
|
|
123
|
-
field:
|
|
117
|
+
field: unknown,
|
|
124
118
|
): field is { data: ScalarFieldDef } & Brand<'modelField'> {
|
|
125
119
|
return isScalarFieldDef((field as any)?.data);
|
|
126
120
|
}
|
|
127
121
|
|
|
128
122
|
function isRefField(
|
|
129
|
-
field:
|
|
123
|
+
field: unknown,
|
|
130
124
|
): field is { data: RefFieldDef } & Brand<'modelField'> {
|
|
131
125
|
return isRefFieldDef((field as any)?.data);
|
|
132
126
|
}
|
|
@@ -501,10 +495,7 @@ function escapeGraphQlString(str: string) {
|
|
|
501
495
|
* @param right
|
|
502
496
|
* @returns
|
|
503
497
|
*/
|
|
504
|
-
function areConflicting(
|
|
505
|
-
left: ModelField<any, any>,
|
|
506
|
-
right: ModelField<any, any>,
|
|
507
|
-
): boolean {
|
|
498
|
+
function areConflicting(left: BaseModelField, right: BaseModelField): boolean {
|
|
508
499
|
// These are the only props we care about for this comparison, because the others
|
|
509
500
|
// (required, arrayRequired, etc) are not specified on auth or FK directives.
|
|
510
501
|
const relevantProps = ['array', 'fieldType'] as const;
|
|
@@ -527,8 +518,8 @@ function areConflicting(
|
|
|
527
518
|
* @param additions A field map to merge in
|
|
528
519
|
*/
|
|
529
520
|
function addFields(
|
|
530
|
-
existing: Record<string,
|
|
531
|
-
additions: Record<string,
|
|
521
|
+
existing: Record<string, BaseModelField>,
|
|
522
|
+
additions: Record<string, BaseModelField>,
|
|
532
523
|
): void {
|
|
533
524
|
for (const [k, addition] of Object.entries(additions)) {
|
|
534
525
|
if (!existing[k]) {
|
|
@@ -550,8 +541,8 @@ function addFields(
|
|
|
550
541
|
* @throws An error when an undefined field is used or when a field is used in a way that conflicts with its generated definition
|
|
551
542
|
*/
|
|
552
543
|
function validateStaticFields(
|
|
553
|
-
existing: Record<string,
|
|
554
|
-
implicitFields: Record<string,
|
|
544
|
+
existing: Record<string, BaseModelField>,
|
|
545
|
+
implicitFields: Record<string, BaseModelField> | undefined,
|
|
555
546
|
) {
|
|
556
547
|
if (implicitFields === undefined) {
|
|
557
548
|
return;
|
|
@@ -574,8 +565,8 @@ function validateStaticFields(
|
|
|
574
565
|
* @throws An error when an undefined field is used or when a field is used in a way that conflicts with its generated definition
|
|
575
566
|
*/
|
|
576
567
|
function validateImpliedFields(
|
|
577
|
-
existing: Record<string,
|
|
578
|
-
implicitFields: Record<string,
|
|
568
|
+
existing: Record<string, BaseModelField>,
|
|
569
|
+
implicitFields: Record<string, BaseModelField> | undefined,
|
|
579
570
|
) {
|
|
580
571
|
if (implicitFields === undefined) {
|
|
581
572
|
return;
|
|
@@ -631,7 +622,7 @@ function validateRefUseCases(
|
|
|
631
622
|
* @returns
|
|
632
623
|
*/
|
|
633
624
|
function calculateAuth(authorization: Authorization<any, any, any>[]) {
|
|
634
|
-
const authFields: Record<string,
|
|
625
|
+
const authFields: Record<string, BaseModelField> = {};
|
|
635
626
|
const rules: string[] = [];
|
|
636
627
|
|
|
637
628
|
for (const entry of authorization) {
|
|
@@ -799,8 +790,8 @@ function capitalize<T extends string>(s: T): Capitalize<T> {
|
|
|
799
790
|
}
|
|
800
791
|
|
|
801
792
|
function processFieldLevelAuthRules(
|
|
802
|
-
fields: Record<string,
|
|
803
|
-
authFields: Record<string,
|
|
793
|
+
fields: Record<string, BaseModelField>,
|
|
794
|
+
authFields: Record<string, BaseModelField>,
|
|
804
795
|
) {
|
|
805
796
|
const fieldLevelAuthRules: {
|
|
806
797
|
[k in keyof typeof fields]: string | null;
|
|
@@ -1168,8 +1159,7 @@ const schemaPreprocessor = (
|
|
|
1168
1159
|
? 'dynamodb'
|
|
1169
1160
|
: 'sql';
|
|
1170
1161
|
|
|
1171
|
-
const staticSchema =
|
|
1172
|
-
schema.data.configuration.database.engine === 'dynamodb' ? false : true;
|
|
1162
|
+
const staticSchema = databaseType === 'sql';
|
|
1173
1163
|
|
|
1174
1164
|
const topLevelTypes = sortTopLevelTypes(Object.entries(schema.data.types));
|
|
1175
1165
|
|
|
@@ -1203,16 +1193,8 @@ const schemaPreprocessor = (
|
|
|
1203
1193
|
|
|
1204
1194
|
const fieldAuthApplicableFields = Object.fromEntries(
|
|
1205
1195
|
Object.entries(fields).filter(
|
|
1206
|
-
(
|
|
1207
|
-
pair
|
|
1208
|
-
): pair is [
|
|
1209
|
-
string,
|
|
1210
|
-
ModelField<
|
|
1211
|
-
ModelFieldTypeParamOuter,
|
|
1212
|
-
CustomTypeAllowedModifiers,
|
|
1213
|
-
any
|
|
1214
|
-
>,
|
|
1215
|
-
] => isModelField(pair[1]),
|
|
1196
|
+
(pair: [string, unknown]): pair is [string, BaseModelField] =>
|
|
1197
|
+
isModelField(pair[1]),
|
|
1216
1198
|
),
|
|
1217
1199
|
);
|
|
1218
1200
|
|
|
@@ -1296,7 +1278,7 @@ const schemaPreprocessor = (
|
|
|
1296
1278
|
} else if (staticSchema) {
|
|
1297
1279
|
const fields = { ...typeDef.data.fields } as Record<
|
|
1298
1280
|
string,
|
|
1299
|
-
|
|
1281
|
+
BaseModelField
|
|
1300
1282
|
>;
|
|
1301
1283
|
|
|
1302
1284
|
validateRefUseCases(typeName, 'model', fields, getRefType);
|
|
@@ -1305,11 +1287,7 @@ const schemaPreprocessor = (
|
|
|
1305
1287
|
const [partitionKey] = identifier;
|
|
1306
1288
|
|
|
1307
1289
|
const { authString, authFields } = calculateAuth(mostRelevantAuthRules);
|
|
1308
|
-
|
|
1309
|
-
throw new Error(
|
|
1310
|
-
`Model \`${typeName}\` is missing authorization rules. Add global rules to the schema or ensure every model has its own rules.`,
|
|
1311
|
-
);
|
|
1312
|
-
}
|
|
1290
|
+
|
|
1313
1291
|
const fieldLevelAuthRules = processFieldLevelAuthRules(
|
|
1314
1292
|
fields,
|
|
1315
1293
|
authFields,
|
|
@@ -1341,10 +1319,7 @@ const schemaPreprocessor = (
|
|
|
1341
1319
|
const model = `type ${typeName} @model(timestamps: null) ${authString}${refersToString}\n{\n ${joined}\n}`;
|
|
1342
1320
|
gqlModels.push(model);
|
|
1343
1321
|
} else {
|
|
1344
|
-
const fields = typeDef.data.fields as Record<
|
|
1345
|
-
string,
|
|
1346
|
-
ModelField<any, any>
|
|
1347
|
-
>;
|
|
1322
|
+
const fields = typeDef.data.fields as Record<string, BaseModelField>;
|
|
1348
1323
|
|
|
1349
1324
|
validateRefUseCases(typeName, 'model', fields, getRefType);
|
|
1350
1325
|
|
package/src/util/Brand.ts
CHANGED