@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.
Files changed (43) hide show
  1. package/dist/cjs/ModelSchema.js +19 -0
  2. package/dist/cjs/ModelSchema.js.map +1 -1
  3. package/dist/cjs/SchemaProcessor.js +1 -4
  4. package/dist/cjs/SchemaProcessor.js.map +1 -1
  5. package/dist/cjs/util/Brand.js +4 -4
  6. package/dist/cjs/util/Brand.js.map +1 -1
  7. package/dist/cjs/util/usedMethods.js +4 -0
  8. package/dist/cjs/util/usedMethods.js.map +1 -0
  9. package/dist/esm/CustomOperation.d.ts +3 -3
  10. package/dist/esm/CustomType.d.ts +3 -3
  11. package/dist/esm/EnumType.d.ts +7 -9
  12. package/dist/esm/MappedTypes/CustomOperations.d.ts +3 -3
  13. package/dist/esm/MappedTypes/ExtractNonModelTypes.d.ts +4 -4
  14. package/dist/esm/MappedTypes/ResolveFieldProperties.d.ts +2 -2
  15. package/dist/esm/MappedTypes/ResolveSchema.d.ts +6 -6
  16. package/dist/esm/ModelField.d.ts +15 -12
  17. package/dist/esm/ModelSchema.d.ts +17 -5
  18. package/dist/esm/ModelSchema.mjs +20 -1
  19. package/dist/esm/ModelSchema.mjs.map +1 -1
  20. package/dist/esm/ModelType.d.ts +16 -12
  21. package/dist/esm/SchemaProcessor.mjs +1 -4
  22. package/dist/esm/SchemaProcessor.mjs.map +1 -1
  23. package/dist/esm/util/Brand.d.ts +1 -2
  24. package/dist/esm/util/Brand.mjs +1 -1
  25. package/dist/esm/util/Brand.mjs.map +1 -1
  26. package/dist/esm/util/usedMethods.d.ts +4 -0
  27. package/dist/esm/util/usedMethods.mjs +2 -0
  28. package/dist/esm/util/usedMethods.mjs.map +1 -0
  29. package/dist/meta/cjs.tsbuildinfo +1 -1
  30. package/package.json +1 -1
  31. package/src/CustomOperation.ts +3 -7
  32. package/src/CustomType.ts +4 -8
  33. package/src/EnumType.ts +16 -22
  34. package/src/MappedTypes/CustomOperations.ts +4 -6
  35. package/src/MappedTypes/ExtractNonModelTypes.ts +39 -40
  36. package/src/MappedTypes/ResolveFieldProperties.ts +2 -2
  37. package/src/MappedTypes/ResolveSchema.ts +18 -21
  38. package/src/ModelField.ts +33 -18
  39. package/src/ModelSchema.ts +51 -13
  40. package/src/ModelType.ts +30 -34
  41. package/src/SchemaProcessor.ts +23 -48
  42. package/src/util/Brand.ts +1 -1
  43. 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 { type Brand, brand } from './util';
4
- import type { ModelField, InternalField } from './ModelField';
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, EnumTypeParamShape } from './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
- | ModelField<any, any, any>
31
+ | BaseModelField
30
32
  | ModelRelationalField<any, string, any, any>
31
33
  | RefType<any, any, any>
32
- | EnumType<EnumTypeParamShape>
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 ModelField<
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<EnumTypeParamShape>
94
+ | EnumType
95
95
  | RefType<RefTypeParamShape, any, any>
96
96
  ? FieldProp
97
- : never]: T['fields'][FieldProp] extends ModelField<infer R, any, any>
97
+ : never]: T['fields'][FieldProp] extends BaseModelField<infer R>
98
98
  ? R
99
- : T['fields'][FieldProp] extends EnumType<infer R>
100
- ? R['values'][number]
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 ModelField<
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 ModelField<infer R, any, any>
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
- K extends keyof ModelType<T> = never,
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
- K | 'identifier'
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
- K | 'secondaryIndexes'
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
- K | 'authorization'
256
+ UsedMethod | 'authorization'
255
257
  >;
256
258
  },
257
- K
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, never | 'identifier'> = ModelType<
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 extends ModelTypeParamShape, any>
283
- ? R['fields']
284
- : never;
280
+ fields: T extends ModelType<infer R, any> ? R['fields'] : never;
285
281
  }
286
282
  : T;
287
283
 
@@ -3,10 +3,10 @@ import {
3
3
  type ModelField,
4
4
  type InternalField,
5
5
  string,
6
- ModelFieldTypeParamOuter,
6
+ type BaseModelField,
7
7
  } from './ModelField';
8
8
  import { type InternalRelationalField } from './ModelRelationalField';
9
- import type { ModelType, InternalModel } from './ModelType';
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: ModelType<any, any>): model is InternalModel {
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: ModelField<any, any>,
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: ModelField<any, any>,
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, ModelField<any, any>>,
531
- additions: Record<string, ModelField<any, any>>,
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, ModelField<any, any>>,
554
- implicitFields: Record<string, ModelField<any, any>> | undefined,
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, ModelField<any, any>>,
578
- implicitFields: Record<string, ModelField<any, any>> | undefined,
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, ModelField<any, any>> = {};
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, ModelField<any, any>>,
803
- authFields: Record<string, ModelField<any, any>>,
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: [string, unknown],
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
- ModelField<any, any>
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
- if (authString == '') {
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
@@ -1,4 +1,4 @@
1
- const brandSymbol = Symbol('brand');
1
+ export const brandSymbol = Symbol('brand');
2
2
 
3
3
  /**
4
4
  * @typeParam BrandStr - String type to brand this object with
@@ -0,0 +1,5 @@
1
+ export type methodKeyOf<o> = {
2
+ [k in keyof o]-?: o[k] extends (...args: never) => unknown ? k : never;
3
+ }[keyof o];
4
+
5
+ export type satisfy<base, t extends base> = t;