harperdb
Version:
HarperDB is a distributed database, caching service, streaming broker, and application development platform focused on performance and ease of use.
156 lines (155 loc) • 7.86 kB
TypeScript
import type { User } from '../security/user.ts';
import type { RecordObject } from './RecordEncoder.js';
import { ResourceInterface, SubscriptionRequest, Id, Context, Query, SourceContext, RequestTargetOrId } from './ResourceInterface.ts';
import { type Transaction } from './DatabaseTransaction.ts';
import { IterableEventQueue } from './IterableEventQueue.ts';
import { AsyncLocalStorage } from 'async_hooks';
import { RequestTarget } from './RequestTarget.ts';
export declare const contextStorage: AsyncLocalStorage<Context>;
/**
* This is the main class that can be extended for any resource in HarperDB and provides the essential reusable
* uniform interface for interacting with data, defining the API for providing data (data sources) and for consuming
* data. This interface is used pervasively in HarperDB and is implemented by database tables and can be used to define
* sources for caching, real-data sources for messaging protocols, and RESTful endpoints, as well as any other types of
* data aggregation, processing, or monitoring.
*
* This base Resource class provides a set of static methods that are main entry points for querying and updating data
* in resources/tables. The static methods provide the default handling of arguments, context, and ensuring that
* internal actions are wrapped in a transaction. The base Resource class intended to be extended, and the instance
* methods can be overridden to provide specific implementations of actions like get, put, post, delete, and subscribe.
*/
export declare class Resource<Record extends object = any> implements ResourceInterface<Record> {
#private;
static transactions: Transaction[] & {
timestamp: number;
};
static directURLMapping: boolean;
static loadAsInstance: boolean;
constructor(identifier: Id, source: any);
/**
* The get methods are for directly getting a resource, and called for HTTP GET requests.
*/
static get: {
(idOrQuery: string | Id | Query, dataOrContext?: any, context?: Context): any;
reliesOnPrototype: boolean;
};
/**
* Store the provided record by the provided id. If no id is provided, it is auto-generated.
*/
static put: {
(idOrQuery: string | Id | Query, dataOrContext?: any, context?: Context): any;
reliesOnPrototype: boolean;
};
static patch: {
(idOrQuery: string | Id | Query, dataOrContext?: any, context?: Context): any;
reliesOnPrototype: boolean;
};
static delete: {
(idOrQuery: string | Id | Query, dataOrContext?: any, context?: Context): any;
reliesOnPrototype: boolean;
};
/**
* Generate a new primary key for a resource; by default we use UUIDs (for now).
*/
static getNewId(): `${string}-${string}-${string}-${string}-${string}`;
/**
* Create a new resource with the provided record and id. If no id is provided, it is auto-generated. Note that this
* facilitates creating a new resource, but does not guarantee that this is not overwriting an existing entry.
* @param idPrefix
* @param record
* @param context
*/
static create(idPrefix: Id, record: any, context: Context): Promise<Id>;
static create(record: any, context: Context): Promise<Id>;
static invalidate: {
(idOrQuery: string | Id | Query, dataOrContext?: any, context?: Context): any;
reliesOnPrototype: boolean;
};
static post: {
(idOrQuery: string | Id | Query, dataOrContext?: any, context?: Context): any;
reliesOnPrototype: boolean;
};
static update: {
(idOrQuery: string | Id | Query, dataOrContext?: any, context?: Context): any;
reliesOnPrototype: boolean;
};
static connect: {
(idOrQuery: string | Id | Query, dataOrContext?: any, context?: Context): any;
reliesOnPrototype: boolean;
};
static subscribe: {
(idOrQuery: string | Id | Query, dataOrContext?: any, context?: Context): any;
reliesOnPrototype: boolean;
};
static publish: {
(idOrQuery: string | Id | Query, dataOrContext?: any, context?: Context): any;
reliesOnPrototype: boolean;
};
static search: {
(idOrQuery: string | Id | Query, dataOrContext?: any, context?: Context): any;
reliesOnPrototype: boolean;
};
static query: {
(idOrQuery: string | Id | Query, dataOrContext?: any, context?: Context): any;
reliesOnPrototype: boolean;
};
static copy: {
(idOrQuery: string | Id | Query, dataOrContext?: any, context?: Context): any;
reliesOnPrototype: boolean;
};
static move: {
(idOrQuery: string | Id | Query, dataOrContext?: any, context?: Context): any;
reliesOnPrototype: boolean;
};
post(target: RequestTargetOrId, newRecord: Partial<Record & RecordObject>): Promise<Record & Partial<RecordObject>>;
static isCollection(resource: any): any;
get isCollection(): boolean;
static coerceId(id: string): number | string;
static parseQuery(search: any, query: any): any;
static parsePath(path: any, context: any, query: any): any;
/**
* Gets an instance of a resource by id
* @param id
* @param request
* @param options
* @returns
*/
static getResource(id: Id, request: Context | SourceContext, options?: any): Resource | Promise<Resource>;
/**
* This is called by protocols that wish to make a subscription for real-time notification/updates.
* This default implementation simply provides a streaming iterator that does not deliver any notifications
* but implementors can call send with
*/
subscribe(request: SubscriptionRequest): AsyncIterable<Record>;
connect(target: RequestTarget, incomingMessages: IterableEventQueue): AsyncIterable<any>;
allowRead(user: User, target: RequestTarget, context: Context): boolean | Promise<boolean>;
allowUpdate(user: User, record: Promise<Record & RecordObject>, context: Context): boolean | Promise<boolean>;
allowCreate(user: User, record: Promise<Record & RecordObject>, context: Context): boolean | Promise<boolean>;
allowDelete(user: User, target: RequestTarget, context: Context): boolean | Promise<boolean>;
/**
* Get the primary key value for this resource.
* @returns primary key
*/
getId(): Id;
/**
* Get the context for this resource
* @returns context object with information about the current transaction, user, and more
*/
getContext(): Context | SourceContext;
get?(target?: RequestTargetOrId): (Record & Partial<RecordObject>) | Promise<Record & Partial<RecordObject>> | AsyncIterable<Record & Partial<RecordObject>> | Promise<AsyncIterable<Record & Partial<RecordObject>>>;
search?(target: RequestTargetOrId): AsyncIterable<Record & Partial<RecordObject>>;
create?(newRecord: Partial<Record & RecordObject>, target: RequestTargetOrId): Promise<Record & Partial<RecordObject>>;
put?(record: Record & RecordObject, target: RequestTargetOrId): void | (Record & Partial<RecordObject>) | Promise<void | (Record & Partial<RecordObject>)>;
patch?(record: Partial<Record & RecordObject>, target: RequestTargetOrId): void | (Record & Partial<RecordObject>) | Promise<void | (Record & Partial<RecordObject>)>;
delete?(target: RequestTargetOrId): boolean | Promise<boolean>;
invalidate?(target: RequestTargetOrId): void | Promise<void>;
publish?(target: RequestTargetOrId, record: Record, options?: any): void;
}
export declare function snakeCase(camelCase: string): string;
/**
* An array for ids that toString's back to slash-delimited string
*/
export declare class MultiPartId extends Array {
toString(): string;
}
export declare function transformForSelect(select: any, resource: any): (object: any) => any;