import { RecordType } from '../data-types/definitions/record.js'; import { CollectionQuery, QueryResultCardinality, QueryWhere, SchemaQuery, } from '../../query/types/index.js'; import { StringKey } from '../../utils/types.js'; // === Model Definitions === // ====== Core Types ====== /** * The set of collections that define a schema */ export type Models>> = { [K in StringKey]: Collection< // @ts-expect-error - allow any for model to allow self-referencing T, K >; }; /** * Information pertaining to a collection */ export interface Collection< M extends Models = Models, CN extends CollectionNameFromModels = CollectionNameFromModels, > { schema: Model; relationships?: Relationships; permissions?: ModelRolePermissions; } /** * Collection names in a model */ export type CollectionNameFromModels> = StringKey; // ====== Model ====== /** * An individual model */ export type Model = RecordType; // ====== Relationships ====== /** * Mapped type of all relationships in a schema */ type ModelsRelationship = Models> = { [CN in CollectionNameFromModels]: Relationship>; }; /** * Union of specified relationships in a schema with CN */ type ModelRelationship< M extends Models = Models, CN extends CollectionNameFromModels = CollectionNameFromModels, > = ModelsRelationship[CN]; export type Relationships< M extends Models = Models, CN extends CollectionNameFromModels = CollectionNameFromModels, > = { [R in string]: ModelRelationship; }; /** * A relationship between two collections */ export type Relationship< M extends Models = Models, Q extends SchemaQuery = SchemaQuery, Cardinality extends QueryResultCardinality = QueryResultCardinality, > = { query: Q; cardinality: Cardinality; }; // ====== Roles and Permissions ====== // ========= Permissions ========= /** * Mapped type of all permissions in a schema */ type ModelsRolePermissions = Models> = { [CN in CollectionNameFromModels]: RolePermissions; }; /** * Union of specified permissions in a schema with CN */ type ModelRolePermissions< M extends Models = Models, CN extends CollectionNameFromModels = CollectionNameFromModels, > = ModelsRolePermissions[CN]; /** * A collection of permissions by role */ export type RolePermissions< M extends Models = Models, CN extends CollectionNameFromModels = CollectionNameFromModels, > = { [R in string]: CollectionPermissions; }; /** * Permissions for a collection by known operation */ export type CollectionPermissions< M extends Models = Models, CN extends CollectionNameFromModels = CollectionNameFromModels, > = { read?: CollectionPermission; insert?: CollectionPermission; update?: CollectionPermission; postUpdate?: CollectionPermission; delete?: CollectionPermission; }; /** * A permissions definition */ export type CollectionPermission< M extends Models = Models, CN extends CollectionNameFromModels = CollectionNameFromModels, > = { filter?: QueryWhere; // attributes?: Array>; // attributesExclude?: Array>; }; /** * Union of operations for permissions */ export type PermissionOperations = keyof CollectionPermissions; /** * Union of write operations for permissions */ export type PermissionWriteOperations = Exclude; // ========= Roles ========= /** * Collection of roles for a database */ export type Roles = Record; /** * Requisite information related to a role */ export type Role = { match: PermissionMatcher; }; // TODO: we could maybe try to make this more type safe, should be valid JSON /** * An object that will be matched against a JWT payload to determine if a user has a role * A value prefixed with '$' indicates a wildcard that will be replaced with the value from the JWT payload */ export type PermissionMatcher = Record; // ====== Rules (deprecated) ====== // TODO: remove export interface CollectionRules< M extends Models, CN extends CollectionNameFromModels, > { read?: Record>; write?: Record>; } // TODO: remove export interface Rule< M extends Models, CN extends CollectionNameFromModels, > { filter: QueryWhere; description?: string; }