import { config } from 'mssql'; import { EntityMeta, RadsDb } from '_rads-db'; type MaybePromise$1 = Promise | T; type Change = { [K in keyof T]?: T[K] extends any[] ? T[K] : T[K] extends {} ? Change : T[K]; }; interface GetManyArgs extends GetArgs { cursor?: string | undefined; maxItemCount?: number; orderBy?: string; orderByArray?: OrderBy; } interface VerifyManyArgs extends GetManyArgs { recompute?: string[]; dryRun?: boolean; } interface VerifyManyResponse { cursor: string | undefined; correctCount: number; incorrectCount: number; incorrectDocs: { id: string; diff: any; toRemove?: any; }[]; } type Where = EntityMeta[EN]['whereType'] & { _not?: Where; _and?: Where[]; _or?: Where[]; }; interface GetArgs { where?: Where; include?: GetArgsInclude; } interface GetAggArgs extends Omit, 'include'> { agg: GetAggArgsAgg; } type GetAggArgsAgg = ('_count' | `${F}_min` | `${F}_max` | `${F}_sum`)[]; type GetManyArgsAny = GetManyArgs; type GetArgsAny = GetArgs; type GetAggArgsAny = GetAggArgs; type VerifyManyArgsAny = VerifyManyArgs; type RelationsAndNestedObjects = EntityMeta[EN]['relations'] & EntityMeta[EN]['nestedObjects']; type JsonFieldsInclude = [EntityMeta[EN]['jsonFields']] extends [never] ? unknown : { [K in EntityMeta[EN]['jsonFields'] & string]?: { _pick?: readonly string[]; }; }; type GetArgsInclude = keyof RelationsAndNestedObjects> = [R] extends [never] ? { _pick?: readonly (EntityMeta[EN]['primitives'] | EntityMeta[EN]['jsonFields'])[]; } & JsonFieldsInclude : { _pick?: readonly (EntityMeta[EN]['primitives'] | EntityMeta[EN]['jsonFields'] | R)[]; } & { [K in R]?: GetArgsInclude[K]['entityName']>; } & JsonFieldsInclude; type GetAggResponse> = { [K in A['agg'][number]]: K extends '_count' ? number : number | undefined; }; interface GetManyResponse> { nodes: GetResponse[]; cursor: string | undefined; } type GetResponse> = (A extends { include: any; } ? GetResponseInclude : GetResponseNoInclude) & StoredDocumentFields; /** Fields the database adds to every stored document. */ interface StoredDocumentFields { /** Version of the stored document; pass it as `_ifMatch` to a put to make the write conditional. */ _etag?: string; } type Get = {}> = [Include] extends [Record] ? GetResponse : GetResponse; type RelationData = Pick; type KeepArray = NonNullable extends any[] ? TType[] : TType; type GetResponseInclude> = I extends { _pick: readonly string[]; } ? GetResponseIncludeSelect : { [K in keyof EntityMeta[EN]['type']]: K extends keyof EntityMeta[EN]['relations'] ? K extends keyof I ? KeepArray> : KeepArray> : K extends keyof EntityMeta[EN]['nestedObjects'] ? K extends keyof I ? KeepArray> : EntityMeta[EN]['type'][K] : EntityMeta[EN]['type'][K]; }; type GetResponseIncludeSelect> = I extends { _pick: readonly (infer P)[]; } ? Pick<{ [K in keyof EntityMeta[EN]['type']]: K extends keyof EntityMeta[EN]['relations'] ? K extends keyof Omit ? KeepArray[K]>> : KeepArray> : K extends keyof EntityMeta[EN]['nestedObjects'] ? K extends keyof Omit ? KeepArray[K]>> : EntityMeta[EN]['type'][K] : K extends EntityMeta[EN]['jsonFields'] ? K extends keyof Omit ? Omit[K] extends { _pick: (infer JP)[]; } ? Pick, JP & string> : EntityMeta[EN]['type'][K] : EntityMeta[EN]['type'][K] : EntityMeta[EN]['type'][K]; }, ((P & string) | (Exclude & string)) & keyof EntityMeta[EN]['type']> : never; type GetResponseNoInclude = { [K in keyof EntityMeta[EN]['type']]: K extends keyof EntityMeta[EN]['relations'] ? KeepArray> : EntityMeta[EN]['type'][K]; }; type DeepPartialWithNulls = { [K in keyof T]?: NonNullable extends any[] ? DeepPartialArrayItem[number]>[] | null : DeepPartialWithNullsItem>; }; type DeepPartialWithNullsItem = T extends { id: string; } ? Exclude extends never ? { id: string; } | null : DeepPartialWithNulls | null : T extends Record ? DeepPartialWithNulls | null : T | null; type DeepPartialArrayItem = T extends { id: string; } ? Exclude extends never ? { id: string; } : DeepPartialWithoutNulls : T extends Record ? DeepPartialWithoutNulls : T; type DeepPartialWithoutNulls = { [K in keyof T]?: NonNullable extends any[] ? DeepPartialArrayItem[number]>[] : DeepPartialWithoutNullsItem>; }; type DeepPartialWithoutNullsItem = T extends { id: string; } ? Exclude extends never ? { id: string; } : DeepPartialWithoutNulls : T extends Record ? DeepPartialWithoutNulls : T; type DeepPartial = { [K in keyof T]?: NonNullable extends any[] ? DeepPartial[number]>[] : NonNullable extends Record ? DeepPartial : T[K]; }; /** Indicates that this field is a relation to another entity in the database. * Only id will be stored in the database. * If you want to store additional fields, please, pass them as the second type argument */ type Relation = never> = Pick; /** Indicates that this is computed field - all documents that point to this document via Relation<>. * Note: this field is not stored in the database at all. Returns up to 100 items and doesn't support pagination * If you need more control, please, use separate request instead. */ type InverseRelation = EntityMeta[EN]['type']; type PutId = T extends { id: string; } ? { id: string; } : {}; type Put = PutId & JsonPutOperations & DeepPartialWithNulls & { /** Optimistic concurrency: write only if the stored document still has this `_etag` (read earlier); * otherwise the put throws an error with `statusCode: 412`. */ _ifMatch?: string; }; type JsonPutOperations = { [K in EntityMeta[EN]['jsonFields'] as `${K & string}_replace`]?: EntityMeta[EN]['type'][K]; }; type DeepKeys = T extends object ? { [K in (string | number) & keyof T]: `${`.${K}` | (`${K}` extends `${number}` ? `[${K}]` : never)}${'' | DeepKeys}`; }[(string | number) & keyof T] : never; interface EntityMethods { /** Returns object with with random UUID as `id` and prefilled default values */ construct(defaultValues?: DeepPartial): E; /** Used to access underlying mechanism of storage directly. * Warning: bypasses all rads features - schema won't be validated, default values won't be filled, etc. */ driver: Driver; get>(args: A, ctx?: RadsRequestContext): MaybePromise$1>; getMany>(args?: A, ctx?: RadsRequestContext): MaybePromise$1>; getAgg>(args: A, ctx?: RadsRequestContext): MaybePromise$1>; getAll>(args?: A, ctx?: RadsRequestContext): MaybePromise$1['nodes']>; put(data: Put, ctx?: RadsRequestContext): MaybePromise$1>; putMany(data: Put[], ctx?: RadsRequestContext): MaybePromise$1[]>; verifyMany>(args?: A, ctx?: RadsRequestContext): MaybePromise$1; verifyAll>(args?: A, ctx?: RadsRequestContext): MaybePromise$1>; } type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ...0[]]; type Primitive = string | number | boolean | symbol | null | undefined; type OrderByDeepKeys = Depth extends 0 ? '' : T extends Primitive ? Prefix extends '' ? never : Prefix : T extends object ? { [K in keyof T]-?: K extends string | number ? OrderByDeepKeys : never; }[keyof T] : never; type TrimEnd = T extends `${infer R}${S}` ? R : T; type ValidOrderByKey = TrimEnd, '.'>; type OrderBy = Array<`${ValidOrderByKey}_${'asc' | 'desc'}`>; interface RadsConfig { dataSources: Record; } interface RadsConfigDataSource { schema: () => MaybePromise; } type MaybePromise = Promise | T; type RequiredFields = T & Required>; type ValidateFieldDecoratorArgs = T extends string ? ValidateStringDecoratorArgs : T extends number ? ValidateNumberDecoratorArgs : ValidateAnyDecoratorArgs; interface ValidateEntityDecoratorArgs { } interface ValidateAnyDecoratorArgs { } interface ValidateNumberDecoratorArgs { isWhole?: boolean; min?: number; max?: number; } interface ValidateStringDecoratorArgs { preset?: 'text' | 'html' | 'markdown' | 'alpha' | 'alphanum' | 'number' | 'decimalNumber' | 'email' | 'icon' | 'imageUrl' | 'fileUrl' | 'absoluteUrl' | 'relativeUrl' | 'phoneNumber' | 'datetime' | 'date' | 'time' | 'timeInterval' | 'duration' | 'hexColor'; regex?: RegExp | string; minLength?: number; maxLength?: number; maxSizeKb?: number; } interface UiFieldDecoratorArgs { /** User-friendly name of the entity (singular). * Used as editor field label and column name in exports. * Defaults to `_.startCase(fieldName)` */ name?: string; /** Icon to display as editor field icon. E.g. `mdi-user`. */ icon?: string; /** Free text - hint to display under editor field in UI */ hint?: string; /** If true, field is hidden from the rads-ui */ isHidden?: boolean; /** If true, field is readonly in the rads-ui */ isReadonly?: boolean; /** If true, field can be edited only during creation */ isImmutable?: boolean; /** TODO: Preferred component to display or edit this value */ component?: string; } interface UiDecoratorArgs { /** User-friendly name of the entity (singular). * Defaults to `_.startCase(entityName).split(' ').slice(1).join(' ')` (i.e. removes the prefix) */ name?: string; /** User-friendly name of the entity (plural) * Defaults to `pluralize(entityName)` */ namePlural?: string; /** Icon to display near this entity. Defaults to `mdi-file-outline` */ icon?: string; /** Field that contains "name" value. * Used by Rads UI to set up default search and display behaviour * Defaults to (if field with such name exists) `name` > `title` > `id` */ nameField?: keyof T; /** Some important-to-know fields, like "id" or "code" or "description". * Used by Rads UI to display in the list view * Defaults to `["id"]` */ captionFields?: (keyof T)[]; /** Field that contains value that points to either: * - icon (e.g. 'mdi-test') * - image URL (e.g. 'https://radsjs.com/icon.png'). Make sure it's not too big (around 200x200px) * Used by Rads UI to display it in the list view. * Defaults to (if exists) `image` > `photo` > `thumbnail` > `icon` > undefined */ iconField?: keyof T; /** Search operator that's used in simple search by name. Defaults to 'istartsWith' */ searchOperator?: 'startsWith' | 'istartsWith' | 'contains' | 'icontains'; /** Defines section name in rads-ui where this entity will be grouped under */ group?: string; /** If true, field is hidden from the rads-ui */ isHidden?: boolean; } interface EntityDecoratorArgs { driver?: string; } interface ComputedDecoratorArgs { preset: string; } interface FieldDecoratorArgs { relation?: Function; } type DriverConstructor = (schema: Schema, entity: string) => MinimalDriver; interface CreateRadsArgsDrivers { default: DriverConstructor; [driverName: string]: DriverConstructor; } interface RestDriverOptions { /** @default '/api' */ baseUrl?: string; fetch?: (url: string, options?: { body?: any; headers?: any; method?: string; }) => any; getHeaders?: (radsDbRequest: { args?: any; context?: RadsRequestContext; }) => Record | undefined; } interface CreateRadsDbArgs { schema?: Schema; driver?: DriverConstructor | CreateRadsArgsDrivers; fileUploadDriver?: FileUploadDriver; noComputed?: boolean; noCustomDrivers?: boolean; /** Set when driver returns documents with includes already resolved, so they are not resolved again. Defaults to true in createRadsDbClient */ includesResolvedByDriver?: boolean; computed?: Record | { _entity?: { compute: Function; recomputeWhen: Record boolean>; }; }>; beforeGet?: (args: GetArgsAny, ctx: RadsRequestContext, context: ComputedContext) => MaybePromise; context?: Record & Omit; features?: RadsFeature[]; keepNulls?: boolean; } type CreateRadsDbArgsNormalized = RequiredFields & { driver: CreateRadsArgsDrivers; }; type CreateRadsDbClientArgs = Omit & { driver?: RestDriverOptions; }; type Schema = Record; interface SchemaLoadResult { schema: Schema; entitiesDir?: string; entitiesDirs?: string[]; } type SchemaValidators = Record any>; interface TypeDefinition { name: string; decorators: Record>; comment?: string; precomputedFields?: string[]; computedFields?: string[]; nestedTypeFields?: string[]; fields?: Record; enumValues?: Record; handle?: string; handlePlural?: string; isExtending?: string; keepHistoryFields?: string[]; sourceFile?: string; } interface FileUploadResult { url: string; } interface FileUploadDriver { driverName: string; client?: any; uploadFile(args: FileUploadArgs, ctx?: RadsRequestContext): Promise; } type RadsDbInstance = RadsDb[keyof RadsDb]; interface GetRestRoutesOptions { /** Instance of RadsDb */ db: RadsDb[keyof RadsDb]; /** Prefix to use for generated routes. Defaults to "/api/" */ prefix?: string; /** By default, rest endpoints for manipulating local files are exposed when NODE_ENV === 'development'. Set to true or false to override. */ exposeFilesystem?: boolean; } interface GetRestRoutesArgs { body?: any; context: any; headers: Record; } type GetRestRoutesResponse = Record Promise>>>; interface FileUploadArgs { blob: Blob; fileName: string; containerName?: string; options?: any; } interface MinimalDriver { driverName: string; /** raw underlying data access service - e.g. sql client or azure storage client */ client?: any; putMany: (items: Record[], ctx?: RadsRequestContext) => MaybePromise; getMany: (args?: GetManyArgsAny, ctx?: RadsRequestContext) => MaybePromise<{ nodes: Record[]; cursor: string | undefined; }>; get?: (args: GetArgsAny, ctx?: RadsRequestContext) => MaybePromise | undefined>; getAll?: (args: GetManyArgsAny, ctx?: RadsRequestContext) => MaybePromise[]>; getAgg?: (args: GetAggArgsAny, ctx?: RadsRequestContext) => MaybePromise>; deleteMany?: (args: GetManyArgsAny, ctx?: RadsRequestContext) => MaybePromise<{ nodes: Record[]; cursor: string | undefined; }>; deleteAll?: (args: GetManyArgsAny, ctx?: RadsRequestContext) => MaybePromise[]>; put?: (data: Record, ctx?: RadsRequestContext) => MaybePromise; verifyMany?: (args?: VerifyManyArgsAny, ctx?: RadsRequestContext) => MaybePromise; ensureClientConnected?: () => MaybePromise; generateMigrationScript?: () => MaybePromise<{ createScript: string; dropScript: string; }>; } type Driver = Required> & Pick; interface FieldDefinition { name: string; type: string; defaultValue?: any; defaultValueClass?: string; defaultValueCopyFrom?: string; isRequired?: boolean; isArray?: boolean; isRelation?: boolean; isInverseRelation?: boolean; isChange?: boolean; inverseRelationField?: string; relationDenormFields?: string[]; comment?: string; decorators?: Record>; } interface EnumDefinition { name: string; comment?: string; decorators?: Record>; } interface ComputedContextGlobal { db: RadsDbInstance; schema: Schema; validators: SchemaValidators; options: CreateRadsDbArgs; drivers: Record; effects: Record; } interface ComputedContext extends ComputedContextGlobal { typeName: string; handle: string; } interface RadsHookDoc { /** Updated document that will be saved to the database */ doc: any; /** Previous version of document - i.e. one that is currently in the database (before saving) */ oldDoc: any; /** If current entity is event sourcing aggregate, you can access all events in the chronological order */ events?: any[]; updatedEvents?: any[]; } interface PutEffect { featureName: string; beforePut?: (computedContext: ComputedContext, docs: RadsHookDoc[], ctx: RadsRequestContext) => MaybePromise; afterPut: (computedContext: ComputedContext, docs: RadsHookDoc[], beforePutResult: any, ctx: RadsRequestContext) => MaybePromise; } interface SqlDriverOptions { authentication: config['authentication']; server: config['server']; database: config['database']; options?: Omit; tablePrefix?: string; stagingTablePrefix?: string; } interface RestFileUploadDriverOptions { /** @default '/api' */ baseUrl?: string; fetch?: (url: string, options?: { body?: any; headers?: any; method?: string; }) => any; /** If true, "multipart/form-data" body will be used (sometimes causes problems in serverless environments). * Otherwise, "application/json" body (with base64-encoded binary content) will be used */ useFormData?: boolean; } type GenerateClientOptions = GenerateClientNormalizedOptions; interface GenerateClientNormalizedOptions { /** For servers - path to your entities directory, e.g. "./entities" */ entitiesDir?: string; /** For client-only integrations - base url of your API, e.g. "https://my-website/api" */ apiUrl?: string; } interface RadsVitePluginOptions extends GenerateClientOptions { /** To simplify debugging, makes modules available on window. * For example, "/src/stores/userStore.ts" will be available at window.stores.userStore. * You can pass the regex - if filename satisfies it, it will be exposed. * Path inside window is determined by first matching group in said regex. * If `true`, default regex is used - `/\/src\/((services|stores)\/(.+))\.[tj]s$/` */ exposeModulesInDev?: boolean | RegExp; } interface RadsRequestContext { _logs?: any[]; log?: (requestInfo: any) => void; getUser?: () => { id: string; role: string; } | undefined; /** If true, no changes made to the database - instead, all changes are returned as logs */ dryRun?: boolean; /** (Not supported yet) If true, updatedAt/updatedBy properties are not updated, and log records are not created */ silent?: boolean; /** Mostly for internal use. When entity name is specified, indicates that calling put* on this entity is allowed, even if it's marked as @precomputed or @readonly */ skipPrecomputedCheckFor?: string; /** Skip precomputed calculation for these fields and use provided values instead */ skipPrecomputed?: string[]; /** Method that was called - get, getAll, getMany, getAgg, put, putMany, etc */ method?: 'get' | 'getAll' | 'getMany' | 'getAgg' | 'put' | 'putMany' | 'deleteMany' | 'deleteAll'; /** if true, all cache layers will be bypassed */ noCache?: boolean; /** Skip these features for this request (blacklist) */ excludeFeatures?: string[]; /** Run only these features, skip all others (whitelist). Cannot be used together with excludeFeatures */ includeFeatures?: string[]; [key: string]: any; } interface FileSystemNode { path: string; size?: number; type: 'blob' | 'tree'; } interface WhereJsonContains { /** Checks for existence of this path inside json object * Example: "meta.countries[0].name". */ path: string; /** Checks if value from "path" is exactly null. Note: it is not the same as not having the key in the object. */ isNull?: boolean; /** Checks if value from "path" equals provided value */ value?: number | string | boolean; } type RadsUiSlotName = 'entityListActions' | 'entityActions' | 'fieldActions'; interface RadsUiSlotDefinition { entityName?: string | { regExp: string; }; fieldName?: string | { regExp: string; }; label: string; icon?: string; endpoint: string; } interface RadsFeature { name: string; radsUiSlots?: Record; init?: (db: Record, context: ComputedContextGlobal) => void; enhanceEntityMethods?: (context: ComputedContext, entityMethodsObj: EntityMethods) => void; beforeGet?: (args: GetArgsAny, ctx: RadsRequestContext, context: ComputedContext) => MaybePromise; afterGet?: (items: any[], args: GetArgsAny, ctx: RadsRequestContext, context: ComputedContext) => MaybePromise; beforePut?: (items: RadsHookDoc[], ctx: RadsRequestContext, computedContext: ComputedContext) => void; afterPut?: (items: RadsHookDoc[], ctx: RadsRequestContext, computedContext: ComputedContext) => void; beforeUploadFile?: (args: FileUploadArgs) => MaybePromise; afterUploadFile?: (result: FileUploadResult, args: FileUploadArgs) => MaybePromise; } export { GetAggArgs as $, RestFileUploadDriverOptions as A, GenerateClientOptions as B, ComputedDecoratorArgs as C, DriverConstructor as D, EntityDecoratorArgs as E, FieldDecoratorArgs as F, GetRestRoutesOptions as G, GenerateClientNormalizedOptions as H, RadsVitePluginOptions as I, FileSystemNode as J, RadsUiSlotName as K, RadsUiSlotDefinition as L, MinimalDriver as M, RadsFeature as N, Change as O, PutEffect as P, GetManyArgs as Q, RadsRequestContext as R, Schema as S, TypeDefinition as T, UiDecoratorArgs as U, ValidateEntityDecoratorArgs as V, WhereJsonContains as W, VerifyManyArgs as X, VerifyManyResponse as Y, Where as Z, GetArgs as _, UiFieldDecoratorArgs as a, GetAggArgsAgg as a0, GetManyArgsAny as a1, GetArgsAny as a2, GetAggArgsAny as a3, VerifyManyArgsAny as a4, GetArgsInclude as a5, GetAggResponse as a6, GetManyResponse as a7, GetResponse as a8, StoredDocumentFields as a9, Get as aa, GetResponseInclude as ab, GetResponseIncludeSelect as ac, GetResponseNoInclude as ad, DeepPartialWithNulls as ae, DeepPartialWithNullsItem as af, DeepPartialArrayItem as ag, DeepPartialWithoutNulls as ah, DeepPartialWithoutNullsItem as ai, DeepPartial as aj, Relation as ak, InverseRelation as al, Put as am, JsonPutOperations as an, DeepKeys as ao, EntityMethods as ap, ValidateFieldDecoratorArgs as b, Driver as c, ComputedContext as d, CreateRadsDbArgs as e, CreateRadsDbClientArgs as f, RadsConfig as g, RadsConfigDataSource as h, RequiredFields as i, ValidateStringDecoratorArgs as j, CreateRadsArgsDrivers as k, RestDriverOptions as l, CreateRadsDbArgsNormalized as m, SchemaLoadResult as n, SchemaValidators as o, FileUploadResult as p, FileUploadDriver as q, RadsDbInstance as r, GetRestRoutesArgs as s, GetRestRoutesResponse as t, FileUploadArgs as u, FieldDefinition as v, EnumDefinition as w, ComputedContextGlobal as x, RadsHookDoc as y, SqlDriverOptions as z };