import { SnapshotInOf, SnapshotOutOf } from '../snapshot/SnapshotOf'; import { AnyStandardType } from '../types/schemas'; import { Flatten, IsNeverType, IsOptionalValue } from '../utils/types'; /** * @ignore */ export declare const noDefaultValue: unique symbol; type SetterMode = boolean | "assign"; export type ModelPropSetterValueTransform = (value: T) => T; /** * A model property. */ export interface ModelProp { $valueType: TPropValue; $creationValueType: TPropCreationValue; $transformedValueType: TTransformedValue; $transformedCreationValueType: TTransformedCreationValue; $isRequired: TIsRequired; $isId: TIsId; $hasSetter: THasSetter; $fromSnapshotOverride: TFromSnapshotOverride; $toSnapshotOverride: TToSnapshotOverride; _defaultFn: (() => TPropValue) | typeof noDefaultValue; _defaultValue: TPropValue | typeof noDefaultValue; _defaultValueIsTransformed: boolean; _typeChecker: AnyStandardType | undefined; _setter: SetterMode; _setterValueTransform: ((value: unknown) => unknown) | undefined; _isId: boolean; _idGenerator?: (() => string) | undefined; _transform: { transform: (original: unknown, model: object, propName: PropertyKey, setOriginalValue: (newOriginalValue: unknown) => void) => unknown; untransform: (transformed: unknown, model: object, propName: PropertyKey) => unknown; } | undefined; _fromSnapshotProcessor?: (sn: unknown) => unknown; _toSnapshotProcessor?: (sn: unknown) => unknown; /** * Adds a setter to the property. The setter will be named `set${CapitalizedPropName}` * and will be available in the model instance. */ withSetter(): ModelProp; /** * Adds a setter with a transform to the property. The setter will be named `set${CapitalizedPropName}` * and will be available in the model instance. */ withSetter(valueTransform: ModelPropSetterValueTransform): ModelProp; /** * @deprecated Setter methods are preferred. */ withSetter(mode: "assign"): ModelProp; /** * Sets a transform for the property instance value. * * @deprecated Prefer using `tProp(types.codec(...))` or one of the built-in codec types * (e.g. `types.dateAsTimestamp`, `types.bigint`, `types.mapFromObject(...)`) instead. * Wrap with `types.skipCheck(...)` if you don't need runtime validation. * Use `.withTransform(...)` only for one-off custom transforms without a codec equivalent. * * @template TTV Transformed value type. * @param transform Transform to be used. * @returns */ withTransform(transform: ModelPropTransform, TTV>): ModelProp, TTV | Extract, TIsRequired, TIsId, THasSetter, TFromSnapshotOverride, TToSnapshotOverride>; /** * Sets snapshot processors for this property. * * `fromSnapshot` runs before assigning snapshot data into the model prop. * `toSnapshot` runs when exporting model data back to snapshot form. */ withSnapshotProcessor(processor: { fromSnapshot?: (sn: FS) => ModelPropFromSnapshot; toSnapshot?: (sn: ModelPropToSnapshot) => TS; }): ModelProp; } /** * The snapshot in type of a model property. */ export type ModelPropFromSnapshot = IsNeverType, SnapshotInOf>, ModelPropFromSnapshotOverride>; /** * The snapshot out type of a model property. */ export type ModelPropToSnapshot = IsNeverType>, MP["$toSnapshotOverride"]>; export type ModelPropStoredValue = MP extends { $storedValueType: infer TStoredValue; } ? TStoredValue : MP["$valueType"]; export type ModelPropStoredCreationValue = MP extends { $storedCreationValueType: infer TStoredCreationValue; } ? TStoredCreationValue : MP["$creationValueType"]; export type ModelPropFromSnapshotOverride = MP extends { $typedFromSnapshotOverride: infer TFromSnapshotOverride; } ? TFromSnapshotOverride : MP["$fromSnapshotOverride"]; /** * A model prop transform. */ export interface ModelPropTransform { /** * Converts the stored/original value into the transformed value exposed by the model prop. */ transform(params: { originalValue: TOriginal; cachedTransformedValue: TTransformed | undefined; setOriginalValue(value: TOriginal): void; }): TTransformed; /** * Converts the transformed model value back into the original stored value. */ untransform(params: { transformedValue: TTransformed; cacheTransformedValue: () => void; }): TOriginal; } /** * Any model property. */ export type AnyModelProp = ModelProp; /** * Model properties. */ export interface ModelProps { [k: string]: AnyModelProp; } export type RequiredModelProps = { [K in keyof MP]: MP[K]["$isRequired"] & K; }[keyof MP]; export type ModelPropsToUntransformedData = Flatten<{ [k in keyof MP]: ModelPropStoredValue; }>; export type ModelPropsToSnapshotData = Flatten<{ [k in keyof MP]: ModelPropToSnapshot extends infer R ? R : never; }>; export type ModelPropsToUntransformedCreationData = { [k in keyof MP]?: ModelPropStoredCreationValue; } & { [k in RequiredModelProps]: ModelPropStoredCreationValue; }; export type ModelPropsToSnapshotCreationData = Flatten<{ [k in keyof MP]?: ModelPropFromSnapshot extends infer R ? R : never; } & { [k in { [K in keyof MP]: IsNeverType, MP[K]["$isRequired"] & K, // no override IsOptionalValue, never, K>>; }[keyof MP]]: ModelPropFromSnapshot extends infer R ? R : never; }>; export type ModelPropsToTransformedData = Flatten<{ [k in keyof MP]: MP[k]["$transformedValueType"]; }>; export type ModelPropsToTransformedCreationData = { [k in keyof MP]?: MP[k]["$transformedCreationValueType"]; } & { [k in RequiredModelProps]: MP[k]["$transformedCreationValueType"]; }; export type ModelPropsToSetter = Flatten<{ [k in keyof MP as MP[k]["$hasSetter"] & `set${Capitalize}`]: (value: MP[k]["$transformedValueType"]) => void; }>; export type ModelIdProp = ModelProp; type TypedModelIdProp = Omit, "withSetter"> & { /** * Enables generation of a setter method for the ID prop (`setId` for `id`, `setCustomId` for `customId`). */ withSetter(): TypedModelIdProp; /** * Enables generation of a setter method for the ID prop and applies a value transform to setter input. */ withSetter(valueTransform: ModelPropSetterValueTransform): TypedModelIdProp; /** * @deprecated Setter methods are preferred. */ withSetter(mode: "assign"): TypedModelIdProp; /** * Sets a custom generator for missing model IDs in this `idProp`. */ withGenerator(generator: () => T): TypedModelIdProp; /** * Same as `idProp`, except that it might have a specific TypeScript string template as type. * E.g. `idProp.typedAs<`custom-${string}`>()` */ typedAs(): TypedModelIdProp; }; /** * A property that will be used as model id, accessible through $modelId. * Can only be used in models and there can be only one per model. */ export declare const idProp: TypedModelIdProp; /** * @ignore */ export type OnlyPrimitives = Exclude; /** * A model prop that maybe / maybe not is optional, depending on if the value can take undefined. */ export type MaybeOptionalModelProp = ModelProp>; /** * A model prop that is definitely optional. */ export type OptionalModelProp = ModelProp; /** * Defines a model property, with an optional function to generate a default value * if the input snapshot / model creation data is `null` or `undefined`. * * Example: * ```ts * x: prop(() => 10) // an optional number, with a default value of 10 * x: prop(() => []) // an optional number array, with a default empty array * ``` * * @template TValue Value type. * @param defaultFn Default value generator function. * @returns */ export declare function prop(defaultFn: () => TValue): OptionalModelProp; /** * Defines a model property, with an optional default value * if the input snapshot / model creation data is `null` or `undefined`. * You should only use this with primitive values and never with object values * (array, model, object, etc). * * Example: * ```ts * x: prop(10) // an optional number, with a default value of 10 * ``` * * @template TValue Value type. * @param defaultValue Default primitive value. * @returns */ export declare function prop(defaultValue: OnlyPrimitives): OptionalModelProp; /** * Defines a model property with no default value. * * Example: * ```ts * x: prop() // a required number * x: prop() // an optional number, which defaults to undefined * ``` * * @template TValue Value type. * @returns */ export declare function prop(): MaybeOptionalModelProp; /** * @ignore */ export declare function getModelPropDefaultValue(propData: AnyModelProp): unknown | typeof noDefaultValue; /** * @ignore */ export declare function getModelPropStoredDefaultValue(propData: AnyModelProp, model: object, propName: string): unknown | typeof noDefaultValue; export {};