import { type CallContext } from 'nice-grpc';
import { Logger } from '@restorecommerce/logger';
import { Client } from '@restorecommerce/grpc-client';
import { UserServiceDefinition } from '@restorecommerce/rc-grpc-clients/dist/generated-server/io/restorecommerce/user.js';
import { type ResourceList, type ResourceListResponse, type DeleteRequest, ReadRequest } from '@restorecommerce/rc-grpc-clients/dist/generated-server/io/restorecommerce/resource_base.js';
import { Operation, ACSResource, AuthZAction, ACSClientContext } from './interfaces.js';
import { Subject } from '@restorecommerce/rc-grpc-clients/dist/generated-server/io/restorecommerce/auth.js';
export type AccessControlledServiceRequest = ResourceList & ReadRequest;
export type DatabaseProvider = 'arangoDB' | 'postgres';
export type ResourceFactory<T extends ResourceList> = (self: any, request: T, ...args: any) => Promise<ACSResource[]>;
export type MetaDataInjector<T extends ResourceList> = (self: any, request: T, ...args: any) => Promise<T>;
export type SubjectResolver<T extends AccessControlledServiceRequest> = (self: any, request: T, ...args: any) => Promise<T>;
export type DatabaseSelector<T extends AccessControlledServiceRequest> = (self: any, request: T, ...args: any) => Promise<DatabaseProvider>;
export type ACSClientContextFactory<T extends AccessControlledServiceRequest> = (self: any, request: T, ...args: any) => Promise<ACSClientContext>;
/**
 * @param action AuthZAction of that function (required),
 * @param opatation Operation [isAllowed | whatIsAllowed] (required),
 * @param subject SubjectResolver should resolve the subject.id by a given token (default: DefaultSubjectResolver)
 * @param meta MetaDataInjector should inject meta data to each item of resource (default: DefaultMetaDataInjector)
 * @param context ACSClientContext | ACSClientContextFactory should provide a static of dynamic ACSContext (default: DefaultACSClientContextFactory)
 * @param resource ACSResource[] | ResourceFactory should provide a static or dynamic ACSResource (default: DefaultResourceFactory)
 * @param database DatabaseProvider | DatabaseSelector -  (detault: cfg.get('authorization:database') ?? 'arangoDB')
 * @param useCache boolean (default: cfg.get('authorization:cache:enabled') ?? false)
 */
export type AccessControlledFunctionOptions<T> = {
    action: AuthZAction;
    operation: Operation;
    subject?: SubjectResolver<T> | null;
    meta?: MetaDataInjector<T> | null;
    context?: ACSClientContext | ACSClientContextFactory<T>;
    resource?: ACSResource[] | ResourceFactory<T>;
    database?: DatabaseProvider | DatabaseSelector<T>;
    useCache?: boolean;
};
export interface AccessControllableService {
    name: string;
    /**
     * Get resources by ID.
     * Required by access controllable services for checking inner state!
     *
     * @param ids - a list of requested resource.id(s)
     * @param subject - the calling subject
     * @param context - incomming grpc + http header context
     * @param bypassACS - set true during inner ACS calles to avoid recursive loops!
     */
    get(ids: string[], subject?: Subject, context?: CallContext, bypassACS?: boolean): Promise<ResourceListResponse>;
}
export interface AccessControlledService extends AccessControllableService {
    readonly __userService: Client<UserServiceDefinition>;
    readonly __acsDatabaseProvider: DatabaseProvider;
    readonly logger?: Logger;
}
export declare const DefaultACSClientContextFactory: <T extends AccessControlledServiceRequest>(self: AccessControllableService, request: T & DeleteRequest, context?: CallContext) => Promise<ACSClientContext>;
export declare const DefaultResourceFactory: <T extends ResourceList>(...resourceNames: string[]) => ResourceFactory<T>;
export declare const DefaultResourceFactoryInstance: ResourceFactory<ResourceList>;
export declare const DefaultSubjectResolver: <T extends ResourceList>(self: any, request: T, ...args: any) => Promise<T>;
export declare const DefaultMetaDataInjector: <T extends ResourceList>(self: any, request: T, ...args: any) => Promise<T>;
export declare function access_controlled_service<T extends {
    new (...args: any): AccessControllableService;
}>(baseService: T): T;
export declare function access_controlled_function<T extends AccessControlledServiceRequest>(kwargs: AccessControlledFunctionOptions<T>): any;
export declare function resolves_subject<T extends ResourceList>(subjectResolver?: SubjectResolver<T>): any;
export declare function injects_meta_data<T extends ResourceList>(metaDataInjector?: MetaDataInjector<T>): any;
//# sourceMappingURL=decorators.d.ts.map