import { type GrantedRole } from '@dereekb/model'; import { type Getter, type SetIncludesMode, type ArrayOrValue, type UseAsync, type UsePromiseFunction } from '@dereekb/util'; import { type FirestoreDocument } from '../firestore/accessor/document'; import { type FirestoreModelIdentity, type FirestoreModelKey, type FirestoreModelType, type FirestoreModelTypes, type ReadFirestoreModelKeyInput } from '../firestore/collection/collection'; import { type FirebaseModelCollectionLoader, type FirebaseModelLoader, type InContextFirebaseModelCollectionLoader, type InContextFirebaseModelLoader } from './model/model.loader'; import { type InContextFirebaseModelPermissionService, type FirebasePermissionContext, type FirebaseModelPermissionService, type FirebasePermissionServiceInstanceDelegate, type InModelContextFirebaseModelPermissionService, type FirebasePermissionErrorContext } from './permission'; import { type ContextGrantedModelRolesReader } from './permission/permission.service.role'; /** * Context type required by the model service layer — combines permission and error handling contexts. */ export type FirebaseModelServiceContext = FirebasePermissionContext & FirebasePermissionErrorContext; /** * Unified service for a single Firestore model type that combines permission checking, model loading, and collection access. * * Each model type in the application (e.g., Notification, StorageFile) gets its own {@link FirebaseModelService}. * The service is the central point for CRUD operations that need permission-aware model access. * * @template C - the model context type * @template T - the Firestore document data type * @template D - the FirestoreDocument wrapper type * @template R - the granted role type for this model */ export interface FirebaseModelService = FirestoreDocument, R extends GrantedRole = GrantedRole> extends FirebaseModelPermissionService, FirebaseModelLoader, FirebaseModelCollectionLoader { } /** * Lazy getter for a {@link FirebaseModelService}, typically used in the service factory map. */ export type FirebaseModelServiceGetter = FirestoreDocument, R extends GrantedRole = GrantedRole> = Getter>; /** * Configuration for creating a {@link FirebaseModelService} via {@link firebaseModelService}. * * Provides the collection loader and the role-mapping delegate. Model loading is derived automatically * from the collection loader. */ export interface FirebaseModelServiceConfig = FirestoreDocument, R extends GrantedRole = GrantedRole> extends Omit, 'loadModelForKey'>, FirebaseModelCollectionLoader { } /** * Creates a {@link FirebaseModelService} that wires together model loading and permission evaluation. * * @param config - collection loader and role mapping functions * @returns a {@link FirebaseModelService} combining model loading and permission evaluation * * @example * ```ts * const notificationService = firebaseModelService({ * getFirestoreCollection: (context) => context.app.notification, * roleMapForModel: (output, context, model) => computeRoles(output, context) * }); * ``` */ export declare function firebaseModelService = FirestoreDocument, R extends GrantedRole = GrantedRole>(config: FirebaseModelServiceConfig): FirebaseModelService; /** * Cached getter that lazily creates and memoizes a {@link FirebaseModelService}. */ export type FirebaseModelServiceFactory = FirestoreDocument, R extends GrantedRole = GrantedRole> = Getter>; /** * Creates a {@link FirebaseModelServiceFactory} that lazily instantiates and caches the service. * * @param config - the service configuration * @returns a {@link FirebaseModelServiceFactory} that lazily creates and caches the service */ export declare function firebaseModelServiceFactory = FirestoreDocument, R extends GrantedRole = GrantedRole>(config: FirebaseModelServiceConfig): FirebaseModelServiceFactory; /** * A context-bound model service with permission checking, model loading, and collection access. * * Does not include the `forKey` method — use {@link InContextFirebaseModelService} for the full interface. */ export type LimitedInContextFirebaseModelService = FirestoreDocument, R extends GrantedRole = GrantedRole> = InContextFirebaseModelPermissionService & InContextFirebaseModelLoader & InContextFirebaseModelCollectionLoader & { forKey: (key: FirestoreModelKey) => InModelContextFirebaseModelService; }; /** * Full context-bound model service that can also be called directly with a model/key to get a model-bound service. * * Calling `service(modelOrKey)` returns an {@link InModelContextFirebaseModelService} with role checking and assertions. * Also provides `forKey(key)` for key-based lookup. */ export type InContextFirebaseModelService = FirestoreDocument, R extends GrantedRole = GrantedRole> = InModelContextFirebaseModelServiceFactory & LimitedInContextFirebaseModelService; /** * Factory that binds a {@link FirebaseModelService} to a specific context, producing an {@link InContextFirebaseModelService}. */ export type InContextFirebaseModelServiceFactory = FirestoreDocument, R extends GrantedRole = GrantedRole> = (context: C) => InContextFirebaseModelService; /** * Factory that binds a context-aware model service to a specific model document or key. */ export type InModelContextFirebaseModelServiceFactory = FirestoreDocument, R extends GrantedRole = GrantedRole> = (modelOrKey: D | FirestoreModelKey) => InModelContextFirebaseModelService; /** * A model service bound to both a context and a specific model document. * * Provides role-based access control via `roleReader()`, `requireRole()`, and `use()`. * Can be called as a function with roles to get a {@link UsePromiseFunction} for the role reader. */ export type InModelContextFirebaseModelService = FirestoreDocument, R extends GrantedRole = GrantedRole> = InModelContextFirebaseModelPermissionService & InModelContextFirebaseModelServiceUseFunction & InContextFirebaseModelCollectionLoader & { roleReader: () => Promise>; requireRole: (roles: ArrayOrValue, setIncludes?: SetIncludesMode) => Promise>; requireUse: InModelContextFirebaseModelServiceUseFunction; use: UsePromiseFunction>; }; export type InModelContextFirebaseModelServiceUseFunction = FirestoreDocument, R extends GrantedRole = GrantedRole> = (roles: ArrayOrValue, setIncludes?: SetIncludesMode) => UsePromiseFunction>; /** * Creates an {@link InContextFirebaseModelServiceFactory} from a service getter. * * The returned factory, when given a context, produces a callable service that can be invoked * with a model or key to perform permission-checked operations. * * @param factory - lazy getter for the underlying model service * @returns an {@link InContextFirebaseModelServiceFactory} that binds contexts to the service */ export declare function inContextFirebaseModelServiceFactory = FirestoreDocument, R extends GrantedRole = GrantedRole>(factory: FirebaseModelServiceGetter): InContextFirebaseModelServiceFactory; /** * Map of model type identifiers to their corresponding {@link FirebaseModelServiceGetter} factories. * * Defines the full set of model services available in the application. */ export type FirebaseModelsServiceFactory = { [J in FirestoreModelTypes]: FirebaseModelServiceGetter; }; /** * Provides access to the list of all registered model types. */ export type FirebaseModelsServiceTypesAccessor = { allTypes(): FirestoreModelType[]; }; /** * Multi-model service function that returns a context-bound service for any registered model type. * * Call with a model type key and context to get an {@link InContextFirebaseModelService} for that model. * This is the top-level entry point for permission-checked model operations in server-side code. */ export type FirebaseModelsService, C extends FirebaseModelServiceContext> = ((type: K, context: C) => X[K] extends FirebaseModelServiceGetter ? InContextFirebaseModelService : never) & FirebaseModelsServiceTypesAccessor; /** * Extracts the union of model type keys from a {@link FirebaseModelsService}. */ export type FirebaseModelsServiceTypes> = S extends FirebaseModelsService ? keyof X : never; /** * Creates a new FirebaseModelsService. * * When a context is passed, it is extended and the services are available in the context too as a services function. * * This allows the services function to reference itself in usage. You do this by creating another type that extends the context. Example: * * export type DemoFirebaseBaseContext = FirebaseAppModelContext; * ... * export const demoFirebaseModelServices = firebaseModelsService(DEMO_FIREBASE_MODEL_SERVICE_FACTORIES); * export type DemoFirebaseContext = DemoFirebaseBaseContext & { service: typeof demoFirebaseModelServices }; * * @param services - the map of model service getter factories * @returns a {@link FirebaseModelsService} that dispatches to the appropriate model service by type */ export declare function firebaseModelsService, C extends FirebaseModelServiceContext, I extends FirestoreModelIdentity = FirestoreModelIdentity>(services: X): FirebaseModelsService; /** * A context-bound multi-model service — call with a model type to get the context-bound single-model service. */ export type InContextFirebaseModelsService = FirebaseModelsServiceTypesAccessor & (Y extends FirebaseModelsService ? (type: K) => X[K] extends FirebaseModelServiceGetter ? InContextFirebaseModelService : never : never); /** * Factory that creates an {@link InContextFirebaseModelsService} from a context. */ export type InContextFirebaseModelsServiceFactory = FirebaseModelsServiceTypesAccessor & (Y extends FirebaseModelsService ? (context: C) => InContextFirebaseModelsService : never); /** * Creates an {@link InContextFirebaseModelsServiceFactory} from a {@link FirebaseModelsService}. * * The returned factory binds a context, so callers can then select individual model services by type. * * @param service - the multi-model service to wrap * @returns an {@link InContextFirebaseModelsServiceFactory} that binds a context to the service */ export declare function inContextFirebaseModelsServiceFactory, C extends FirebaseModelServiceContext, I extends FirestoreModelIdentity = FirestoreModelIdentity>(service: FirebaseModelsService): InContextFirebaseModelsServiceFactory>; /** * Selection parameters for accessing a specific model by type and key (without role requirements). */ export type FirebaseModelsServiceSelection, T extends FirebaseModelsServiceTypes> = Omit, 'roles' | 'rolesSetIncludes'>; export type FirebaseModelsServiceSelectionResult, T extends FirebaseModelsServiceTypes> = Y extends FirebaseModelsService ? (T extends keyof X ? (X[T] extends FirebaseModelServiceGetter ? InModelContextFirebaseModelService : never) : never) : never; export type FirebaseModelsServiceSelectionResultRolesReader, T extends FirebaseModelsServiceTypes> = Y extends FirebaseModelsService ? (T extends keyof X ? (X[T] extends FirebaseModelServiceGetter ? ContextGrantedModelRolesReader : never) : never) : never; export type FirebaseModelsServiceSelectionResultDocumentType, T extends FirebaseModelsServiceTypes> = Y extends FirebaseModelsService ? (T extends keyof X ? (X[T] extends FirebaseModelServiceGetter ? D : never) : never) : never; export type UseFirebaseModelsServiceSelection, T extends FirebaseModelsServiceTypes> = Y extends FirebaseModelsService ? X extends FirebaseModelsServiceFactory> ? { context: C; key: X[T] extends FirebaseModelServiceGetter ? ReadFirestoreModelKeyInput : ReadFirestoreModelKeyInput; roles?: X[T] extends FirebaseModelServiceGetter ? ArrayOrValue : never; rolesSetIncludes?: SetIncludesMode; } : never : never; export type UseFirebaseModelsServiceSelectionResult, T extends FirebaseModelsServiceTypes> = Y extends FirebaseModelsService ? (T extends keyof X ? (X[T] extends FirebaseModelServiceGetter ? UsePromiseFunction> : never) : never) : never; export type UseFirebaseModelsServiceSelectionUseFunction, T extends FirebaseModelsServiceTypes, O> = Y extends FirebaseModelsService ? (T extends keyof X ? (X[T] extends FirebaseModelServiceGetter ? UseAsync, O> : never) : never) : never; /** * Selects a model-bound service instance from a multi-model service by type and key. * * @param service - the multi-model service * @param type - the model type to select * @param select - selection params including context and key * @returns the {@link FirebaseModelsServiceSelectionResult} bound to the specified model */ export declare function selectFromFirebaseModelsService, T extends FirebaseModelsServiceTypes>(service: Y, type: T, select: FirebaseModelsServiceSelection): FirebaseModelsServiceSelectionResult; /** * Selects a model-bound service and returns a {@link UsePromiseFunction} that lazily evaluates roles on use. * * If roles are provided, uses `requireUse` to assert them. Otherwise, returns the basic `use` function. * * @param service - the multi-model service * @param type - the model type to select * @param select - selection params including context, key, and optional role requirements * @returns a {@link UsePromiseFunction} for the resolved roles reader */ export declare function useFirebaseModelsService, T extends FirebaseModelsServiceTypes>(service: Y, type: T, select: UseFirebaseModelsServiceSelection): UseFirebaseModelsServiceSelectionResult; /** * Builds a type map from collection type to {@link FirestoreModelIdentity} for all registered models. * * Useful for routing incoming requests to the correct model service by collection path. * * @param inContextFirebaseModelsService - context-bound multi-model service * @returns a map of collection type strings to their {@link FirestoreModelIdentity} objects */ export declare function buildFirebaseCollectionTypeModelTypeMap>(inContextFirebaseModelsService: InContextFirebaseModelsService): import("..").FirestoreModelIdentityTypeMap;