import type { deferredRefResolvingPrefix, ModelTypeParamShape, ModelDefaultIdentifier, DisableOperationsOptions } from '../../ModelType'; import type { ClientSchemaProperty } from './ClientSchemaProperty'; import type { Authorization, ImpliedAuthFields } from '../../Authorization'; import type { SchemaMetadata, ResolveFields, FlatResolveFields } from '../utilities'; import type { IsEmptyStringOrNever, UnionToIntersection, Equal, Prettify } from '@aws-amplify/data-schema-types'; import type { ModelField } from '../../ModelField'; import type { ModelRelationshipField } from '../../ModelRelationshipField'; import type { EnumType } from '../../EnumType'; import type { CustomType, CustomTypeParamShape } from '../../CustomType'; import type { RefType } from '../../RefType'; import type { StringFilter, NumericFilter, ModelPrimaryCompositeKeyInput, PrimaryIndexIrShape, SecondaryIndexIrShape, KindaPretty } from '../../util'; export interface ClientModel, Metadata extends SchemaMetadata, IsRDS extends boolean, T extends ModelTypeParamShape, K extends keyof Bag & string> extends ClientSchemaProperty { __entityType: 'model'; type: KindaPretty>; createType: Prettify>>; updateType: Prettify>>; deleteType: Prettify>; identifier: KindaPretty>; nestedTypes: NestedTypes, T>; secondaryIndexes: IndexQueryMethodsFromIR; __meta: { listOptionsPkParams: ListOptionsPkParams; rawType: T; flatModel: FlatClientFields; disabledOperations: DisabledOpsToMap; }; } /** * Creates a map of disabled operations, expanding coarse-grained ops into fine-grained ones * The map is used in runtime/client/index.ts to Omit any disabled ops from the data-client types * * @example * a.model({...}).disableOperations(['update', 'subscriptions']) * Returns * { * update: true; * onCreate: true; * onUpdate: true; * onDelete: true; * observeQuery: true; * } */ type DisabledOpsToMap> = { [Op in Ops[number] as Op extends 'queries' ? 'list' | 'get' | 'observeQuery' : Op extends 'mutations' ? 'create' | 'update' | 'delete' : Op extends 'subscriptions' ? 'onCreate' | 'onUpdate' | 'onDelete' | 'observeQuery' : Op extends 'list' ? 'list' | 'observeQuery' : Op]: true; }; type ClientFields, Metadata extends SchemaMetadata, IsRDS extends boolean, T extends ModelTypeParamShape> = ResolveFields & If, ImplicitIdentifier> & AuthFields & Omit, keyof ResolveFields>; type FlatClientFields, Metadata extends SchemaMetadata, IsRDS extends boolean, T extends ModelTypeParamShape, ModelName extends keyof Bag & string> = FlatResolveFields & If, ImplicitIdentifier> & AuthFields & Omit, keyof ResolveFields>; type SystemFields = IsRDS extends false ? { readonly createdAt: string; readonly updatedAt: string; } : object; type ModelIdentifier, T extends ModelTypeParamShape> = ResolveIdentifierFields, T['identifier']['pk'] & (T['identifier']['sk'] extends never ? unknown : T['identifier']['sk'])>; /** * Separate util for *injecting* the default implicit identifier for performance * reasons. The full ModelIdentifer util needs to extract types from the fields * matching the explicitly defined field types. Contrast that to **injecting** PK * fields into the model, which is only done specifically when the default of * `readonly id: string` is being injected IF AND ONLY IF another `id` field is * not already present on the model. */ type ImplicitIdentifier = T['identifier']['pk'] extends ModelDefaultIdentifier['pk'] ? 'id' extends keyof T['fields'] ? unknown : ModelDefaultIdentifier['pk'] : unknown; type ResolveIdentifierFields = { [K in keyof IdentifierFields]: K extends keyof Model ? Model[K] : string; }; type If = ConditionResult extends true ? IfTrueValue : IfFalseValue; type Not = T extends true ? false : true; /** * Models with composite PKs defined are expected to contain the model's pk, sk, and sortDirection properties in the `options` param * * @returns an object containing additional `options` properties for models with a composite primary index * */ export type ListOptionsPkParams, T extends ModelTypeParamShape> = T['identifier']['sk'] extends never ? unknown : Prettify>>; type AuthFields, Model extends ModelTypeParamShape> = (Model['authorization'][number] extends never ? SchemaMeta['authFields'] extends never ? object : SchemaMeta['authFields'] : ImpliedAuthFields extends never ? object : ImpliedAuthFields) & ImpliedAuthFieldsFromFields; type ImpliedAuthFieldsFromFields = UnionToIntersection | ModelRelationshipField | RefType ? Auth extends Authorization ? ImpliedAuthFields : object : object : object>; type NestedTypes, T extends ModelTypeParamShape> = { [K in keyof T['fields'] as T['fields'][K] extends EnumType | CustomType ? K : never]: K extends keyof Bag ? { __entityType: T['fields'][K] extends EnumType ? 'enum' : 'customType'; type: Exclude; } : never; }; type IndexQueryMethodsFromIR, Indexes, ModelName extends string, Res = unknown> = Indexes extends [ infer A extends SecondaryIndexIrShape, ...infer B extends SecondaryIndexIrShape[] ] ? IndexQueryMethodsFromIR & Res> : Res; type IndexQueryMethodSignature, Idx extends SecondaryIndexIrShape, ModelName extends string> = Record extends false ? Idx['queryField'] : `list${ModelName}By${Idx['defaultQueryFieldSuffix']}`, { input: IndexQueryInput; }>; /** * Accepts a PrimaryIndexIr or SecondaryIndexIr and returns resolved parameters * * TODO: Get rid of the `deferredRefResolvingPrefix` reference hack. * Instead, just dereference refs as usual? */ export type IndexQueryInput, Idx extends PrimaryIndexIrShape> = { [PKField in keyof Idx['pk']]: Idx['pk'][PKField] extends `${deferredRefResolvingPrefix}${infer R}` ? 'type' extends keyof Bag[R] ? Bag[R]['type'] : never : Idx['pk'][PKField]; } & (Idx['compositeSk'] extends never ? { [SKField in keyof Idx['sk']]+?: number extends Idx['sk'][SKField] ? NumericFilter : Idx['sk'][SKField] extends `${deferredRefResolvingPrefix}${infer R}` ? 'type' extends keyof Bag[R] ? Bag[R]['type'] extends string ? StringFilter : never : never : StringFilter; } : { [CompositeSk in Idx['compositeSk']]+?: ModelPrimaryCompositeKeyInput<{ [SKField in keyof Idx['sk']]: Idx['sk'][SKField] extends `${deferredRefResolvingPrefix}${infer _R}` ? string : Idx['sk'][SKField]; }>; }); /** * * TEMP * ---++--- * || * || * \^^/ * \/ */ /** * All required fields and relationship fields, exclude readonly fields */ type MutationInput, WritableFields = Pick>> = WithNullablesAsOptionalRecursively<{ [Prop in keyof WritableFields as WritableFields[Prop] extends (...args: any) => any ? never : Prop]: WritableFields[Prop]; }>; type IfEquals = (() => T extends X ? 1 : 2) extends () => T extends Y ? 1 : 2 ? A : B; type WritableKeys = { [P in keyof T]-?: IfEquals<{ [Q in P]: T[P]; }, { -readonly [Q in P]: T[P]; }, P>; }[keyof T]; type MinusReadonly = { -readonly [K in keyof T]: T[K]; }; type WithNullablesAsOptionalRecursively = T extends Array | ((...args: any) => any) ? T : T extends object ? { [K in keyof T as null extends T[K] ? K : never]+?: WithNullablesAsOptionalRecursively; } & { [K in keyof T as null extends T[K] ? never : K]: WithNullablesAsOptionalRecursively; } : T; /** * All identifiers and fields used to create a model */ type CreateModelInput> = Equal, { id: string; }> extends true ? Partial> & Omit, 'id'> : MutationInput; type UpdateModelInput> = MinusReadonly & Partial>; export {};