import type { ModelType } from '../ModelType'; import type { GenericModelSchema } from '../ModelSchema'; import type { ModelRelationshipField, ModelRelationshipTypes, RelationTypeFunctionOmitMapping, } from '../ModelRelationshipField'; import type { BaseModelField } from '../ModelField'; import type { CustomType, CustomTypeParamShape } from '../CustomType'; import type { EnumType } from '../EnumType'; import type { RefType, RefTypeParamShape } from '../RefType'; import type { CustomOperation, CustomOperationParamShape, } from '../CustomOperation'; export type ResolveSchema = FieldTypes>>; // TODO: find better name export type SchemaTypes = T extends GenericModelSchema ? T['data']['types'] : never; /** * Resolves model types * * Removes CustomTypes and Enums from resolved schema. * They are extracted separately in ExtractNonModelTypes.ts and * added to ModelMeta in ClientSchema.ts */ export type ModelTypes = { [Model in keyof Schema as Schema[Model] extends | EnumType | CustomType | CustomOperation ? never : Model]: Schema[Model] extends ModelType ? R['fields'] : never; }; /** * Gets the collection of all ModelTypes and CustomTypes which are explicitly * defined in the schema. */ export type ModelAndCustomTypes = { [Model in keyof Schema as Schema[Model] extends | EnumType | CustomOperation ? never : // TODO: This should use BaseModel, but seems to only work because it relies on // omitting extra methods Model]: Schema[Model] extends | ModelType | CustomType ? Schema[Model] : never; }; /** * Resolves field types * * Non-model types are replaced with Refs. Refs remain and are resolved in ResolveFieldProperties.ts */ export type FieldTypes = { [ModelProp in keyof T]: { [FieldProp in keyof T[ModelProp]]: T[ModelProp][FieldProp] extends BaseModelField< // Match the most common field type to improve resolving performance infer R > ? R : T[ModelProp][FieldProp] extends RefType< infer R extends RefTypeParamShape, any, any > ? // leave Ref as-is. We'll resolve it to the linked entity downstream in ResolveFieldProperties R['valueRequired'] extends true ? T[ModelProp][FieldProp] : T[ModelProp][FieldProp] | null : // replace non-model types with Ref T[ModelProp][FieldProp] extends | EnumType | CustomType ? RefType<{ link: `${Capitalize}${Capitalize< FieldProp & string >}`; type: 'ref'; valueRequired: false; array: false; arrayRequired: false; authorization: []; }> | null : // resolve relationship and model fields to the their first type arg T[ModelProp][FieldProp] extends ModelRelationshipField< infer R, string, RelationTypeFunctionOmitMapping, any > ? R : never; }; }; /** * Resolves field types for a CustomType. * * This utility type is needed in addition to the `FieldTypes` utility type as * without checking `ModelRelationshipField` can improve ~5% on resolving performance. * * Non-model types are replaced with Refs. Refs remain and are resolved in ResolveFieldProperties.ts */ export type FieldTypesOfCustomType = { [CustomTypeName in keyof T]: { [FieldProp in keyof T[CustomTypeName]]: T[CustomTypeName][FieldProp] extends BaseModelField< infer R > ? R : T[CustomTypeName][FieldProp] extends RefType< infer R extends RefTypeParamShape, any, any > ? // leave Ref as-is. We'll resolve it to the linked entity downstream in ResolveFieldProperties R['valueRequired'] extends true ? T[CustomTypeName][FieldProp] : T[CustomTypeName][FieldProp] | null : // replace non-model types with Ref T[CustomTypeName][FieldProp] extends | EnumType | CustomType ? RefType<{ link: `${Capitalize}${Capitalize< FieldProp & string >}`; type: 'ref'; valueRequired: false; array: false; arrayRequired: false; authorization: []; }> | null : never; }; };