import type { Firestore } from '@google-cloud/firestore'; import type { auth } from 'firebase-admin'; import type { BigQueryClient } from './bigquery.mjs'; import type { Logger } from './logger.mjs'; import type { PostgresClient } from './postgres.mjs'; export type Auth = auth.Auth; export type { BigQueryClient, PostgresClient }; export type BaseContext = { readonly env: E; readonly logger: Logger; readonly db: { firestore?: Firestore; postgres?: PostgresClient; bigquery?: BigQueryClient; }; readonly authClient?: Auth; }; export type SimpleContext = { readonly correlationId: string; readonly role: string; readonly userId: string; }; export type TenantContext = SimpleContext & { readonly tenantId: string; }; export type RequestContext = TenantContext & { readonly organisationType: string; }; export type RequestWithContext = BaseContext & { readonly ctx: RequestContext; readonly requestLogger: Logger; }; export type RepoContext = { readonly repoFns: Record>; readonly repo: Record Promise>>; }; export type ServicesContext = { readonly serviceFns: Record>; readonly services: Record Promise>>; }; export type AuthContext = { readonly authFns?: Record>; readonly auth?: Record Promise>>; }; export type CmdsContext = { readonly cmdFns: Record>; readonly cmds: Record Promise>>; }; export type AppContext = RequestWithContext & RepoContext & ServicesContext & AuthContext & CmdsContext; export type Ok = { ok: true; value: T; }; export type Err = { ok: false; error: AppError; }; export type Result = Ok | Err; export type AppError = { code: 'NOT_FOUND' | 'CONFLICT' | 'SERVICE_UNAVAILABLE' | 'VALIDATION_ERROR' | 'UNAUTHORIZED' | 'FORBIDDEN' | 'DATA_CORRUPTION'; message: string; cause?: Error | unknown; data?: unknown; }; export type FirestoreRepoFn = { dbType: 'firestore'; fn: (db: Firestore, ctx: RequestContext, logger: Logger) => (args: A) => Promise>; }; export type PostgresRepoFn = { dbType: 'postgres'; adapter?: 'query' | 'transaction'; fn: (db: PostgresClient['query'] | PostgresClient['transaction'], ctx: RequestContext, logger: Logger) => (args: A) => Promise>; }; export type BigQueryRepoFn = { dbType: 'bigquery'; fn: (db: BigQueryClient, ctx: RequestContext, logger: Logger) => (args: A) => Promise>; }; export type RepoFn = FirestoreRepoFn | PostgresRepoFn | BigQueryRepoFn; export type WrappedFirestoreRepoFn> = F extends FirestoreRepoFn ? (args: A) => Promise> : never; export type ServiceFn = (ctx: RequestContext, logger: Logger) => (args: A) => Promise; export type WrappedServiceFn> = F extends ServiceFn ? (args: A) => Promise> : never; export type FirebaseAuthFn = (auth: Auth, ctx: RequestContext, logger: Logger) => (args: A) => Promise>; export type WrappedFirebaseAuthFn> = F extends FirebaseAuthFn ? (args: A) => Promise> : never; export type CommandFn = (deps: { repo: Re; services: Se; auth: Au; }, ctx: RequestContext, logger: Logger) => (args: A) => Promise>; export type WrappedCommandFn> = F extends CommandFn ? (args: A) => Promise> : never; export type SuccessResponse = { code: 'SUCCESS'; data: T; }; export type NotFoundResponse = { code: 'NOT_FOUND'; data: { message: string; }; }; export type ConflictResponse = { code: 'CONFLICT'; data: { message: string; }; }; export type InternalServerErrorResponse = { code: 'INTERNAL_SERVER_ERROR'; data: { message: string; }; }; export type ServiceUnavailableResponse = { code: 'SERVICE_UNAVAILABLE'; data: { message: string; }; }; export type HttpResponse = SuccessResponse | NotFoundResponse | ConflictResponse | InternalServerErrorResponse | ServiceUnavailableResponse;