import type { UnionToIntersection } from '@aws-amplify/data-schema-types'; import type { CustomType, CustomTypeParamShape } from '../CustomType'; import type { EnumType } from '../EnumType'; import type { SchemaTypes, ModelAndCustomTypes, FieldTypesOfCustomType } from './ResolveSchema'; import type { ModelType, ModelTypeParamShape } from '../ModelType'; export type NonModelTypesShape = { enums: Record; customTypes: Record; }; export type ExtractNonModelTypes = ResolveNonModelFields>>; /** * Extract all implicit non-model types a `FieldName: Field` map recursively, * and store them in a flat map. The keys are serialized property path. * * For example, with the following schema structure: * ``` * ExtractAndFlattenImplicitNonModelTypesFromFields< * 'Post', * { * content: string, * status: enum(['reviewing'], ['published']), * meta: customType({ * tag: enum(['internal', 'external']), * views: number * }), * tag: ref('SomeExplicitEnum'), * } * > * ``` * It generates the result as: * ``` * { * PostStatus: enum(['reviewing'], ['published']), * PostMeta: customType({ * tag: enum(['internal', 'external']), * views: number * }), * PostMetaTag: enum(['internal', 'external']), * } * ``` */ export type ExtractAndFlattenImplicitNonModelTypesFromFields = { [FieldProp in keyof Fields as Fields[FieldProp] extends EnumType | CustomType ? FieldProp : never]: (x: NonNullable extends infer FieldType ? FieldType extends EnumType ? { [Key in `${ParentTypeName}${Capitalize}`]: Fields[FieldProp]; } : FieldType extends CustomType ? // recursively extract to the Nested CustomType, and return the ExtractAndFlattenImplicitNonModelTypesFromFields<`${ParentTypeName}${Capitalize}`, CustomTypeShape['fields']> & { [Key in `${ParentTypeName}${Capitalize}`]: Fields[FieldProp]; } : never : never) => void; } extends Record ? Func extends (x: infer P) => void ? P : Record : Record; /** * Pulls out implicit, i.e. field-level non-model types from `ModelType` and * `CustomType` which may contain deeply nested implicit (inline) non-model * types. */ export type ExtractImplicitNonModelTypes>> = UnionToIntersection<{ [Model in keyof Targets]: Targets[Model] extends CustomType ? // extract nested non-model types from it, and include itself ExtractAndFlattenImplicitNonModelTypesFromFields, R['fields']> & { [key in Model]: Targets[Model]; } : Targets[Model] extends ModelType ? ExtractAndFlattenImplicitNonModelTypesFromFields, R['fields']> : Targets[Model]; }[keyof Targets]>; type ResolveNonModelTypes & Extracted> = { enums: { [Model in keyof ResolvedSchema as ResolvedSchema[Model] extends EnumType ? Model : never]: ResolvedSchema[Model] extends EnumType ? values[number] : never; }; customTypes: { [Model in keyof ResolvedSchema as ResolvedSchema[Model] extends CustomType ? Model : never]: ResolvedSchema[Model] extends CustomType ? R['fields'] : never; }; }; type ResolveNonModelFields = { enums: T['enums']; customTypes: FieldTypesOfCustomType; }; export {};