UNPKG

@opra/sqb

Version:

Opra SQB adapter package

432 lines (431 loc) 17.1 kB
import { ComplexType } from '@opra/common'; import { ExecutionContext, ServiceBase } from '@opra/core'; import { SqlElement } from '@sqb/builder'; import { EntityMetadata, Repository } from '@sqb/connect'; import type { Nullish, PartialDTO, PatchDTO, RequiredSome, StrictOmit, Type } from 'ts-gems'; import { vg } from 'valgen'; import { SQBAdapter } from './sqb-adapter.js'; import { SqbServiceBase } from './sqb-service-base.js'; /** * Namespace containing types and options for SqbEntityService. */ export declare namespace SqbEntityService { /** * Configuration options for SqbEntityService. */ interface Options extends SqbServiceBase.Options { /** * The name of the resource managed by this service. */ resourceName?: SqbEntityService<any>['resourceName']; /** * Optional error handler. */ onError?: SqbEntityService<any>['onError']; /** * Optional common filter applied to all read/write operations. */ commonFilter?: SqbEntityService<any>['commonFilter']; /** * Optional interceptor for the service operations. */ interceptor?: SqbEntityService<any>['interceptor']; /** * Optional scope for the service. */ scope?: SqbEntityService<any>['scope']; } /** * Represents the CRUD operation types. */ type CrudOp = 'create' | 'read' | 'update' | 'delete'; /** * Information about the command being executed. */ interface CommandInfo { crud: SqbEntityService.CrudOp; method: string; byId: boolean; documentId?: SQBAdapter.IdOrIds; input?: Record<string, any>; options?: Record<string, any>; } /** * Type definition for a common filter. */ type CommonFilter = SQBAdapter.FilterInput | ((args: SqbEntityService.CommandInfo, _this: SqbEntityService<any>) => SQBAdapter.FilterInput | Promise<SQBAdapter.FilterInput> | undefined); interface CreateOptions extends Repository.CreateOptions { } interface CountOptions extends StrictOmit<Repository.CountOptions, 'filter'> { filter?: Repository.CountOptions['filter'] | string; } interface DeleteOptions extends StrictOmit<Repository.DeleteOptions, 'filter'> { filter?: Repository.DeleteOptions['filter'] | string; } interface DeleteManyOptions extends StrictOmit<Repository.DeleteManyOptions, 'filter'> { filter?: Repository.DeleteManyOptions['filter'] | string; } interface ExistsOptions extends StrictOmit<Repository.ExistsOptions, 'filter'> { filter?: Repository.ExistsOptions['filter'] | string; } interface FindOneOptions extends StrictOmit<Repository.FindOneOptions, 'filter' | 'offset'> { filter?: Repository.FindOneOptions['filter'] | string; skip?: number; } interface FindManyOptions extends StrictOmit<Repository.FindManyOptions, 'filter' | 'offset'> { filter?: Repository.FindManyOptions['filter'] | string; skip?: number; } interface UpdateOneOptions extends StrictOmit<Repository.UpdateOptions, 'filter'> { filter?: Repository.UpdateOptions['filter'] | string; } interface UpdateManyOptions extends StrictOmit<Repository.UpdateManyOptions, 'filter'> { filter?: Repository.UpdateManyOptions['filter'] | string; } interface CreateCommand<T> extends StrictOmit<RequiredSome<CommandInfo, 'input'>, 'documentId'> { crud: 'create'; input: PatchDTO<T>; options?: CreateOptions; } interface CountCommand extends StrictOmit<CommandInfo, 'documentId' | 'input'> { crud: 'read'; options?: CountOptions; } interface DeleteOneCommand extends StrictOmit<CommandInfo, 'input'> { crud: 'delete'; options?: DeleteOptions; } interface DeleteManyCommand extends StrictOmit<CommandInfo, 'input'> { crud: 'delete'; options?: DeleteManyOptions; } interface ExistsCommand extends StrictOmit<CommandInfo, 'input'> { crud: 'read'; options?: ExistsOptions; } interface FindOneCommand extends StrictOmit<CommandInfo, 'input'> { crud: 'read'; options?: FindOneOptions; } interface FindManyCommand extends StrictOmit<CommandInfo, 'input'> { crud: 'read'; options?: FindManyOptions; } interface UpdateOneCommand<T> extends CommandInfo { crud: 'update'; input: PatchDTO<T, SqlElement>; options?: UpdateOneOptions; } interface UpdateManyCommand<T> extends CommandInfo { crud: 'update'; input: PatchDTO<T, SqlElement>; options?: UpdateManyOptions; } } export interface SqbEntityService { /** * Optional interceptor that wraps every command execution. * * @param next - Calls the next interceptor or the actual command handler. * @param command - Metadata describing the current operation. * @param _this - Reference to the service instance. * @returns The result of the command execution. */ interceptor?(next: () => any, command: SqbEntityService.CommandInfo, _this: any): Promise<any>; } /** * Base service providing CRUD operations over an SQB entity. * * @typeParam T - The entity type managed by this service */ export declare class SqbEntityService<T extends object = object> extends SqbServiceBase { protected _dataTypeScope?: string; protected _dataType_: Type | string; protected _dataType?: ComplexType; protected _dataTypeClass?: Type; protected _entityMetadata?: EntityMetadata; protected _inputCodecs: Record<string, vg.isObject.Validator<T>>; protected _outputCodecs: Record<string, vg.isObject.Validator<T>>; /** * Comma-delimited scopes used to filter the API document. */ scope?: string; /** * Override for the resource name exposed in error messages and API metadata. * Accepts a static string or a function that returns one. */ resourceName?: string | ((_this: this) => string); /** * Filter(s) automatically applied to every query for this service. * Useful for multi-tenant isolation or other cross-cutting constraints. */ commonFilter?: SqbEntityService.CommonFilter | SqbEntityService.CommonFilter[]; /** * Called whenever a command throws. Useful for logging or transforming errors. * * @param error - The thrown error. * @param command - The service command during which the error was thrown. * @param _this - The service instance. */ onError?: (error: unknown, command: SqbEntityService.CommandInfo, _this: any) => void | Promise<void>; /** * Constructs a new instance. * * @param dataType - The entity class or its registered name. * @param options - Options for the service. */ constructor(dataType: Type<T> | string, options?: SqbEntityService.Options); /** * Returns the resolved OPRA `ComplexType` for this service's entity. * * @throws If the data type is not registered as a `ComplexType`. */ get dataType(): ComplexType; /** * Returns the constructor class of the entity data type. * * @throws If the data type is not registered as a `ComplexType`. */ get dataTypeClass(): Type; /** * Returns the SQB `EntityMetadata` for the entity class. * * @throws If the class is not decorated with `@Entity()`. */ get entityMetadata(): EntityMetadata; for<C extends ExecutionContext, P extends Partial<this>>(context: C | ServiceBase, overwriteProperties?: Nullish<P>, overwriteContext?: Partial<C>): this & Required<P>; /** * Returns the resource name used in error messages and API metadata. * * @throws If neither `resourceName` nor the data type name is available. */ getResourceName(): string; /** * Returns the input codec for the given operation (e.g. `'create'`, `'update'`). * * @param operation - The operation name. */ getInputCodec(operation: string): vg.isObject.Validator<T>; /** * Returns the output codec for the given operation. * * @param operation - The operation name. */ getOutputCodec(operation: string): vg.isObject.Validator<T>; /** * Inserts a new record into the database and returns the created document. * * @param command - The create command. * @returns The created document. * @protected */ protected _create(command: SqbEntityService.CreateCommand<T>): Promise<PartialDTO<T>>; /** * Inserts a new record into the database without returning it. * * @param command - The create command. * @protected */ protected _createOnly(command: SqbEntityService.CreateCommand<T>): Promise<any>; /** * Returns the count of records matching the command options. * * @param command - The count command. * @protected */ protected _count(command: SqbEntityService.CountCommand): Promise<number>; /** * Deletes the record identified by `command.documentId`. * * @param command - The delete command. * @returns The number of records deleted. * @protected */ protected _delete(command: SqbEntityService.DeleteOneCommand): Promise<number>; /** * Deletes all records matching the command filter. * * @param command - The deleteMany command. * @returns The number of records deleted. * @protected */ protected _deleteMany(command: SqbEntityService.DeleteManyCommand): Promise<number>; /** * Checks whether the record identified by `command.documentId` exists. * * @param command - The exists command. * @protected */ protected _exists(command: SqbEntityService.ExistsCommand): Promise<boolean>; /** * Checks whether any record matching the command filter exists. * * @param command - The existsOne command. * @protected */ protected _existsOne(command: SqbEntityService.ExistsCommand): Promise<boolean>; /** * Finds the record identified by `command.documentId`. * * @param command - The findById command. * @returns The found record, or `undefined` if not found. * @protected */ protected _findById(command: SqbEntityService.FindOneCommand): Promise<PartialDTO<T> | undefined>; /** * Finds the first record matching the command filter. * * @param command - The findOne command. * @returns The found record, or `undefined` if not found. * @protected */ protected _findOne(command: SqbEntityService.FindOneCommand): Promise<PartialDTO<T> | undefined>; /** * Finds all records matching the command filter. * * @param command - The findMany command. * @returns An array of matching records. * @protected */ protected _findMany(command: SqbEntityService.FindManyCommand): Promise<PartialDTO<T>[]>; /** * Updates the record identified by `command.documentId` and returns it. * * @param command - The update command. * @returns The updated record, or `undefined` if not found. * @protected */ protected _update(command: SqbEntityService.UpdateOneCommand<T>): Promise<PartialDTO<T> | undefined>; /** * Updates the record identified by `command.documentId` without returning it. * * @param command - The updateOnly command. * @returns The number of records modified. * @protected */ protected _updateOnly(command: SqbEntityService.UpdateOneCommand<T>): Promise<number>; /** * Updates all records matching the command filter. * * @param command - The updateMany command. * @returns The number of records modified. * @protected */ protected _updateMany(command: SqbEntityService.UpdateOneCommand<T>): Promise<number>; /** * Acquires a connection and performs `Repository.create`. * * @param input - The document to insert. * @param options - Optional settings. * @protected */ protected _dbCreate(input: PartialDTO<T>, options?: Repository.CreateOptions): Promise<PartialDTO<T>>; /** * Acquires a connection and performs `Repository.count`. * * @param options - Optional settings. * @protected */ protected _dbCount(options?: Repository.CountOptions): Promise<number>; /** * Acquires a connection and performs `Repository.delete`. * * @param id - The key field value identifying the record. * @param options - Optional settings. * @protected */ protected _dbDelete(id: SQBAdapter.IdOrIds, options?: Repository.DeleteOptions): Promise<number>; /** * Acquires a connection and performs `Repository.deleteMany`. * * @param options - Optional settings. * @protected */ protected _dbDeleteMany(options?: Repository.DeleteManyOptions): Promise<number>; /** * Acquires a connection and performs `Repository.exists`. * * @param id - The key field value identifying the record. * @param options - Optional settings. * @protected */ protected _dbExists(id: SQBAdapter.IdOrIds, options?: Repository.ExistsOptions): Promise<boolean>; /** * Acquires a connection and performs `Repository.existsOne`. * * @param options - Optional settings. * @protected */ protected _dbExistsOne(options?: Repository.ExistsOptions): Promise<boolean>; /** * Acquires a connection and performs `Repository.findById`. * * @param id - The key field value identifying the record. * @param options - Optional settings. * @protected */ protected _dbFindById(id: SQBAdapter.IdOrIds, options?: Repository.FindOptions): Promise<PartialDTO<T> | undefined>; /** * Acquires a connection and performs `Repository.findOne`. * * @param options - Optional settings. * @protected */ protected _dbFindOne(options?: StrictOmit<Repository.FindOneOptions, 'offset'> & { skip?: number; }): Promise<PartialDTO<T> | undefined>; /** * Acquires a connection and performs `Repository.findMany`. * * @param options - Optional settings. * @protected */ protected _dbFindMany(options?: StrictOmit<Repository.FindManyOptions, 'offset'> & { skip?: number; }): Promise<PartialDTO<T>[]>; /** * Acquires a connection and performs `Repository.update`. * * @param id - The key field value identifying the record. * @param data - The update values. * @param options - Optional settings. * @protected */ protected _dbUpdate(id: SQBAdapter.IdOrIds, data: PatchDTO<T>, options?: Repository.UpdateOptions): Promise<PartialDTO<T> | undefined>; /** * Acquires a connection and performs `Repository.updateOnly`. * * @param id - The key field value identifying the record. * @param data - The update values. * @param options - Optional settings. * @protected */ protected _dbUpdateOnly(id: SQBAdapter.IdOrIds, data: PatchDTO<T>, options?: Repository.UpdateOptions): Promise<number>; /** * Acquires a connection and performs `Repository.updateMany`. * * @param data - The update values. * @param options - Optional settings. * @protected */ protected _dbUpdateMany(data: PatchDTO<T>, options?: Repository.UpdateManyOptions): Promise<number>; /** * Builds the common filter for the given command. * Used primarily for multi-tenant isolation and similar cross-cutting concerns. * * @protected * @returns The resolved filter input, or `undefined` if none is configured. */ protected _getCommonFilter(command: SqbEntityService.CommandInfo): SQBAdapter.FilterInput | Promise<SQBAdapter.FilterInput> | undefined; protected _executeCommand(command: SqbEntityService.CommandInfo, commandFn: () => any): Promise<any>; protected _beforeCreate(command: SqbEntityService.CreateCommand<T>): Promise<void>; protected _beforeUpdate(command: SqbEntityService.UpdateOneCommand<T>): Promise<void>; protected _beforeUpdateMany(command: SqbEntityService.UpdateManyCommand<T>): Promise<void>; protected _beforeDelete(command: SqbEntityService.DeleteOneCommand): Promise<void>; protected _beforeDeleteMany(command: SqbEntityService.DeleteManyCommand): Promise<void>; protected _afterCreate(command: SqbEntityService.CreateCommand<T>, result: PartialDTO<T>): Promise<void>; protected _afterUpdate(command: SqbEntityService.UpdateOneCommand<T>, result?: PartialDTO<T>): Promise<void>; protected _afterUpdateMany(command: SqbEntityService.UpdateManyCommand<T>, affected: number): Promise<void>; protected _afterDelete(command: SqbEntityService.DeleteOneCommand, affected: number): Promise<void>; protected _afterDeleteMany(command: SqbEntityService.DeleteManyCommand, affected: number): Promise<void>; }