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 { RequestTarget } from './RequestTarget.ts';
/**
 * This is the main class that can be extended for any resource in Harper 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 Harper 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(target: RequestTarget, 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<Record>): AsyncIterable<Record>;
    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 the current user for the current request, based on the context.
     * @returns user object or undefined if no user is logged in
     */
    getCurrentUser(): User | undefined;
    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;
export declare function missingMethod(resource: any, method: string): void;
export declare function allowedMethods(resource: any): any[];
export declare function transformForSelect(select: any, resource: any): (object: any) => any;
