import { Request as Request$1, Response as Response$1, NextFunction as NextFunction$1, Express as Express$1, Router as Router$1 } from 'express'; /** * Authentication & Authorization Types * Shared across core, sdk, cli, and app packages */ /** * Base user interface */ interface User { id: string; email: string; firstName?: string; lastName?: string; avatar?: string; role?: Role; role_Id?: string; tenant_Id?: string; status?: string; createdAt?: string; updatedAt?: string; [key: string]: unknown; } /** * User with password (internal use only) */ interface UserWithPassword extends User { password?: string; } /** * User with expanded roles and permissions */ interface UserWithRolesAndPermissions { id: string | number; email?: string; roles: string[]; permissions: string[]; tenantId?: string | number; [key: string]: unknown; } /** * Role interface */ interface Role { id: string; name: string; description?: string; isTenantSpecific?: boolean; [key: string]: unknown; } /** * Permission action types */ type PermissionAction = "create" | "read" | "update" | "delete"; /** * Permission interface */ interface Permission { id: string; role_Id: string; collection: string; action: PermissionAction; fields?: string[] | null; conditions?: Record; defaultValues?: Record; relConditions?: Record; /** WITH CHECK filter — see PermissionData.checkConditions */ checkConditions?: Record | null; } /** * Permission data structure (internal to PermissionService) */ interface PermissionData { fields: string[] | null; conditions: Record; relConditions: Record; defaultValues: Record; /** * WITH CHECK (RLS-style) filter: what a written row must satisfy, enforced * post-write pre-commit on both create and update. null/absent = no check. * `conditions` never applies to create grants. */ checkConditions?: Record | null; } /** * Data for creating a new permission */ interface CreatePermissionData { role_Id: string; collection: string; action: PermissionAction; fields?: string[]; conditions?: Record; defaultValues?: Record; relConditions?: Record; /** WITH CHECK filter — see PermissionData.checkConditions */ checkConditions?: Record | null; } /** * Tenant interface */ interface Tenant { id: string; name: string; [key: string]: unknown; } /** * Session interface */ interface Session { id: string; token: string; user_Id: string; expiresAt: Date | string; ipAddress?: string; userAgent?: string; createdAt?: string; updatedAt?: string; } /** * Auth tokens */ interface AuthTokens { accessToken: string; refreshToken?: string; expiresAt?: number; expiresIn?: number; } /** * JWT payload interface */ interface JWTPayload { id: string; email: string; role: string; sessionToken: string; tenant_Id?: string | number | null; /** Pinned baasix_UserRole row id (assignment switching). Absent on legacy tokens. */ userRole_Id?: string | null; } /** * Accountability object interface - used for permission checking */ interface Accountability { user?: { id: string | number; email?: string; isAdmin?: boolean; [key: string]: any; }; role?: { id: string | number; name?: string; isTenantSpecific?: boolean; } | string | number; /** Full active baasix_UserRole row (assignment) — custom columns included. */ userRole?: Record; permissions?: any[]; tenant?: string | number; ipaddress?: string; } /** * Login credentials */ interface LoginCredentials { email: string; password: string; tenantId?: string; /** Authentication mode: 'jwt' for token-based or 'cookie' for cookie-based auth */ authMode?: "jwt" | "cookie"; /** Authentication type for session management (e.g., 'web', 'mobile', 'default') */ authType?: string; } /** * Registration data */ interface RegisterData { email: string; password: string; firstName?: string; lastName?: string; [key: string]: unknown; } /** * Auth response */ interface AuthResponse { token: string; refreshToken?: string; user: User; role?: Role; expiresIn?: number; } /** * Auth state events */ type AuthStateEvent = "SIGNED_IN" | "SIGNED_OUT" | "TOKEN_REFRESHED" | "USER_UPDATED" | "TENANT_SWITCHED"; /** * Auth state */ interface AuthState { user: User | null; isAuthenticated: boolean; isLoading: boolean; error: Error | null; } /** * Magic link options */ interface MagicLinkOptions { email: string; redirectUrl?: string; mode?: "link" | "code"; } /** * Password reset options */ interface PasswordResetOptions { email: string; redirectUrl?: string; mode?: "link" | "code"; } /** * Authentication mode for the SDK/app * - 'jwt': Use JWT tokens stored in the configured storage adapter (default) * - 'cookie': Use HTTP-only cookies (server handles token storage) */ type AuthMode = "jwt" | "cookie"; /** * OAuth2 tokens */ interface OAuth2Tokens { accessToken: string; refreshToken?: string; idToken?: string; expiresAt?: Date; tokenType?: string; scope?: string; } /** * OAuth2 user info */ interface OAuth2UserInfo { id: string; email: string; name?: string; firstName?: string; lastName?: string; picture?: string; [key: string]: unknown; } /** * Schema & Field Types * Shared across core, sdk, cli, and app packages */ /** * Supported field types in Baasix */ type FieldType = "String" | "Text" | "HTML" | "Integer" | "BigInt" | "Float" | "Real" | "Double" | "Decimal" | "Boolean" | "Date" | "DateTime" | "Time" | "UUID" | "SUID" | "JSON" | "JSONB" | "Array" | "Geometry" | "Point" | "LineString" | "Polygon" | "ENUM" /** @deprecated Use "ENUM" — the server normalizes casing, but "ENUM" is canonical */ | "Enum"; /** * Default value types supported by Baasix */ type DefaultValueType = { type: "UUIDV4"; } | { type: "SUID"; } | { type: "NOW"; } | { type: "AUTOINCREMENT"; } | { type: "SQL"; value: string; } | { type: "CURRENT_USER"; } | { type: "CURRENT_TENANT"; }; /** * Field validation rules */ interface FieldValidationRules { /** Minimum value for numeric fields */ min?: number; /** Maximum value for numeric fields */ max?: number; /** Validate as integer */ isInt?: boolean; /** Validate email format */ isEmail?: boolean; /** Validate URL format */ isUrl?: boolean; /** Validate IP address format */ isIP?: boolean; /** Validate UUID format */ isUUID?: boolean; /** String must not be empty */ notEmpty?: boolean; /** String length range [min, max] */ len?: [number, number]; /** Pattern matching with regex */ is?: string; /** Pattern matching with regex (alias for is) */ matches?: string; /** @deprecated Use 'is' or 'matches' instead */ regex?: string; } /** * Field values configuration (for type-specific options) */ interface FieldValues { /** String length (varchar) */ length?: number; /** String length (alias for length) */ stringLength?: number; /** Decimal precision */ precision?: number; /** Decimal scale */ scale?: number; /** Array element type */ type?: string; /** Enum values */ values?: string[]; /** Spatial reference system identifier (for geometry types) */ srid?: number; /** Vector dimensions (for pgvector types: Vector, HalfVec, SparseVec) */ dimensions?: number; } /** * Field definition * Note: `type` is optional because relation fields use `relType` instead */ interface FieldDefinition { /** Field type (required for data fields, not used for relation fields) */ type?: FieldType | string; primaryKey?: boolean; allowNull?: boolean; unique?: boolean; /** * Default value for the field * Can be a static value or a dynamic type */ defaultValue?: DefaultValueType | string | number | boolean | null | unknown[] | Record; /** Field values configuration (for type-specific options like length, precision, enum values) */ values?: FieldValues; validate?: FieldValidationRules; comment?: string; /** Field description for documentation */ description?: string; /** Relation type (if this is a relation field) */ relType?: RelationshipType | string; /** Target collection for relations */ target?: string; /** Alias for relation (used in queries) */ as?: string; /** Display format for relations */ showAs?: string; /** Foreign key field name or boolean indicating it's a foreign key */ foreignKey?: string | boolean; /** Target key for relations */ targetKey?: string; /** Junction table name for M2M (or junction config object) */ through?: string | Record; /** Other key in junction table */ otherKey?: string; /** Display format string */ displayFormat?: string; /** Display options */ displayOptions?: Record; /** Calculated field expression */ calculated?: string; /** Hide field from API responses */ hidden?: boolean; /** Mark field as system-generated (not user-editable) */ SystemGenerated?: string | boolean; /** Whether to add constraints */ constraints?: boolean; /** Delete behavior for relations */ onDelete?: "CASCADE" | "RESTRICT" | "SET NULL" | string; /** Update behavior for relations */ onUpdate?: "CASCADE" | "RESTRICT" | "SET NULL" | string; /** Whether this is a polymorphic relation (M2A) */ polymorphic?: boolean; /** Target tables for polymorphic (M2A) relations */ tables?: string[]; } /** * Flattened field info (used in core services) */ interface FlattenedField { name: string; type: FieldType; allowNull?: boolean; unique?: boolean; primaryKey?: boolean; defaultValue?: unknown; validate?: FieldValidationRules; relType?: RelationshipType; target?: string; } /** * Field info with full metadata */ interface FieldInfo extends FlattenedField { path: string; isRelation: boolean; isNested: boolean; } /** * Index definition */ interface IndexDefinition { /** Index name (auto-generated if not provided) */ name?: string; fields: string[]; unique?: boolean; /** When true, NULL values are considered equal for unique indexes (PostgreSQL 15+) */ nullsNotDistinct?: boolean; type?: "btree" | "hash" | "gin" | "gist"; } /** * Partitioning options */ interface PartitioningOptions { /** Partitioning strategy: LIST by tenant, RANGE by time, or composite */ strategy: "tenant" | "time" | "tenant+time"; /** DateTime field used for RANGE partitioning (default "createdAt") */ timeField?: string; /** Time partition width (default "year") */ interval?: "month" | "quarter" | "year"; /** Future periods to pre-create (default 1) */ premake?: number; } /** * Schema definition */ interface SchemaDefinition { name: string; timestamps?: boolean; paranoid?: boolean; sortEnabled?: boolean; /** * Controls tenant context enforcement for this collection. * - true: enforce tenant scoping * - false: global/shared collection (no tenant enforcement) * - undefined: use default runtime behavior */ tenantScoped?: boolean; /** Partitioning configuration for this collection */ partitioning?: PartitioningOptions; /** * Track user who created/updated records (adds createdBy_Id, updatedBy_Id) */ usertrack?: boolean; /** * True for M2M/M2A junction tables (system-generated) */ isJunction?: boolean; fields: Record; indexes?: IndexDefinition[]; } /** * Schema info (full schema with collection name) */ interface SchemaInfo { collectionName: string; schema: SchemaDefinition; relationships?: RelationshipDefinition[]; } /** * Validation result (generic base) */ interface ValidationResult { valid: boolean; errors: string[]; warnings: string[]; } /** * Field validation result */ interface FieldValidation extends ValidationResult { fieldName: string; } /** * Schema validation result */ interface SchemaValidation extends ValidationResult { collectionName: string; fieldValidations?: FieldValidation[]; } /** * Relationship types * - M2O: Many-to-One (creates foreign key with auto-index) * - O2M: One-to-Many (virtual reverse of M2O) * - O2O: One-to-One (creates foreign key with unique constraint) * - M2M: Many-to-Many (creates junction table) * - M2A: Many-to-Any (polymorphic junction table) * * Legacy aliases (deprecated, use M2O/O2M/M2M/O2O instead): * - BelongsTo: alias for M2O * - HasMany: alias for O2M * - HasOne: alias for O2O * - BelongsToMany: alias for M2M */ type RelationshipType = "M2O" | "O2M" | "M2M" | "M2A" | "O2O" | "BelongsTo" | "HasMany" | "HasOne" | "BelongsToMany"; /** * Association type (alias for RelationshipType) */ type AssociationType = RelationshipType; /** * Relationship definition */ interface RelationshipDefinition { type: RelationshipType; target: string; name: string; alias?: string; /** * Custom junction table name for M2M/M2A relationships */ through?: string; onDelete?: "CASCADE" | "RESTRICT" | "SET NULL"; onUpdate?: "CASCADE" | "RESTRICT" | "SET NULL"; /** Target tables for M2A (polymorphic) relationships */ tables?: string[]; } /** * Association definition (used internally in core) */ interface AssociationDefinition { type: AssociationType; foreignKey?: string; sourceKey?: string; targetKey?: string; through?: string; as?: string; target: string; onDelete?: "CASCADE" | "RESTRICT" | "SET NULL"; onUpdate?: "CASCADE" | "RESTRICT" | "SET NULL"; } /** * Include configuration for relation fetching */ interface IncludeConfig { model: string; as?: string; attributes?: string[]; where?: Record; required?: boolean; include?: IncludeConfig[]; } /** * Processed include (after parsing) */ interface ProcessedInclude { association: string; as: string; attributes?: string[]; where?: Record; required?: boolean; include?: ProcessedInclude[]; } /** * Query & Filter Types * Shared across core, sdk, cli, and app packages */ /** * Filter operators supported by Baasix * Also known as OperatorName in core (alias provided for backward compatibility) */ type FilterOperator = "eq" | "ne" | "neq" | "gt" | "gte" | "lt" | "lte" | "is" | "not" | "in" | "notIn" | "nin" | "like" | "notLike" | "iLike" | "notILike" | "ilike" | "contains" | "icontains" | "ncontains" | "startsWith" | "startsWiths" | "endsWith" | "endsWiths" | "nstartsWith" | "nstartsWiths" | "nendsWith" | "nendsWiths" | "regex" | "between" | "notBetween" | "nbetween" | "isNull" | "isNotNull" | "empty" | "arraycontains" | "arraycontainsany" | "arraycontained" | "arrayoverlap" | "arraylength" | "arrayempty" | "jsoncontains" | "jsonbContains" | "jsonbContainedBy" | "jsonbNotContains" | "jsonhaskey" | "jsonbHasKey" | "jsonhasanykeys" | "jsonbHasAnyKeys" | "jsonhasallkeys" | "jsonbHasAllKeys" | "jsonpath" | "jsonbKeyEquals" | "jsonbKeyNotEquals" | "jsonbKeyGt" | "jsonbKeyGte" | "jsonbKeyLt" | "jsonbKeyLte" | "jsonbKeyIn" | "jsonbKeyNotIn" | "jsonbKeyLike" | "jsonbKeyIsNull" | "jsonbKeyIsNotNull" | "jsonbPathExists" | "jsonbPathMatch" | "jsonbDeepValue" | "jsonbArrayLength" | "jsonbTypeOf" | "within" | "containsGEO" | "contains" | "intersects" | "nIntersects" | "dwithin" | "overlaps"; /** * Operator name type (alias for FilterOperator) * Used internally in core for the OPERATOR_MAP keys * @see FilterOperator */ type OperatorName = FilterOperator; /** * Filter value with operator */ type FilterValue = T | { [K in FilterOperator]?: T | T[]; } | { cast?: string; }; /** * Filter condition for a field */ type FilterCondition = { [field: string]: FilterValue | FilterCondition; }; /** * Logical filter operators */ interface LogicalFilter { AND?: (FilterCondition | LogicalFilter)[]; OR?: (FilterCondition | LogicalFilter)[]; NOT?: FilterCondition | LogicalFilter; } /** * Complete filter type */ type Filter = FilterCondition | LogicalFilter; /** * Filter object (used internally in core) */ interface FilterObject { field: string; operator: FilterOperator; value: unknown; cast?: string; } /** * Sort direction */ type SortDirection = "asc" | "desc" | "ASC" | "DESC"; /** * Sort configuration - supports multiple formats */ type Sort = string | string[] | Record | { column: string; order: SortDirection; }[] | { field: string; order: SortDirection; }[]; /** * Sort item (normalized) */ interface SortItem { field: string; direction: SortDirection; } /** * Sort object structure (Sequelize-style) * Example: { name: 'ASC', createdAt: 'DESC' } */ interface SortObject { [field: string]: SortDirection; } /** * Pagination options */ interface PaginationOptions { page?: number; limit?: number; offset?: number; pageSize?: number; } /** * Pagination metadata in response */ interface PaginationMetadata { total: number; page: number; pageSize: number; pageCount: number; hasNextPage: boolean; hasPreviousPage: boolean; /** @deprecated Use total instead */ totalCount?: number; /** @deprecated Use pageCount instead */ totalPages?: number; /** @deprecated Use pageSize instead */ limit?: number; } /** * Aggregation function */ type AggregateFunction = "count" | "sum" | "avg" | "min" | "max" | "distinct" | "array_agg"; /** * Aggregation configuration */ interface AggregateConfig { function: AggregateFunction; field: string; alias?: string; } /** * Aggregate mapping (general form) */ type Aggregate = Record; /** * Aggregate result mapping (strict form - always uses AggregateConfig) * Example: { totalUsers: { function: 'count', field: 'id' } } */ interface AggregateMapping { [alias: string]: AggregateConfig; } /** * Date part for date extraction */ type DatePart = "year" | "month" | "week" | "day" | "hour" | "minute" | "second" | "dow" | "isodow" | "quarter"; /** * Date truncation precision */ type DateTruncPrecision = "day" | "week" | "month" | "year" | "hour" | "minute" | "second"; /** * Query parameters for listing items * Used by SDK, app, and can be extended by core for internal use */ interface QueryParams { /** * Fields to return * @example ['*'], ['id', 'name'], ['*', 'author.*'] */ fields?: string[]; /** * Filter conditions */ filter?: Filter; /** * Sorting configuration */ sort?: Sort; /** * Number of items per page (-1 for all) * @default 10 */ limit?: number; /** * Page number (1-indexed) * @default 1 */ page?: number; /** * Number of items to skip */ offset?: number; /** * Full-text search query */ search?: string; /** * Fields to search in */ searchFields?: string[]; /** * Sort results by search relevance * @default false */ sortByRelevance?: boolean; /** * Aggregation configuration */ aggregate?: Aggregate; /** * Fields to group by (used with aggregate) */ groupBy?: string[]; /** * Include soft-deleted items * @default false */ paranoid?: boolean; /** * Filter conditions for related items (O2M/M2M) */ relConditions?: Record; /** * Whether to compute the total record count for the result. * * When omitted (`undefined`), the server falls back to the deployment * default (env `COUNT_BY_DEFAULT`, which itself defaults to `true`). * Passing `false` skips the COUNT query even when the default is on; * passing `true` forces it even when the default is off. * * When the count is skipped, `totalCount` is returned as `null`. * When `limit` is `-1` (return all) with no offset, the count is taken * from the result length instead of running a separate query. */ count?: boolean; /** * Additional metadata */ meta?: T; } /** * Query options for read operations (alias for QueryParams) * Core-compatible naming */ type QueryOptions = QueryParams; /** * Query context (used internally in core) */ interface QueryContext { collection: string; filter?: Filter; sort?: Sort; fields?: string[]; limit?: number; page?: number; offset?: number; aggregate?: Aggregate; groupBy?: string[]; } /** * Report configuration */ interface ReportConfig { collection: string; fields?: string[]; filter?: Record; groupBy?: string[]; sort?: string[] | Record; aggregate?: Record; limit?: number; page?: number; dateRange?: { start: string; end: string; field?: string; }; } /** * Report result */ interface ReportResult { data: Record[]; totalCount?: number; summary?: Record; } /** * Report query parameters */ interface ReportQuery { fields?: string[]; filter?: Record; sort?: string[]; limit?: number; page?: number; aggregate?: Record; groupBy?: string[]; } /** * Stats query */ interface StatsQuery { name: string; query: Record; collection: string; } /** * Stats result */ interface StatsResult { data: Record; totalStats: number; successfulStats: number; } /** * Response Types * Shared across core, sdk, cli, and app packages */ /** * Paginated response */ interface PaginatedResponse { data: T[]; /** * Total number of records matching the query. * `null` when the count was intentionally skipped via `count: false` * (or the deployment default `COUNT_BY_DEFAULT=false`). */ totalCount?: number | null; page?: number; limit?: number; totalPages?: number; } /** * Single item response */ interface SingleResponse { data: T; } /** * Create/Update response */ interface MutationResponse { data: T; message?: string; } /** * Delete response */ interface DeleteResponse { data: { deleted: boolean; count?: number; }; message?: string; } /** * Bulk operation response */ interface BulkResponse { data: T; message?: string; errors?: Array<{ index: number; error: string; }>; } /** * Read result (used internally in services) */ interface ReadResult { data: T[]; /** * Total number of records matching the query. * `null` when the count was intentionally skipped (see `QueryParams.count`). */ totalCount: number | null; page?: number; limit?: number; } /** * Error response */ interface ErrorResponse { error: string; message: string; status: number; details?: unknown[]; } /** * File & Asset Types * Shared across core, sdk, and app packages */ /** * File metadata */ interface FileMetadata { id: string; title?: string; description?: string; filename: string; mimeType: string; size: number; width?: number; height?: number; duration?: number; storage: string; path: string; isPublic?: boolean; uploadedBy?: string; tenant_Id?: string; createdAt: string; updatedAt?: string; [key: string]: unknown; } /** * File data (internal use) */ interface FileData { buffer: Buffer; filename: string; mimetype: string; size: number; } /** * Upload options */ interface UploadOptions { title?: string; description?: string; folder?: string; storage?: "local" | "s3"; isPublic?: boolean; metadata?: Record; onProgress?: (progress: number) => void; /** Request timeout in milliseconds (default: 30000). Set to 0 for no timeout. */ timeout?: number; } /** * Internal uploaded file (from express-fileupload) */ interface InternalUploadedFile { name: string; data: Buffer; size: number; encoding: string; tempFilePath: string; truncated: boolean; mimetype: string; md5: string; mv: (path: string) => Promise; } /** * Asset transform options */ interface AssetTransformOptions { width?: number; height?: number; fit?: "cover" | "contain" | "fill" | "inside" | "outside"; quality?: number; format?: "jpeg" | "png" | "webp" | "avif"; } /** * Asset query parameters (from HTTP query string) * Values can be string | number since they come from query params */ interface AssetQuery { width?: string | number; height?: string | number; fit?: "cover" | "contain" | "fill" | "inside" | "outside" | string; quality?: string | number; format?: string; withoutEnlargement?: string | boolean; } /** * Processed image result */ interface ProcessedImage { buffer: Buffer; /** Content type (e.g., 'image/jpeg') or format (e.g., 'jpeg') */ contentType?: string; format?: string; width?: number; height?: number; } /** * Storage provider type */ type StorageProvider = "local" | "s3" | "gcs" | "azure"; /** * Storage adapter interface */ interface StorageAdapter { getItem(key: string): string | null | Promise; setItem(key: string, value: string): void | Promise; removeItem(key: string): void | Promise; } /** * Uploaded file interface (from multipart form) */ interface UploadedFile { originalname: string; mimetype: string; buffer: Buffer; size: number; } /** * Import options */ interface ImportOptions { collection: string; file?: UploadedFile; data?: unknown[]; format?: "csv" | "json"; mapping?: Record; skipValidation?: boolean; batchSize?: number; onProgress?: (processed: number, total: number) => void; onError?: (error: Error, row: unknown, index: number) => void; } /** * Export options */ interface ExportOptions { collection: string; format?: "csv" | "json"; fields?: string[]; filter?: Record; limit?: number; offset?: number; } /** * Import result */ interface ImportResult { success: boolean; imported: number; failed: number; errors: Array<{ row: number; error: string; data?: unknown; }>; duration: number; } /** * Export result */ interface ExportResult { success: boolean; data: string | unknown[]; count: number; format: string; } /** * Workflow Types * Shared across core, sdk, and app packages */ /** * Workflow trigger types */ type WorkflowTriggerType = "manual" | "webhook" | "schedule" | "hook" | "cron"; /** * Workflow status */ type WorkflowStatus = "draft" | "active" | "inactive" | "archived"; /** * Workflow definition */ interface Workflow { id: string; name: string; description?: string; status: WorkflowStatus; /** @deprecated Use status instead. Kept for backward compatibility. */ isActive?: boolean; trigger_type?: WorkflowTriggerType; /** Alternative trigger format used by SDK */ trigger?: WorkflowTrigger; trigger_cron?: string; trigger_webhook_path?: string; trigger_webhook_method?: string; trigger_hook_collection?: string; trigger_hook_action?: string; allowed_roles?: string[]; flow_data?: WorkflowFlowData; /** Alternative format: nodes at top level */ nodes?: WorkflowNode[]; /** Alternative format: edges at top level */ edges?: WorkflowEdge[]; variables?: Record; options?: Record; createdAt?: string; updatedAt?: string; } /** * Workflow flow data (React Flow format) */ interface WorkflowFlowData { nodes: WorkflowNode[]; edges: WorkflowEdge[]; viewport?: { x: number; y: number; zoom: number; }; } /** * Workflow trigger configuration */ interface WorkflowTrigger { type: WorkflowTriggerType; config?: Record; } /** * Workflow node */ interface WorkflowNode { id: string; type: string; data: WorkflowNodeData; position: { x: number; y: number; }; } /** * Workflow node data */ interface WorkflowNodeData { label?: string; [key: string]: unknown; } /** * Workflow edge */ interface WorkflowEdge { id: string; source: string; target: string; sourceHandle?: string; targetHandle?: string; condition?: string; label?: string; } /** * Workflow execution status */ type WorkflowExecutionStatus = "queued" | "pending" | "running" | "completed" | "failed" | "cancelled"; /** * Workflow execution */ interface WorkflowExecution { id: string; workflow_Id: string; status: WorkflowExecutionStatus; triggeredBy?: string; triggerData?: Record; result?: Record; error?: string; durationMs?: number; startedAt?: string; completedAt?: string; createdAt: string; updatedAt?: string; } /** * Workflow execution log */ interface WorkflowExecutionLog { id: string; execution_Id: string; nodeId: string; nodeType: string; status: "pending" | "running" | "completed" | "failed" | "skipped"; input?: Record; output?: Record; error?: string; durationMs?: number; startedAt?: string; completedAt?: string; } /** * Notification Types * Shared across core, sdk, and app packages */ /** * Notification type */ type NotificationType = "info" | "success" | "warning" | "error" | string; /** * Notification */ interface Notification { id: string; type: NotificationType; title: string; message: string; data?: Record; seen: boolean; user_Id: string; tenant_Id?: string; createdAt: string; updatedAt?: string; } /** * Notification options (for creating) */ interface NotificationOptions { type?: NotificationType; title: string; message: string; data?: Record; userIds?: string[]; tenant_Id?: string; } /** * Send notification data */ interface SendNotificationData { type?: NotificationType; title: string; message: string; data?: Record; userIds: string[]; } /** * Spatial/GeoJSON Types * Types for geospatial data (PostGIS compatible) */ /** * GeoJSON Point */ interface GeoJSONPoint { type: "Point"; coordinates: [number, number]; } /** * GeoJSON LineString */ interface GeoJSONLineString { type: "LineString"; coordinates: [number, number][]; } /** * GeoJSON Polygon */ interface GeoJSONPolygon { type: "Polygon"; coordinates: [number, number][][]; } /** * GeoJSON Geometry (union type) */ type GeoJSONGeometry = GeoJSONPoint | GeoJSONLineString | GeoJSONPolygon; /** * Cache Types * Types for caching functionality */ /** * Cache configuration (SDK/app level) */ interface CacheConfig { enabled?: boolean; ttl?: number; prefix?: string; } /** * Cache set options (Redis-style options for cache.set operations) */ interface CacheSetOptions { /** Expiration in seconds */ ex?: number; [key: string]: unknown; } /** * Cache strategy */ type CacheStrategy = "explicit" | "all"; /** * Cache entry structure */ interface CacheEntry { value: any; expiry: number; tables: string[]; tags: string[]; tenant?: string | null; } /** * Base interface for all cache adapters * Implement this interface to create custom cache adapters */ interface ICacheAdapter { get(key: string): Promise; set(key: string, value: any, ttl?: number, metadata?: { tables: string[]; tags: string[]; tenant?: string | null; }): Promise; delete(key: string): Promise; clear(): Promise; invalidateByPattern(pattern: string): Promise; invalidateByTables(tables: string[], tenant?: string | null): Promise; invalidateByTags(tags: string[], tenant?: string | null): Promise; getStats(): Promise<{ keys: number; size?: number; }>; close(): Promise; } /** * Common/Utility Types * Shared across all packages */ /** * Generic record type with ID */ interface BaseItem { id: string; createdAt?: string; updatedAt?: string; deletedAt?: string; [key: string]: unknown; } /** * Timestamped item */ interface TimestampedItem { createdAt: string; updatedAt?: string; } /** * Soft deletable item */ interface SoftDeletableItem { deletedAt?: string | null; } /** * Make all properties of T optional recursively */ type DeepPartial = { [P in keyof T]?: T[P] extends object ? DeepPartial : T[P]; }; /** * Extract the item type from a collection */ type CollectionItem = T extends Array ? U : T; /** * Make specific properties required */ type WithRequired = T & { [P in K]-?: T[P]; }; /** * Make specific properties optional */ type WithOptional = Omit & Partial>; /** * Extract keys of T that have values of type V */ type KeysOfType = { [K in keyof T]: T[K] extends V ? K : never; }[keyof T]; /** * Record with string keys and unknown values */ type AnyRecord = Record; /** * Generic settings */ interface Settings { [key: string]: unknown; } /** * Session type limits */ interface SessionTypeLimits { /** -1 = unlimited, 0 = disabled, positive n = max concurrent sessions */ web?: number; mobile?: number; } /** * Session limits by role and type */ interface SessionLimits { default?: SessionTypeLimits; roles?: Record; } /** * Tenant settings */ interface TenantSettings { tenant_Id?: string | number | null; project_name?: string; title?: string; project_url?: string | null; app_url?: string | null; project_color?: string; secondary_color?: string; description?: string; keywords?: string; from_email_name?: string; smtp_enabled?: boolean; smtp_host?: string; smtp_port?: number; smtp_secure?: boolean; smtp_user?: string; smtp_pass?: string; smtp_from_address?: string; timezone?: string; language?: string; date_format?: string; currency?: string; email_signature?: string; email_icon?: any; metadata?: Record; modules?: Record; session_limits?: SessionLimits | null; [key: string]: any; } /** * Background task */ interface BackgroundTask { id: string | number; task_status: string; scheduled_time: Date; max_retries?: number; retry_count?: number; started_at?: Date | null; [key: string]: unknown; } /** * Hook events */ type HookEvent = "items.create" | "items.read" | "items.update" | "items.delete" | "auth.login" | "auth.logout" | "auth.register"; /** * Hook handler context */ interface HookContext { event: HookEvent; collection?: string; payload?: unknown; keys?: string[]; accountability?: { user?: { id: string; }; role?: { id: string; name: string; }; tenant?: { id: string; }; }; } /** * Hook handler function */ type HookHandler = (context: HookContext) => void | Promise; /** * Hook definition */ interface Hook { event: HookEvent; collection?: string; handler: HookHandler; } /** * HTTP methods */ type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "OPTIONS" | "HEAD"; /** * Mail options for sending emails */ interface MailOptions { to: string | string[]; subject: string; html?: string; text?: string; from?: string; cc?: string | string[]; bcc?: string | string[]; replyTo?: string; attachments?: Array<{ filename: string; content?: string | Buffer; path?: string; contentType?: string; }>; } /** * Sender configuration for email */ interface SenderConfig { from: string; name?: string; replyTo?: string; } /** * Seed data configuration */ interface SeedData { collection: string; data: Record | Record[]; /** Whether to clear existing data before seeding */ clearBefore?: boolean; /** Whether to skip if data already exists (check by unique fields) */ skipDuplicates?: boolean; } /** * Seed operation result */ interface SeedResult { collection: string; created: number; skipped: number; errors: number; errorDetails?: Array<{ item: unknown; error: string; }>; } /** * Plugin System Types * Shared types for Baasix plugin development */ /** Express Request type */ type Request = Request$1; /** Express Response type */ type Response = Response$1; /** Express NextFunction type */ type NextFunction = NextFunction$1; /** Express Application type */ type Express = Express$1; /** Express Router type */ type Router = Router$1; /** Type aliases for clarity */ type ExpressRequest = Request$1; type ExpressResponse = Response$1; type ExpressNextFunction = NextFunction$1; type ExpressApp = Express$1; type ExpressRouter = Router$1; /** * Generic request type (compatible with Express Request) */ interface PluginRequest { params: Record; query: Record; body: any; headers: Record; method: string; path: string; url: string; originalUrl: string; baseUrl: string; cookies?: Record; signedCookies?: Record; ip?: string; ips?: string[]; hostname?: string; protocol?: string; secure?: boolean; xhr?: boolean; accountability?: Accountability; get(header: string): string | undefined; header(header: string): string | undefined; accepts(...types: string[]): string | false; is(type: string): string | false | null; [key: string]: any; } /** * Generic response type (compatible with Express Response) */ interface PluginResponse { status(code: number): PluginResponse; sendStatus(code: number): PluginResponse; json(data: any): PluginResponse; send(data: any): PluginResponse; end(data?: any): PluginResponse; set(header: string, value: string | string[]): PluginResponse; set(headers: Record): PluginResponse; header(header: string, value: string | string[]): PluginResponse; get(header: string): string | undefined; type(type: string): PluginResponse; contentType(type: string): PluginResponse; redirect(url: string): void; redirect(status: number, url: string): void; cookie(name: string, value: string, options?: Record): PluginResponse; clearCookie(name: string, options?: Record): PluginResponse; attachment(filename?: string): PluginResponse; download(path: string, filename?: string): void; locals: Record; headersSent: boolean; statusCode: number; [key: string]: any; } /** * Generic next function type (compatible with Express NextFunction) */ type PluginNextFunction = (error?: any) => void; /** * Generic Express application type */ interface PluginApp { use(...handlers: any[]): PluginApp; get(path: string, ...handlers: any[]): PluginApp; post(path: string, ...handlers: any[]): PluginApp; put(path: string, ...handlers: any[]): PluginApp; patch(path: string, ...handlers: any[]): PluginApp; delete(path: string, ...handlers: any[]): PluginApp; options(path: string, ...handlers: any[]): PluginApp; all(path: string, ...handlers: any[]): PluginApp; listen(port: number, callback?: () => void): any; set(setting: string, value: any): PluginApp; get(setting: string): any; locals: Record; [key: string]: any; } /** * Generic Router type (compatible with Express Router) */ interface PluginRouter { use(...handlers: any[]): PluginRouter; get(path: string, ...handlers: any[]): PluginRouter; post(path: string, ...handlers: any[]): PluginRouter; put(path: string, ...handlers: any[]): PluginRouter; patch(path: string, ...handlers: any[]): PluginRouter; delete(path: string, ...handlers: any[]): PluginRouter; options(path: string, ...handlers: any[]): PluginRouter; all(path: string, ...handlers: any[]): PluginRouter; [key: string]: any; } /** * Base service options with accountability */ interface ServiceOptions { accountability?: Accountability; [key: string]: any; } /** * Items service interface for CRUD operations * Note: Actual implementations may have additional methods and different signatures. * The index signature provides flexibility for all implementations. */ interface IItemsService { [key: string]: any; } /** * Permission service interface */ interface IPermissionService { [key: string]: any; } /** * Mail service interface */ interface IMailService { [key: string]: any; } /** * Storage service interface */ interface IStorageService { [key: string]: any; } /** * Settings service interface */ interface ISettingsService { [key: string]: any; } /** * Socket service interface */ interface ISocketService { [key: string]: any; } /** * Realtime service interface */ interface IRealtimeService { [key: string]: any; } /** * Tasks service interface */ interface ITasksService { [key: string]: any; } /** * Workflow service interface */ interface IWorkflowService { [key: string]: any; } /** * Migration service interface */ interface IMigrationService { [key: string]: any; } /** * Hook function type - called during lifecycle events */ type HookFunction = (context: PluginHookContext) => Promise | PluginHookContext; /** * Hooks manager interface - manages lifecycle hooks for collections */ interface IHooksManager { /** * Register a hook for a collection and event * @param collection - Collection name (use '*' for all collections) * @param event - Event name (e.g., 'items.create', 'items.update') * @param hookFunction - Function to execute */ registerHook(collection: string, event: string, hookFunction: HookFunction): void; /** * Get hooks for a collection and event * @param collection - Collection name * @param event - Event name * @returns Array of registered hook functions */ getHooks(collection: string, event: string): HookFunction[]; /** * Execute hooks for a collection and event * @param collection - Collection name * @param event - Event name * @param accountability - User/role accountability info * @param context - Hook context with data * @returns Modified context after all hooks execute */ executeHooks(collection: string, event: string, accountability: Accountability | undefined, context: PluginHookContext): Promise; /** * Load hooks from extensions directory * @param context - Plugin context * @param directory - Optional directory path */ loadHooksFromDirectory?(context: any, directory?: string): Promise; /** * Load schedules from extensions directory * @param context - Plugin context * @param schedule - Schedule manager * @param directory - Optional directory path */ loadSchedulesFromDirectory?(context: any, schedule: any, directory?: string): Promise; /** Allow additional methods/properties */ [key: string]: any; } /** * Cache service interface */ interface ICacheService { [key: string]: any; } /** * Files service interface */ interface IFilesService { [key: string]: any; } /** * Assets service interface */ interface IAssetsService { [key: string]: any; } /** * Notification service interface */ interface INotificationService { [key: string]: any; } /** * Report service interface */ interface IReportService { [key: string]: any; } /** * Stats service interface */ interface IStatsService { [key: string]: any; } /** * Plugin types categorize plugins by their primary function */ type PluginType = "feature" | "auth" | "payment" | "storage" | "ai" | "notification" | "integration"; /** * Plugin metadata - information about the plugin */ interface PluginMeta { /** Unique plugin name (used as identifier) */ name: string; /** Plugin version (semver) */ version: string; /** Plugin type/category */ type: PluginType; /** Human-readable description */ description?: string; /** Plugin author */ author?: string; /** Plugin dependencies (names of other plugins that must be loaded first) */ dependencies?: string[]; } /** * Schema definition for plugin collections */ interface PluginSchemaDefinition { collectionName: string; schema: SchemaDefinition; } /** * Plugin route handler context - available in route handlers */ interface PluginRouteContext { /** Database connection */ db: any; /** ItemsService class for CRUD operations */ ItemsService: new (...args: any[]) => IItemsService; /** Registered plugin services */ services: Record; /** Permission service (singleton) */ permissionService?: IPermissionService; /** Mail service (singleton) */ mailService?: IMailService; /** Storage service (singleton) */ storageService?: IStorageService; /** Settings service (singleton) */ settingsService?: ISettingsService; /** Socket service (singleton) */ socketService?: ISocketService; /** Realtime service (singleton) */ realtimeService?: IRealtimeService; /** Tasks service (singleton) */ tasksService?: ITasksService; /** Workflow service (singleton) */ workflowService?: IWorkflowService; /** Migration service (singleton) */ migrationService?: IMigrationService; /** Get cache service instance */ getCacheService?: () => ICacheService; /** FilesService class */ FilesService?: new (...args: any[]) => IFilesService; /** AssetsService class */ AssetsService?: new (...args: any[]) => IAssetsService; /** NotificationService class */ NotificationService?: new (...args: any[]) => INotificationService; /** ReportService class */ ReportService?: new (...args: any[]) => IReportService; /** StatsService class */ StatsService?: new (...args: any[]) => IStatsService; /** Plugin configuration */ config: Record; } /** * Plugin route handler function */ type PluginRouteHandler = (req: TReq, res: TRes, context: PluginRouteContext) => Promise | any; /** * Plugin route definition */ interface PluginRoute { /** Route path (e.g., '/payments/stripe/checkout') */ path: string; /** HTTP method */ method: HttpMethod; /** Route handler */ handler: PluginRouteHandler; /** Whether authentication is required */ requireAuth?: boolean; /** Whether to parse raw body (for webhooks) */ rawBody?: boolean; /** Custom middleware for this route */ middleware?: Array<(req: TReq, res: TRes, next: PluginNextFunction) => void>; /** Route description for documentation */ description?: string; } /** * Plugin hook event types */ type PluginHookEvent = "items.create" | "items.read" | "items.update" | "items.delete" | "items.create.after" | "items.read.after" | "items.update.after" | "items.delete.after"; /** * Plugin hook context - passed to hook handlers * All properties are optional to allow flexibility in different contexts */ interface PluginHookContext { collection?: string; accountability?: Accountability; db?: any; data?: any; id?: string | number; query?: any; schema?: any; transaction?: any; [key: string]: any; } /** * Plugin hook handler function */ type PluginHookHandler = (context: PluginHookContext) => Promise | PluginHookContext; /** * Plugin hook definition */ interface PluginHook { /** Collection name (use '*' for all collections) */ collection: string; /** Hook event */ event: PluginHookEvent; /** Hook handler */ handler: PluginHookHandler; /** Hook priority (lower runs first) */ priority?: number; } /** * Plugin context - passed to lifecycle hooks and service factories */ interface PluginContext extends PluginRouteContext { /** Hooks manager (singleton) */ hooksManager?: IHooksManager; /** Invalidate cache for a collection */ invalidateCache?: (collection?: string) => Promise; /** Express app instance (when available) */ app?: PluginApp; /** Get another plugin's service */ getPluginService: (pluginName: string, serviceName: string) => any; } /** * Plugin service factory function */ type PluginServiceFactory = (context: PluginContext) => any; /** * Plugin service definition */ interface PluginService { /** Service name (used to access via context.services.name) */ name: string; /** Service factory function */ factory: PluginServiceFactory; } /** * Plugin auth provider type */ type AuthProviderType = "oauth2" | "otp" | "passkey" | "custom"; /** * OAuth2 configuration */ interface OAuth2Config { authorizationUrl: string; tokenUrl: string; userInfoUrl: string; clientId: string; clientSecret: string; scope?: string[]; } /** * Plugin auth provider definition */ interface PluginAuthProvider { /** Provider identifier (e.g., 'github', 'otp') */ id: string; /** Display name */ name: string; /** Provider type */ type: AuthProviderType; /** OAuth2 configuration (for oauth2 type) */ oauth2Config?: OAuth2Config; /** Custom authentication handler */ authenticate?: (credentials: Record, context: PluginContext) => Promise<{ user: any; account?: any; } | null>; /** Custom routes for this provider */ routes?: PluginRoute[]; } /** * Plugin middleware definition */ interface PluginMiddleware { /** Middleware name (for debugging) */ name: string; /** Path pattern (optional, defaults to all routes) */ path?: string; /** Middleware handler */ handler: (req: TReq, res: TRes, next: PluginNextFunction) => void; /** Priority (lower runs first) */ priority?: number; } /** * Plugin schedule definition */ interface PluginSchedule { /** Schedule name */ name: string; /** Cron expression */ cron: string; /** Schedule handler */ handler: (context: PluginContext) => Promise | void; /** Whether to run immediately on startup */ runOnStart?: boolean; } /** * Plugin definition - what a plugin provides */ interface PluginDefinition { /** Plugin metadata */ meta: PluginMeta; /** Schema extensions - new collections/tables */ schemas?: PluginSchemaDefinition[]; /** Route extensions - new API endpoints */ routes?: PluginRoute[]; /** Hook extensions - lifecycle hooks */ hooks?: PluginHook[]; /** Service extensions - new services */ services?: PluginService[]; /** Auth provider extensions */ authProviders?: PluginAuthProvider[]; /** Middleware extensions */ middleware?: PluginMiddleware[]; /** Scheduled tasks */ schedules?: PluginSchedule[]; /** Called when the plugin is initialized */ onInit?: (context: PluginContext) => Promise; /** Called when all plugins are loaded and server is ready */ onReady?: (context: PluginContext) => Promise; /** Called when the server is shutting down */ onShutdown?: (context: PluginContext) => Promise; } /** * Plugin factory function - creates a plugin with configuration */ type PluginFactory> = (config: TConfig) => PluginDefinition; /** * Baasix plugin type */ type BaasixPlugin = PluginDefinition; /** * Loaded plugin - plugin with runtime state */ interface LoadedPlugin { /** Plugin definition */ definition: PluginDefinition; /** Plugin configuration */ config: Record; /** Plugin services (instantiated) */ services: Record; /** Whether the plugin has been initialized */ initialized: boolean; /** Whether the plugin is ready */ ready: boolean; } /** * Plugin manager options */ interface PluginManagerOptions { /** Whether to log plugin loading */ verbose?: boolean; } /** * Start server options with plugin support */ interface StartServerOptions { /** Server port */ port?: number; /** Plugins to load */ plugins?: BaasixPlugin[]; /** Plugin manager options */ pluginOptions?: PluginManagerOptions; } /** * Plugin route handler function with Express types */ type ExpressPluginRouteHandler = (req: Request, res: Response, context: PluginRouteContext) => Promise | any; /** * Plugin route definition with Express types */ interface ExpressPluginRoute extends Omit { /** Route handler */ handler: ExpressPluginRouteHandler; /** Custom middleware for this route */ middleware?: Array<(req: Request, res: Response, next: NextFunction) => void>; } /** * Plugin middleware definition with Express types */ interface ExpressPluginMiddleware extends Omit { /** Middleware handler */ handler: (req: Request, res: Response, next: NextFunction) => void; } /** * Plugin context with Express types */ interface ExpressPluginContext extends PluginRouteContext { /** Hooks manager (singleton) - lifecycle hooks for collections */ hooksManager?: IHooksManager; /** Invalidate cache for a collection */ invalidateCache?: (collection?: string) => Promise; /** Express app instance */ app?: Express; /** Get another plugin's service */ getPluginService: (pluginName: string, serviceName: string) => any; } export type { Accountability, Aggregate, AggregateConfig, AggregateFunction, AggregateMapping, AnyRecord, AssetQuery, AssetTransformOptions, AssociationDefinition, AssociationType, AuthMode, AuthProviderType, AuthResponse, AuthState, AuthStateEvent, AuthTokens, BaasixPlugin, BackgroundTask, BaseItem, BulkResponse, CacheConfig, CacheEntry, CacheSetOptions, CacheStrategy, CollectionItem, CreatePermissionData, DatePart, DateTruncPrecision, DeepPartial, DefaultValueType, DeleteResponse, ErrorResponse, ExportOptions, ExportResult, Express, ExpressApp, ExpressNextFunction, ExpressPluginContext, ExpressPluginMiddleware, ExpressPluginRoute, ExpressPluginRouteHandler, ExpressRequest, ExpressResponse, ExpressRouter, FieldDefinition, FieldInfo, FieldType, FieldValidation, FieldValidationRules, FieldValues, FileData, FileMetadata, Filter, FilterCondition, FilterObject, FilterOperator, FilterValue, FlattenedField, GeoJSONGeometry, GeoJSONLineString, GeoJSONPoint, GeoJSONPolygon, Hook, HookContext, HookEvent, HookFunction, HookHandler, HttpMethod, IAssetsService, ICacheAdapter, ICacheService, IFilesService, IHooksManager, IItemsService, IMailService, IMigrationService, INotificationService, IPermissionService, IRealtimeService, IReportService, ISettingsService, ISocketService, IStatsService, IStorageService, ITasksService, IWorkflowService, ImportOptions, ImportResult, IncludeConfig, IndexDefinition, InternalUploadedFile, JWTPayload, KeysOfType, LoadedPlugin, LogicalFilter, LoginCredentials, MagicLinkOptions, MailOptions, MutationResponse, NextFunction, Notification, NotificationOptions, NotificationType, OAuth2Config, OAuth2Tokens, OAuth2UserInfo, OperatorName, PaginatedResponse, PaginationMetadata, PaginationOptions, PasswordResetOptions, Permission, PermissionAction, PermissionData, PluginApp, PluginAuthProvider, PluginContext, PluginDefinition, PluginFactory, PluginHook, PluginHookContext, PluginHookEvent, PluginHookHandler, PluginManagerOptions, PluginMeta, PluginMiddleware, PluginNextFunction, PluginRequest, PluginResponse, PluginRoute, PluginRouteContext, PluginRouteHandler, PluginRouter, PluginSchedule, PluginSchemaDefinition, PluginService, PluginServiceFactory, PluginType, ProcessedImage, ProcessedInclude, QueryContext, QueryOptions, QueryParams, ReadResult, RegisterData, RelationshipDefinition, RelationshipType, ReportConfig, ReportQuery, ReportResult, Request, Response, Role, Router, SchemaDefinition, SchemaInfo, SchemaValidation, SeedData, SeedResult, SendNotificationData, SenderConfig, ServiceOptions, Session, SessionLimits, SessionTypeLimits, Settings, SingleResponse, SoftDeletableItem, Sort, SortDirection, SortItem, SortObject, StartServerOptions, StatsQuery, StatsResult, StorageAdapter, StorageProvider, Tenant, TenantSettings, TimestampedItem, UploadOptions, UploadedFile, User, UserWithPassword, UserWithRolesAndPermissions, ValidationResult, WithOptional, WithRequired, Workflow, WorkflowEdge, WorkflowExecution, WorkflowExecutionLog, WorkflowExecutionStatus, WorkflowFlowData, WorkflowNode, WorkflowNodeData, WorkflowStatus, WorkflowTrigger, WorkflowTriggerType };