/** Role that a value or property plays in a relational model. */ export type ValueRole = "value" | "primaryKey" | "foreignKey" | "referenceNavigation" | "collectionNavigation"; /** Root metadata object, off of which all metadata for the application's data model is stored. */ export interface Domain { types: { [modelName: string]: ClassType; }; enums: { [modelName: string]: EnumType; }; services: { [modelName: string]: Service; }; } /** Type discriminators of non-object types that are natively represented in javascript, i.e. they are valid results of the typeof operator. */ export type NativePrimitiveTypeDiscriminator = "string" | "number" | "boolean"; /** Type discriminators of object types that exist natively in javascript. */ export type NativeObjectTypeDiscriminator = "date" | "file" | "binary"; /** * Type discriminators of types that do not have a `CustomType` representation in the metadata. * Enums do have such a representation, and so aren't included. */ export type NativeTypeDiscriminator = NativePrimitiveTypeDiscriminator | NativeObjectTypeDiscriminator; /** Type discriminators of non-poco types */ export type ValueTypeDiscriminator = NativeTypeDiscriminator | "enum"; /** Type discriminators of object-based types. */ export type ClassTypeDiscriminator = "model" | "object"; /** Type discriminators of custom types that have their own metadata representation. */ export type CustomTypeDiscriminator = ClassTypeDiscriminator | "enum"; /** Type discriminator of all non-collection types */ export type NonCollectionTypeDiscriminator = ValueTypeDiscriminator | ClassTypeDiscriminator | "unknown"; /** Union of all valid type discriminators. */ export type TypeDiscriminator = NonCollectionTypeDiscriminator | "collection"; /** Maps a type discriminator to its best match TypeScript type */ export type TypeDiscriminatorToType = T extends "string" ? string : T extends "number" ? number : T extends "boolean" ? boolean : T extends "date" ? Date : T extends "file" ? File : T extends "unknown" ? unknown : T extends "binary" ? Uint8Array | string : any; /** Base properties found on all pieces of metadata. */ export interface Metadata { /** The machine-readable name of the value or type. Values are typically camel-cased; types are typically PascalCased. */ readonly name: string; /** The human-readable name of the value or type */ readonly displayName: string; /** * Custom metadata extracted from C# attributes specified * via `[assembly: CoalesceMetadata]` declarations. */ readonly attributes?: { readonly [key: string]: { readonly [key: string]: unknown; }; }; } /** Common properties for custom object types. */ export interface CustomReferenceTypeBase extends Metadata { readonly type: ClassTypeDiscriminator; /** The description of the type itself. */ readonly description?: string; /** The properties of the represented type */ readonly props: { [propName in string]: Property; }; /** * The description of the property that holds a value that offers some textual representation of this model. * This property is not necessarily a string property - it may even be a object property. * To get a textual representation of any object, use function `modelDisplay` from the `model` module. */ readonly displayProp?: Property; /** The types that this type inherits from. */ readonly baseTypes?: CustomReferenceTypeBase[]; /** The types that inherit this type. */ readonly derivedTypes?: CustomReferenceTypeBase[]; readonly abstract?: boolean; } export interface ApiRoutedType { /** * The URI path segment that identifies this type in API endpoints. * This value contains no leading/trailing slashes. */ readonly controllerRoute: string; /** The methods of the type that are invokable via API endpoints. */ readonly methods: { [methodName in string]: Method; }; } /** Represents a type that is not part of a relational model. */ export interface ObjectType extends CustomReferenceTypeBase { readonly type: "object"; } /** Flags representing the 3 different behaviors in Coalesce - Create, Edit, and Delete. */ export declare enum BehaviorFlags { Create = 1, Edit = 2, Delete = 4 } /** Represents a type that is part of a relational model and can be identified by a single, unique key. */ export interface ModelType extends CustomReferenceTypeBase, ApiRoutedType { readonly type: "model"; readonly displayProp: Property; /** The primary key property of the entity */ readonly keyProp: Property; /** Flags indicating the create/edit/delete capabilities of the type. */ readonly behaviorFlags: BehaviorFlags; /** The data sources that can be used to query the API for objects of this type. */ readonly dataSources: { [sourceName in string]: DataSourceType; }; /** The types that inherit this type. */ readonly derivedTypes?: ModelType[]; } export interface DataSourceType extends Metadata { readonly type: "dataSource"; readonly isDefault?: true; readonly description?: string; /** The parameters of the data source. */ readonly props: { [paramName in string]: PrimitiveProperty | DateProperty | EnumProperty | ObjectProperty | UnknownProperty | BinaryProperty | ModelValueProperty | BasicCollectionProperty; }; } export interface Service extends Metadata, ApiRoutedType { readonly type: "service"; } /** Represents a value of an enum */ export interface EnumMember { readonly value: number; readonly strValue: string; readonly displayName: string; readonly description?: string; } /** A dictionary with both string and numeric keys for looking up `EnumValue` objects by their string or numeric value. */ export type EnumMembers = { [strValue in K]: EnumMember; } & { [n: number]: EnumMember; }; /** Utility function for creating the required properties of `EnumType<>` from an array of `EnumValue` */ export declare function getEnumMeta(values: EnumMember[]): { readonly valueLookup: EnumMembers; readonly values: EnumMember[]; }; /** Metadata representation of an enum type */ export interface EnumType extends Metadata { readonly type: "enum"; /** A lookup object with both string and numeric keys for obtaining metadata about a particular enum value. */ readonly valueLookup: EnumMembers; /** * The collection of all declared values of this enumeration. */ readonly values: EnumMember[]; /** * The format of this enum's values over the wire. * When `"string"`, enum values are serialized as their string member names instead of numbers. * Set when the enum has `JsonStringEnumConverter` attribute. */ readonly format?: "string"; } /** Union of all metadata descriptions of object-based types. */ export type ClassType = ObjectType | ModelType | DataSourceType; /** Union of all metadata descriptions of custom types, including enums. */ export type CustomType = ClassType | EnumType; /** A special value that represents void. * Not be included in the standard unions of all `Value` kinds, * since its usage only applies to method returns - it should instead * only be included in unions where its usage is applicable. * Also note that its `type` property is not part of `TypeDiscriminator`. */ export interface VoidValue extends Metadata { readonly role: "value"; readonly type: "void"; } /** Narrowing intersection interface for the 'return' value on methods. */ export interface MethodReturnValue { readonly name: "$return"; } export type Rule = (val: T | null | undefined) => true | string; export interface Rules { required?: Rule; minLength?: Rule; maxLength?: Rule; min?: Rule; max?: Rule; pattern?: Rule; email?: Rule; phone?: Rule; url?: Rule; uri?: Rule; } /** * Base interface for all normal value metadata representations. * For our purposes, a value is defined as the usage of a type. * This includes properties, method parameters, method returns, * items in a collection, and more. */ export interface ValueMeta extends Metadata { /** * Role that the value or property plays in a relational model. * Some values may be nonapplicable in some contexts, like method parameters. */ readonly role: ValueRole; readonly type: TType; readonly description?: string; } /** * Base interface for values whose type has a custom definition in the metadata. */ export interface ValueMetaWithTypeDef extends ValueMeta { /** Full description of the type represented by this value. */ readonly typeDef: TTypeDef; } /** Represents the usage of a string */ export interface StringValue extends ValueMeta<"string"> { readonly role: "value" | "foreignKey" | "primaryKey"; /** Details about the kind of data that the string represents. */ readonly subtype?: "password" | "url" | "email" | "tel" | "multiline" | "color" | "url-image"; readonly rules?: Rules; readonly defaultValue?: string; } /** Represents the usage of a number */ export interface NumberValue extends ValueMeta<"number"> { readonly role: "value" | "foreignKey" | "primaryKey"; readonly rules?: Rules; readonly defaultValue?: number; } /** Represents the usage of a boolean */ export interface BooleanValue extends ValueMeta<"boolean"> { readonly rules?: Rules; readonly defaultValue?: boolean; } /** Represents the usage of a primitive value (string, number, or bool) */ export type PrimitiveValue = StringValue | NumberValue | BooleanValue; export type DateKind = "date" | "time" | "datetime"; /** Represents the usage of a date */ export interface DateValue extends ValueMeta<"date"> { readonly role: "value" | "foreignKey" | "primaryKey"; readonly dateKind: DateKind; /** True if the date value is insensitive to timezone offsets * (i.e. the C# type is `DateTime`, not `DateTimeOffset`) */ readonly noOffset?: boolean; readonly serializeAs?: DateKind; readonly rules?: Rules; } export interface FileValue extends ValueMeta<"file"> { readonly role: "value"; readonly fileType?: string; } export interface BinaryValue extends ValueMeta<"binary"> { readonly role: "value"; /** True if the value only supports base64 representation (and not raw formats like ArrayBuffer) */ readonly base64?: boolean; } /** Represents the usage of an unknown type, i.e. an object declared as `object` in C#. * Such types have no metadata and their values only exist as their JSON representation. */ export interface UnknownValue extends ValueMeta<"unknown"> { readonly role: "value"; } /** Represents the usage of an enum */ export interface EnumValue extends ValueMetaWithTypeDef<"enum", EnumType> { readonly role: "value" | "foreignKey" | "primaryKey"; readonly rules?: Rules; readonly defaultValue?: number; } /** Represents the usage of an 'external type', i.e. an object that is not part of a relational model */ export interface ObjectValue extends ValueMetaWithTypeDef<"object", ObjectType> { readonly role: "value"; } /** Represents the usage of an object that is part of a relational model */ export interface ModelValue extends ValueMetaWithTypeDef<"model", ModelType> { readonly role: "value" | "referenceNavigation"; } /** Represents the usage of a collection of values */ export interface CollectionValue extends ValueMeta<"collection"> { readonly role: "value" | "collectionNavigation"; readonly itemType: NonCollectionValue; } /** Represents the usage of a collection of model values */ export interface ModelCollectionValue extends ValueMeta<"collection"> { readonly role: "value" | "collectionNavigation"; readonly itemType: ModelValue; } /** Union of all representations of the usage of types with explicit type metadata */ export type CustomTypeValue = EnumValue | ObjectValue | ModelValue; /** Union of all representations of the usage of non-collection types */ export type NonCollectionValue = PrimitiveValue | DateValue | FileValue | BinaryValue | UnknownValue | CustomTypeValue; /** Union of all representations of the usage of a type */ export type Value = NonCollectionValue | CollectionValue; /** Union of all type usages that can be represented in JSON. */ export type JsonValue = Exclude; export declare enum HiddenAreas { List = 1, Edit = 2 } export interface PropertyBase { /** True if the property should be skipped when mapping to a DTO. */ readonly dontSerialize?: boolean | undefined; /** True if the property can only be changed on a create, but not on an update. */ readonly createOnly?: boolean | undefined; /** Enum indicating what admin views the property is hidden on, if any. */ readonly hidden?: HiddenAreas; /** True if the property is not filterable via the list `filter` parameter. */ readonly noFilter?: boolean | undefined; } /** Represents a primitive property */ export type PrimitiveProperty = PropertyBase & PrimitiveValue & { readonly role: "value"; }; /** Represents a property that serves as a primary key */ export type PrimaryKeyProperty = PropertyBase & (StringValue | NumberValue | EnumValue | DateValue) & { readonly role: "primaryKey"; }; /** Represents a property that serves as a foreign key */ export type ForeignKeyProperty = PropertyBase & (StringValue | NumberValue | EnumValue | DateValue) & { readonly role: "foreignKey"; readonly principalKey: PrimaryKeyProperty; readonly principalType: ModelType; readonly navigationProp?: ModelReferenceNavigationProperty; }; /** Represents a date property */ export type DateProperty = PropertyBase & DateValue & { readonly role: "value"; }; /** Represents an enum property */ export type EnumProperty = PropertyBase & EnumValue & { readonly role: "value"; }; /** Represents an object property */ export interface ObjectProperty extends PropertyBase, ObjectValue { } /** Represents an unknown property */ export interface UnknownProperty extends PropertyBase, UnknownValue { } /** Represents a binary property */ export interface BinaryProperty extends PropertyBase, BinaryValue { readonly base64: true; } /** * Represents a model property that simply exists as a value, * not as a relational navigation property. */ export interface ModelValueProperty extends PropertyBase, ModelValue { readonly role: "value"; } /** * Represents an object property that represents the foreign end of * a 1-to-1 or 1-to-many relationship in a relational model. */ export interface ModelReferenceNavigationProperty extends PropertyBase, ModelValue { readonly role: "referenceNavigation"; readonly foreignKey: ForeignKeyProperty | PrimaryKeyProperty; readonly principalKey: PrimaryKeyProperty; readonly inverseNavigation?: ModelReferenceNavigationProperty | ModelCollectionNavigationProperty; } /** * Represents a collection property that simple contains values that do not * have any special meaning in a relational model. */ export interface BasicCollectionProperty extends PropertyBase, CollectionValue { readonly role: "value"; } /** * Represents a collection property that represents * the foreign objects in a many-to-1 relationship in a relational model. */ export interface ModelCollectionNavigationProperty extends PropertyBase, CollectionValue { readonly role: "collectionNavigation"; /** * Reference to the property on the type contained in this collection that relates * to the primary key of the model that owns the collection property. */ readonly foreignKey: ForeignKeyProperty; readonly itemType: ModelValue; readonly inverseNavigation?: ModelReferenceNavigationProperty; readonly manyToMany?: { /** The name of the many-to-many collection. */ readonly name: string; /** The human-readable name of the many-to-many collection. */ displayName: string; /** The type represented by the other side of the many-to-many relationship. */ readonly typeDef: ModelType; /** The foreign key on the join entity that refers to an entity on the current property's side of the relationship. */ readonly nearForeignKey: ForeignKeyProperty; /** The navigation on the join entity that refers to an entity on the current property's side of the relationship. */ readonly nearNavigationProp: ModelReferenceNavigationProperty; /** The foreign key on the join entity that refers to an entity on the other side of the relationship. */ readonly farForeignKey: ForeignKeyProperty; /** The navigation on the join entity that refers to an entity on the other side of the relationship. */ readonly farNavigationProp: ModelReferenceNavigationProperty; }; } export type CollectionProperty = BasicCollectionProperty | ModelCollectionNavigationProperty; export type Property = PrimitiveProperty | PrimaryKeyProperty | ForeignKeyProperty | DateProperty | EnumProperty | ObjectProperty | UnknownProperty | BinaryProperty | ModelValueProperty | ModelReferenceNavigationProperty | CollectionProperty; export type MethodParameter = Value & { /** If specified, the name of a property on the model that owns the parameter's method * that the value of this parameter should be automatically sourced from when invoked on viewmodels. */ source?: Property; readonly rules?: Rules; }; export interface MethodBase extends Metadata { readonly description?: string; /** The HTTP method to use when calling the method. */ readonly httpMethod: "GET" | "POST" | "PUT" | "DELETE" | "PATCH"; /** True if the method is static; otherwise undefined/false */ readonly isStatic?: boolean; /** True if the args object should be cleared on admin pages after a successful invocation. */ readonly autoClear?: boolean; /** The query string (GET/DELETE only) or body parameters of the method */ readonly params: { [paramName in string]: MethodParameter; }; /** Enum indicating what admin views the method is hidden on, if any. */ readonly hidden?: HiddenAreas; } export interface ItemMethod extends MethodBase { /** The return type of the method. */ readonly return: Value | VoidValue; /** The transport container for the return type, corresponding to "ListResult" or "ItemResult". */ readonly transportType: "item"; } export interface ListMethod extends MethodBase { /** The return type of the method. */ readonly return: CollectionValue; /** The transport container for the return type, corresponding to "ListResult" or "ItemResult". */ readonly transportType: "list"; } export type Method = ItemMethod | ListMethod; export type KeysOfType = { [K in keyof TObject]: TObject[K] extends Type ? K : never; }[Extract]; export type PropNames = KeysOfType; export type PropertyOrName = PropNames | Property; export declare function resolvePropMeta(metadata: ClassType, propOrString: TProp | string): Exclude; export declare function resolvePropMeta(metadata: ClassType, propOrString: TProp | string, silent: true): Exclude | undefined; /** Recursively freeze the object, and convert any getter props into props * that hold the current value of the getter. */ export declare function solidify(root: T): T;