@baasix/types 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2065 @@
1
+ import { Request as Request$1, Response as Response$1, NextFunction as NextFunction$1, Express as Express$1, Router as Router$1 } from 'express';
2
+
3
+ /**
4
+ * Authentication & Authorization Types
5
+ * Shared across core, sdk, cli, and app packages
6
+ */
7
+ /**
8
+ * Base user interface
9
+ */
10
+ interface User {
11
+ id: string;
12
+ email: string;
13
+ firstName?: string;
14
+ lastName?: string;
15
+ avatar?: string;
16
+ role?: Role;
17
+ role_Id?: string;
18
+ tenant_Id?: string;
19
+ status?: string;
20
+ createdAt?: string;
21
+ updatedAt?: string;
22
+ [key: string]: unknown;
23
+ }
24
+ /**
25
+ * User with password (internal use only)
26
+ */
27
+ interface UserWithPassword extends User {
28
+ password?: string;
29
+ }
30
+ /**
31
+ * User with expanded roles and permissions
32
+ */
33
+ interface UserWithRolesAndPermissions {
34
+ id: string | number;
35
+ email?: string;
36
+ roles: string[];
37
+ permissions: string[];
38
+ tenantId?: string | number;
39
+ [key: string]: unknown;
40
+ }
41
+ /**
42
+ * Role interface
43
+ */
44
+ interface Role {
45
+ id: string;
46
+ name: string;
47
+ description?: string;
48
+ isTenantSpecific?: boolean;
49
+ [key: string]: unknown;
50
+ }
51
+ /**
52
+ * Permission action types
53
+ */
54
+ type PermissionAction = "create" | "read" | "update" | "delete";
55
+ /**
56
+ * Permission interface
57
+ */
58
+ interface Permission {
59
+ id: string;
60
+ role_Id: string;
61
+ collection: string;
62
+ action: PermissionAction;
63
+ fields?: string[] | null;
64
+ conditions?: Record<string, unknown>;
65
+ defaultValues?: Record<string, unknown>;
66
+ relConditions?: Record<string, unknown>;
67
+ }
68
+ /**
69
+ * Permission data structure (internal to PermissionService)
70
+ */
71
+ interface PermissionData {
72
+ fields: string[] | null;
73
+ conditions: Record<string, unknown>;
74
+ relConditions: Record<string, unknown>;
75
+ defaultValues: Record<string, unknown>;
76
+ }
77
+ /**
78
+ * Data for creating a new permission
79
+ */
80
+ interface CreatePermissionData {
81
+ role_Id: string;
82
+ collection: string;
83
+ action: PermissionAction;
84
+ fields?: string[];
85
+ conditions?: Record<string, unknown>;
86
+ defaultValues?: Record<string, unknown>;
87
+ relConditions?: Record<string, unknown>;
88
+ }
89
+ /**
90
+ * Tenant interface
91
+ */
92
+ interface Tenant {
93
+ id: string;
94
+ name: string;
95
+ [key: string]: unknown;
96
+ }
97
+ /**
98
+ * Session interface
99
+ */
100
+ interface Session {
101
+ id: string;
102
+ token: string;
103
+ user_Id: string;
104
+ expiresAt: Date | string;
105
+ ipAddress?: string;
106
+ userAgent?: string;
107
+ createdAt?: string;
108
+ updatedAt?: string;
109
+ }
110
+ /**
111
+ * Auth tokens
112
+ */
113
+ interface AuthTokens {
114
+ accessToken: string;
115
+ refreshToken?: string;
116
+ expiresAt?: number;
117
+ expiresIn?: number;
118
+ }
119
+ /**
120
+ * JWT payload interface
121
+ */
122
+ interface JWTPayload {
123
+ id: string;
124
+ email: string;
125
+ role: string;
126
+ sessionToken: string;
127
+ tenant_Id?: string | number | null;
128
+ }
129
+ /**
130
+ * Accountability object interface - used for permission checking
131
+ */
132
+ interface Accountability {
133
+ user?: {
134
+ id: string | number;
135
+ email?: string;
136
+ isAdmin?: boolean;
137
+ [key: string]: any;
138
+ };
139
+ role?: {
140
+ id: string | number;
141
+ name?: string;
142
+ isTenantSpecific?: boolean;
143
+ } | string | number;
144
+ permissions?: any[];
145
+ tenant?: string | number;
146
+ ipaddress?: string;
147
+ }
148
+ /**
149
+ * Login credentials
150
+ */
151
+ interface LoginCredentials {
152
+ email: string;
153
+ password: string;
154
+ tenantId?: string;
155
+ }
156
+ /**
157
+ * Registration data
158
+ */
159
+ interface RegisterData {
160
+ email: string;
161
+ password: string;
162
+ firstName?: string;
163
+ lastName?: string;
164
+ [key: string]: unknown;
165
+ }
166
+ /**
167
+ * Auth response
168
+ */
169
+ interface AuthResponse {
170
+ token: string;
171
+ refreshToken?: string;
172
+ user: User;
173
+ role?: Role;
174
+ expiresIn?: number;
175
+ }
176
+ /**
177
+ * Auth state events
178
+ */
179
+ type AuthStateEvent = "SIGNED_IN" | "SIGNED_OUT" | "TOKEN_REFRESHED" | "USER_UPDATED" | "TENANT_SWITCHED";
180
+ /**
181
+ * Auth state
182
+ */
183
+ interface AuthState {
184
+ user: User | null;
185
+ isAuthenticated: boolean;
186
+ isLoading: boolean;
187
+ error: Error | null;
188
+ }
189
+ /**
190
+ * Magic link options
191
+ */
192
+ interface MagicLinkOptions {
193
+ email: string;
194
+ redirectUrl?: string;
195
+ mode?: "link" | "code";
196
+ }
197
+ /**
198
+ * Password reset options
199
+ */
200
+ interface PasswordResetOptions {
201
+ email: string;
202
+ redirectUrl?: string;
203
+ }
204
+ /**
205
+ * Authentication mode for the SDK/app
206
+ * - 'jwt': Use JWT tokens stored in the configured storage adapter (default)
207
+ * - 'cookie': Use HTTP-only cookies (server handles token storage)
208
+ */
209
+ type AuthMode = "jwt" | "cookie";
210
+ /**
211
+ * OAuth2 tokens
212
+ */
213
+ interface OAuth2Tokens {
214
+ accessToken: string;
215
+ refreshToken?: string;
216
+ idToken?: string;
217
+ expiresAt?: Date;
218
+ tokenType?: string;
219
+ scope?: string;
220
+ }
221
+ /**
222
+ * OAuth2 user info
223
+ */
224
+ interface OAuth2UserInfo {
225
+ id: string;
226
+ email: string;
227
+ name?: string;
228
+ firstName?: string;
229
+ lastName?: string;
230
+ picture?: string;
231
+ [key: string]: unknown;
232
+ }
233
+
234
+ /**
235
+ * Schema & Field Types
236
+ * Shared across core, sdk, cli, and app packages
237
+ */
238
+ /**
239
+ * Supported field types in Baasix
240
+ */
241
+ 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";
242
+ /**
243
+ * Default value types supported by Baasix
244
+ */
245
+ type DefaultValueType = {
246
+ type: "UUIDV4";
247
+ } | {
248
+ type: "SUID";
249
+ } | {
250
+ type: "NOW";
251
+ } | {
252
+ type: "AUTOINCREMENT";
253
+ } | {
254
+ type: "SQL";
255
+ value: string;
256
+ } | {
257
+ type: "CURRENT_USER";
258
+ } | {
259
+ type: "CURRENT_TENANT";
260
+ };
261
+ /**
262
+ * Field validation rules
263
+ */
264
+ interface FieldValidationRules {
265
+ /** Minimum value for numeric fields */
266
+ min?: number;
267
+ /** Maximum value for numeric fields */
268
+ max?: number;
269
+ /** Validate as integer */
270
+ isInt?: boolean;
271
+ /** Validate email format */
272
+ isEmail?: boolean;
273
+ /** Validate URL format */
274
+ isUrl?: boolean;
275
+ /** Validate IP address format */
276
+ isIP?: boolean;
277
+ /** Validate UUID format */
278
+ isUUID?: boolean;
279
+ /** String must not be empty */
280
+ notEmpty?: boolean;
281
+ /** String length range [min, max] */
282
+ len?: [number, number];
283
+ /** Pattern matching with regex */
284
+ is?: string;
285
+ /** Pattern matching with regex (alias for is) */
286
+ matches?: string;
287
+ /** @deprecated Use 'is' or 'matches' instead */
288
+ regex?: string;
289
+ }
290
+ /**
291
+ * Field values configuration (for type-specific options)
292
+ */
293
+ interface FieldValues {
294
+ /** String length (varchar) */
295
+ length?: number;
296
+ /** String length (alias for length) */
297
+ stringLength?: number;
298
+ /** Decimal precision */
299
+ precision?: number;
300
+ /** Decimal scale */
301
+ scale?: number;
302
+ /** Array element type */
303
+ type?: string;
304
+ /** Enum values */
305
+ values?: string[];
306
+ /** Spatial reference system identifier (for geometry types) */
307
+ srid?: number;
308
+ }
309
+ /**
310
+ * Field definition
311
+ * Note: `type` is optional because relation fields use `relType` instead
312
+ */
313
+ interface FieldDefinition {
314
+ /** Field type (required for data fields, not used for relation fields) */
315
+ type?: FieldType | string;
316
+ primaryKey?: boolean;
317
+ allowNull?: boolean;
318
+ unique?: boolean;
319
+ /**
320
+ * Default value for the field
321
+ * Can be a static value or a dynamic type
322
+ */
323
+ defaultValue?: DefaultValueType | string | number | boolean | null | unknown[] | Record<string, unknown>;
324
+ /** Field values configuration (for type-specific options like length, precision, enum values) */
325
+ values?: FieldValues;
326
+ validate?: FieldValidationRules;
327
+ comment?: string;
328
+ /** Field description for documentation */
329
+ description?: string;
330
+ /** Relation type (if this is a relation field) */
331
+ relType?: RelationshipType | string;
332
+ /** Target collection for relations */
333
+ target?: string;
334
+ /** Alias for relation (used in queries) */
335
+ as?: string;
336
+ /** Display format for relations */
337
+ showAs?: string;
338
+ /** Foreign key field name or boolean indicating it's a foreign key */
339
+ foreignKey?: string | boolean;
340
+ /** Target key for relations */
341
+ targetKey?: string;
342
+ /** Junction table name for M2M (or junction config object) */
343
+ through?: string | Record<string, unknown>;
344
+ /** Other key in junction table */
345
+ otherKey?: string;
346
+ /** Display format string */
347
+ displayFormat?: string;
348
+ /** Display options */
349
+ displayOptions?: Record<string, unknown>;
350
+ /** Calculated field expression */
351
+ calculated?: string;
352
+ /** Hide field from API responses */
353
+ hidden?: boolean;
354
+ /** Mark field as system-generated (not user-editable) */
355
+ SystemGenerated?: string | boolean;
356
+ /** Whether to add constraints */
357
+ constraints?: boolean;
358
+ /** Delete behavior for relations */
359
+ onDelete?: "CASCADE" | "RESTRICT" | "SET NULL" | string;
360
+ /** Update behavior for relations */
361
+ onUpdate?: "CASCADE" | "RESTRICT" | "SET NULL" | string;
362
+ /** Whether this is a polymorphic relation (M2A) */
363
+ polymorphic?: boolean;
364
+ /** Target tables for polymorphic (M2A) relations */
365
+ tables?: string[];
366
+ }
367
+ /**
368
+ * Flattened field info (used in core services)
369
+ */
370
+ interface FlattenedField {
371
+ name: string;
372
+ type: FieldType;
373
+ allowNull?: boolean;
374
+ unique?: boolean;
375
+ primaryKey?: boolean;
376
+ defaultValue?: unknown;
377
+ validate?: FieldValidationRules;
378
+ relType?: RelationshipType;
379
+ target?: string;
380
+ }
381
+ /**
382
+ * Field info with full metadata
383
+ */
384
+ interface FieldInfo extends FlattenedField {
385
+ path: string;
386
+ isRelation: boolean;
387
+ isNested: boolean;
388
+ }
389
+ /**
390
+ * Index definition
391
+ */
392
+ interface IndexDefinition {
393
+ /** Index name (auto-generated if not provided) */
394
+ name?: string;
395
+ fields: string[];
396
+ unique?: boolean;
397
+ /** When true, NULL values are considered equal for unique indexes (PostgreSQL 15+) */
398
+ nullsNotDistinct?: boolean;
399
+ type?: "btree" | "hash" | "gin" | "gist";
400
+ }
401
+ /**
402
+ * Schema definition
403
+ */
404
+ interface SchemaDefinition {
405
+ name: string;
406
+ timestamps?: boolean;
407
+ paranoid?: boolean;
408
+ sortEnabled?: boolean;
409
+ /**
410
+ * Track user who created/updated records (adds createdBy_Id, updatedBy_Id)
411
+ */
412
+ usertrack?: boolean;
413
+ /**
414
+ * True for M2M/M2A junction tables (system-generated)
415
+ */
416
+ isJunction?: boolean;
417
+ fields: Record<string, FieldDefinition>;
418
+ indexes?: IndexDefinition[];
419
+ }
420
+ /**
421
+ * Schema info (full schema with collection name)
422
+ */
423
+ interface SchemaInfo {
424
+ collectionName: string;
425
+ schema: SchemaDefinition;
426
+ relationships?: RelationshipDefinition[];
427
+ }
428
+ /**
429
+ * Validation result (generic base)
430
+ */
431
+ interface ValidationResult {
432
+ valid: boolean;
433
+ errors: string[];
434
+ warnings: string[];
435
+ }
436
+ /**
437
+ * Field validation result
438
+ */
439
+ interface FieldValidation extends ValidationResult {
440
+ fieldName: string;
441
+ }
442
+ /**
443
+ * Schema validation result
444
+ */
445
+ interface SchemaValidation extends ValidationResult {
446
+ collectionName: string;
447
+ fieldValidations?: FieldValidation[];
448
+ }
449
+ /**
450
+ * Relationship types
451
+ * - M2O: Many-to-One (creates foreign key with auto-index)
452
+ * - O2M: One-to-Many (virtual reverse of M2O)
453
+ * - O2O: One-to-One (creates foreign key with unique constraint)
454
+ * - M2M: Many-to-Many (creates junction table)
455
+ * - M2A: Many-to-Any (polymorphic junction table)
456
+ *
457
+ * Legacy aliases (deprecated, use M2O/O2M/M2M/O2O instead):
458
+ * - BelongsTo: alias for M2O
459
+ * - HasMany: alias for O2M
460
+ * - HasOne: alias for O2O
461
+ * - BelongsToMany: alias for M2M
462
+ */
463
+ type RelationshipType = "M2O" | "O2M" | "M2M" | "M2A" | "O2O" | "BelongsTo" | "HasMany" | "HasOne" | "BelongsToMany";
464
+ /**
465
+ * Association type (alias for RelationshipType)
466
+ */
467
+ type AssociationType = RelationshipType;
468
+ /**
469
+ * Relationship definition
470
+ */
471
+ interface RelationshipDefinition {
472
+ type: RelationshipType;
473
+ target: string;
474
+ name: string;
475
+ alias?: string;
476
+ /**
477
+ * Custom junction table name for M2M/M2A relationships
478
+ */
479
+ through?: string;
480
+ onDelete?: "CASCADE" | "RESTRICT" | "SET NULL";
481
+ onUpdate?: "CASCADE" | "RESTRICT" | "SET NULL";
482
+ /** Target tables for M2A (polymorphic) relationships */
483
+ tables?: string[];
484
+ }
485
+ /**
486
+ * Association definition (used internally in core)
487
+ */
488
+ interface AssociationDefinition {
489
+ type: AssociationType;
490
+ foreignKey?: string;
491
+ sourceKey?: string;
492
+ targetKey?: string;
493
+ through?: string;
494
+ as?: string;
495
+ target: string;
496
+ onDelete?: "CASCADE" | "RESTRICT" | "SET NULL";
497
+ onUpdate?: "CASCADE" | "RESTRICT" | "SET NULL";
498
+ }
499
+ /**
500
+ * Include configuration for relation fetching
501
+ */
502
+ interface IncludeConfig {
503
+ model: string;
504
+ as?: string;
505
+ attributes?: string[];
506
+ where?: Record<string, unknown>;
507
+ required?: boolean;
508
+ include?: IncludeConfig[];
509
+ }
510
+ /**
511
+ * Processed include (after parsing)
512
+ */
513
+ interface ProcessedInclude {
514
+ association: string;
515
+ as: string;
516
+ attributes?: string[];
517
+ where?: Record<string, unknown>;
518
+ required?: boolean;
519
+ include?: ProcessedInclude[];
520
+ }
521
+
522
+ /**
523
+ * Query & Filter Types
524
+ * Shared across core, sdk, cli, and app packages
525
+ */
526
+ /**
527
+ * Filter operators supported by Baasix
528
+ * Also known as OperatorName in core (alias provided for backward compatibility)
529
+ */
530
+ 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";
531
+ /**
532
+ * Operator name type (alias for FilterOperator)
533
+ * Used internally in core for the OPERATOR_MAP keys
534
+ * @see FilterOperator
535
+ */
536
+ type OperatorName = FilterOperator;
537
+ /**
538
+ * Filter value with operator
539
+ */
540
+ type FilterValue<T = unknown> = T | {
541
+ [K in FilterOperator]?: T | T[];
542
+ } | {
543
+ cast?: string;
544
+ };
545
+ /**
546
+ * Filter condition for a field
547
+ */
548
+ type FilterCondition = {
549
+ [field: string]: FilterValue | FilterCondition;
550
+ };
551
+ /**
552
+ * Logical filter operators
553
+ */
554
+ interface LogicalFilter {
555
+ AND?: (FilterCondition | LogicalFilter)[];
556
+ OR?: (FilterCondition | LogicalFilter)[];
557
+ NOT?: FilterCondition | LogicalFilter;
558
+ }
559
+ /**
560
+ * Complete filter type
561
+ */
562
+ type Filter = FilterCondition | LogicalFilter;
563
+ /**
564
+ * Filter object (used internally in core)
565
+ */
566
+ interface FilterObject {
567
+ field: string;
568
+ operator: FilterOperator;
569
+ value: unknown;
570
+ cast?: string;
571
+ }
572
+ /**
573
+ * Sort direction
574
+ */
575
+ type SortDirection = "asc" | "desc" | "ASC" | "DESC";
576
+ /**
577
+ * Sort configuration - supports multiple formats
578
+ */
579
+ type Sort = string | string[] | Record<string, SortDirection> | {
580
+ column: string;
581
+ order: SortDirection;
582
+ }[] | {
583
+ field: string;
584
+ order: SortDirection;
585
+ }[];
586
+ /**
587
+ * Sort item (normalized)
588
+ */
589
+ interface SortItem {
590
+ field: string;
591
+ direction: SortDirection;
592
+ }
593
+ /**
594
+ * Sort object structure (Sequelize-style)
595
+ * Example: { name: 'ASC', createdAt: 'DESC' }
596
+ */
597
+ interface SortObject {
598
+ [field: string]: SortDirection;
599
+ }
600
+ /**
601
+ * Pagination options
602
+ */
603
+ interface PaginationOptions {
604
+ page?: number;
605
+ limit?: number;
606
+ offset?: number;
607
+ pageSize?: number;
608
+ }
609
+ /**
610
+ * Pagination metadata in response
611
+ */
612
+ interface PaginationMetadata {
613
+ total: number;
614
+ page: number;
615
+ pageSize: number;
616
+ pageCount: number;
617
+ hasNextPage: boolean;
618
+ hasPreviousPage: boolean;
619
+ /** @deprecated Use total instead */
620
+ totalCount?: number;
621
+ /** @deprecated Use pageCount instead */
622
+ totalPages?: number;
623
+ /** @deprecated Use pageSize instead */
624
+ limit?: number;
625
+ }
626
+ /**
627
+ * Aggregation function
628
+ */
629
+ type AggregateFunction = "count" | "sum" | "avg" | "min" | "max" | "distinct" | "array_agg";
630
+ /**
631
+ * Aggregation configuration
632
+ */
633
+ interface AggregateConfig {
634
+ function: AggregateFunction;
635
+ field: string;
636
+ alias?: string;
637
+ }
638
+ /**
639
+ * Aggregate mapping (general form)
640
+ */
641
+ type Aggregate = Record<string, AggregateConfig | AggregateFunction>;
642
+ /**
643
+ * Aggregate result mapping (strict form - always uses AggregateConfig)
644
+ * Example: { totalUsers: { function: 'count', field: 'id' } }
645
+ */
646
+ interface AggregateMapping {
647
+ [alias: string]: AggregateConfig;
648
+ }
649
+ /**
650
+ * Date part for date extraction
651
+ */
652
+ type DatePart = "year" | "month" | "week" | "day" | "hour" | "minute" | "second" | "dow" | "isodow" | "quarter";
653
+ /**
654
+ * Date truncation precision
655
+ */
656
+ type DateTruncPrecision = "day" | "week" | "month" | "year" | "hour" | "minute" | "second";
657
+ /**
658
+ * Query parameters for listing items
659
+ * Used by SDK, app, and can be extended by core for internal use
660
+ */
661
+ interface QueryParams<T = unknown> {
662
+ /**
663
+ * Fields to return
664
+ * @example ['*'], ['id', 'name'], ['*', 'author.*']
665
+ */
666
+ fields?: string[];
667
+ /**
668
+ * Filter conditions
669
+ */
670
+ filter?: Filter;
671
+ /**
672
+ * Sorting configuration
673
+ */
674
+ sort?: Sort;
675
+ /**
676
+ * Number of items per page (-1 for all)
677
+ * @default 10
678
+ */
679
+ limit?: number;
680
+ /**
681
+ * Page number (1-indexed)
682
+ * @default 1
683
+ */
684
+ page?: number;
685
+ /**
686
+ * Number of items to skip
687
+ */
688
+ offset?: number;
689
+ /**
690
+ * Full-text search query
691
+ */
692
+ search?: string;
693
+ /**
694
+ * Fields to search in
695
+ */
696
+ searchFields?: string[];
697
+ /**
698
+ * Sort results by search relevance
699
+ * @default false
700
+ */
701
+ sortByRelevance?: boolean;
702
+ /**
703
+ * Aggregation configuration
704
+ */
705
+ aggregate?: Aggregate;
706
+ /**
707
+ * Fields to group by (used with aggregate)
708
+ */
709
+ groupBy?: string[];
710
+ /**
711
+ * Include soft-deleted items
712
+ * @default false
713
+ */
714
+ paranoid?: boolean;
715
+ /**
716
+ * Filter conditions for related items (O2M/M2M)
717
+ */
718
+ relConditions?: Record<string, Filter>;
719
+ /**
720
+ * Additional metadata
721
+ */
722
+ meta?: T;
723
+ }
724
+ /**
725
+ * Query options for read operations (alias for QueryParams)
726
+ * Core-compatible naming
727
+ */
728
+ type QueryOptions = QueryParams;
729
+ /**
730
+ * Query context (used internally in core)
731
+ */
732
+ interface QueryContext {
733
+ collection: string;
734
+ filter?: Filter;
735
+ sort?: Sort;
736
+ fields?: string[];
737
+ limit?: number;
738
+ page?: number;
739
+ offset?: number;
740
+ aggregate?: Aggregate;
741
+ groupBy?: string[];
742
+ }
743
+ /**
744
+ * Report configuration
745
+ */
746
+ interface ReportConfig {
747
+ collection: string;
748
+ filter?: Record<string, unknown>;
749
+ groupBy?: string;
750
+ aggregate?: Record<string, unknown>;
751
+ dateRange?: {
752
+ start: string;
753
+ end: string;
754
+ field?: string;
755
+ };
756
+ }
757
+ /**
758
+ * Report result
759
+ */
760
+ interface ReportResult {
761
+ data: Record<string, unknown>[];
762
+ summary?: Record<string, unknown>;
763
+ }
764
+ /**
765
+ * Report query parameters
766
+ */
767
+ interface ReportQuery {
768
+ fields?: string[];
769
+ filter?: Record<string, any>;
770
+ sort?: string[];
771
+ limit?: number;
772
+ page?: number;
773
+ aggregate?: Record<string, any>;
774
+ groupBy?: string[];
775
+ }
776
+ /**
777
+ * Stats query
778
+ */
779
+ interface StatsQuery {
780
+ name: string;
781
+ query: Record<string, unknown>;
782
+ collection: string;
783
+ }
784
+ /**
785
+ * Stats result
786
+ */
787
+ interface StatsResult {
788
+ data: Record<string, unknown>;
789
+ totalStats: number;
790
+ successfulStats: number;
791
+ }
792
+
793
+ /**
794
+ * Response Types
795
+ * Shared across core, sdk, cli, and app packages
796
+ */
797
+ /**
798
+ * Paginated response
799
+ */
800
+ interface PaginatedResponse<T> {
801
+ data: T[];
802
+ totalCount?: number;
803
+ page?: number;
804
+ limit?: number;
805
+ totalPages?: number;
806
+ }
807
+ /**
808
+ * Single item response
809
+ */
810
+ interface SingleResponse<T> {
811
+ data: T;
812
+ }
813
+ /**
814
+ * Create/Update response
815
+ */
816
+ interface MutationResponse<T = string> {
817
+ data: T;
818
+ message?: string;
819
+ }
820
+ /**
821
+ * Delete response
822
+ */
823
+ interface DeleteResponse {
824
+ data: {
825
+ deleted: boolean;
826
+ count?: number;
827
+ };
828
+ message?: string;
829
+ }
830
+ /**
831
+ * Bulk operation response
832
+ */
833
+ interface BulkResponse<T = string[]> {
834
+ data: T;
835
+ message?: string;
836
+ errors?: Array<{
837
+ index: number;
838
+ error: string;
839
+ }>;
840
+ }
841
+ /**
842
+ * Read result (used internally in services)
843
+ */
844
+ interface ReadResult<T = any> {
845
+ data: T[];
846
+ totalCount: number;
847
+ page?: number;
848
+ limit?: number;
849
+ }
850
+ /**
851
+ * Error response
852
+ */
853
+ interface ErrorResponse {
854
+ error: string;
855
+ message: string;
856
+ status: number;
857
+ details?: unknown[];
858
+ }
859
+
860
+ /**
861
+ * File & Asset Types
862
+ * Shared across core, sdk, and app packages
863
+ */
864
+ /**
865
+ * File metadata
866
+ */
867
+ interface FileMetadata {
868
+ id: string;
869
+ title?: string;
870
+ description?: string;
871
+ filename: string;
872
+ mimeType: string;
873
+ size: number;
874
+ width?: number;
875
+ height?: number;
876
+ duration?: number;
877
+ storage: string;
878
+ path: string;
879
+ isPublic?: boolean;
880
+ uploadedBy?: string;
881
+ tenant_Id?: string;
882
+ createdAt: string;
883
+ updatedAt?: string;
884
+ [key: string]: unknown;
885
+ }
886
+ /**
887
+ * File data (internal use)
888
+ */
889
+ interface FileData {
890
+ buffer: Buffer;
891
+ filename: string;
892
+ mimetype: string;
893
+ size: number;
894
+ }
895
+ /**
896
+ * Upload options
897
+ */
898
+ interface UploadOptions {
899
+ title?: string;
900
+ description?: string;
901
+ folder?: string;
902
+ storage?: "local" | "s3";
903
+ isPublic?: boolean;
904
+ metadata?: Record<string, unknown>;
905
+ onProgress?: (progress: number) => void;
906
+ /** Request timeout in milliseconds (default: 30000). Set to 0 for no timeout. */
907
+ timeout?: number;
908
+ }
909
+ /**
910
+ * Internal uploaded file (from express-fileupload)
911
+ */
912
+ interface InternalUploadedFile {
913
+ name: string;
914
+ data: Buffer;
915
+ size: number;
916
+ encoding: string;
917
+ tempFilePath: string;
918
+ truncated: boolean;
919
+ mimetype: string;
920
+ md5: string;
921
+ mv: (path: string) => Promise<void>;
922
+ }
923
+ /**
924
+ * Asset transform options
925
+ */
926
+ interface AssetTransformOptions {
927
+ width?: number;
928
+ height?: number;
929
+ fit?: "cover" | "contain" | "fill" | "inside" | "outside";
930
+ quality?: number;
931
+ format?: "jpeg" | "png" | "webp" | "avif";
932
+ }
933
+ /**
934
+ * Asset query parameters (from HTTP query string)
935
+ * Values can be string | number since they come from query params
936
+ */
937
+ interface AssetQuery {
938
+ width?: string | number;
939
+ height?: string | number;
940
+ fit?: "cover" | "contain" | "fill" | "inside" | "outside" | string;
941
+ quality?: string | number;
942
+ format?: string;
943
+ withoutEnlargement?: string | boolean;
944
+ }
945
+ /**
946
+ * Processed image result
947
+ */
948
+ interface ProcessedImage {
949
+ buffer: Buffer;
950
+ /** Content type (e.g., 'image/jpeg') or format (e.g., 'jpeg') */
951
+ contentType?: string;
952
+ format?: string;
953
+ width?: number;
954
+ height?: number;
955
+ }
956
+ /**
957
+ * Storage provider type
958
+ */
959
+ type StorageProvider = "local" | "s3" | "gcs" | "azure";
960
+ /**
961
+ * Storage adapter interface
962
+ */
963
+ interface StorageAdapter {
964
+ getItem(key: string): string | null | Promise<string | null>;
965
+ setItem(key: string, value: string): void | Promise<void>;
966
+ removeItem(key: string): void | Promise<void>;
967
+ }
968
+ /**
969
+ * Uploaded file interface (from multipart form)
970
+ */
971
+ interface UploadedFile {
972
+ originalname: string;
973
+ mimetype: string;
974
+ buffer: Buffer;
975
+ size: number;
976
+ }
977
+ /**
978
+ * Import options
979
+ */
980
+ interface ImportOptions {
981
+ collection: string;
982
+ file?: UploadedFile;
983
+ data?: unknown[];
984
+ format?: "csv" | "json";
985
+ mapping?: Record<string, string>;
986
+ skipValidation?: boolean;
987
+ batchSize?: number;
988
+ onProgress?: (processed: number, total: number) => void;
989
+ onError?: (error: Error, row: unknown, index: number) => void;
990
+ }
991
+ /**
992
+ * Export options
993
+ */
994
+ interface ExportOptions {
995
+ collection: string;
996
+ format?: "csv" | "json";
997
+ fields?: string[];
998
+ filter?: Record<string, unknown>;
999
+ limit?: number;
1000
+ offset?: number;
1001
+ }
1002
+ /**
1003
+ * Import result
1004
+ */
1005
+ interface ImportResult {
1006
+ success: boolean;
1007
+ imported: number;
1008
+ failed: number;
1009
+ errors: Array<{
1010
+ row: number;
1011
+ error: string;
1012
+ data?: unknown;
1013
+ }>;
1014
+ duration: number;
1015
+ }
1016
+ /**
1017
+ * Export result
1018
+ */
1019
+ interface ExportResult {
1020
+ success: boolean;
1021
+ data: string | unknown[];
1022
+ count: number;
1023
+ format: string;
1024
+ }
1025
+
1026
+ /**
1027
+ * Workflow Types
1028
+ * Shared across core, sdk, and app packages
1029
+ */
1030
+ /**
1031
+ * Workflow trigger types
1032
+ */
1033
+ type WorkflowTriggerType = "manual" | "webhook" | "schedule" | "hook" | "cron";
1034
+ /**
1035
+ * Workflow status
1036
+ */
1037
+ type WorkflowStatus = "draft" | "active" | "inactive" | "archived";
1038
+ /**
1039
+ * Workflow definition
1040
+ */
1041
+ interface Workflow {
1042
+ id: string;
1043
+ name: string;
1044
+ description?: string;
1045
+ status: WorkflowStatus;
1046
+ /** @deprecated Use status instead. Kept for backward compatibility. */
1047
+ isActive?: boolean;
1048
+ trigger_type?: WorkflowTriggerType;
1049
+ /** Alternative trigger format used by SDK */
1050
+ trigger?: WorkflowTrigger;
1051
+ trigger_cron?: string;
1052
+ trigger_webhook_path?: string;
1053
+ trigger_webhook_method?: string;
1054
+ trigger_hook_collection?: string;
1055
+ trigger_hook_action?: string;
1056
+ allowed_roles?: string[];
1057
+ flow_data?: WorkflowFlowData;
1058
+ /** Alternative format: nodes at top level */
1059
+ nodes?: WorkflowNode[];
1060
+ /** Alternative format: edges at top level */
1061
+ edges?: WorkflowEdge[];
1062
+ variables?: Record<string, unknown>;
1063
+ options?: Record<string, unknown>;
1064
+ createdAt?: string;
1065
+ updatedAt?: string;
1066
+ }
1067
+ /**
1068
+ * Workflow flow data (React Flow format)
1069
+ */
1070
+ interface WorkflowFlowData {
1071
+ nodes: WorkflowNode[];
1072
+ edges: WorkflowEdge[];
1073
+ viewport?: {
1074
+ x: number;
1075
+ y: number;
1076
+ zoom: number;
1077
+ };
1078
+ }
1079
+ /**
1080
+ * Workflow trigger configuration
1081
+ */
1082
+ interface WorkflowTrigger {
1083
+ type: WorkflowTriggerType;
1084
+ config?: Record<string, unknown>;
1085
+ }
1086
+ /**
1087
+ * Workflow node
1088
+ */
1089
+ interface WorkflowNode {
1090
+ id: string;
1091
+ type: string;
1092
+ data: WorkflowNodeData;
1093
+ position: {
1094
+ x: number;
1095
+ y: number;
1096
+ };
1097
+ }
1098
+ /**
1099
+ * Workflow node data
1100
+ */
1101
+ interface WorkflowNodeData {
1102
+ label?: string;
1103
+ [key: string]: unknown;
1104
+ }
1105
+ /**
1106
+ * Workflow edge
1107
+ */
1108
+ interface WorkflowEdge {
1109
+ id: string;
1110
+ source: string;
1111
+ target: string;
1112
+ sourceHandle?: string;
1113
+ targetHandle?: string;
1114
+ condition?: string;
1115
+ label?: string;
1116
+ }
1117
+ /**
1118
+ * Workflow execution status
1119
+ */
1120
+ type WorkflowExecutionStatus = "queued" | "pending" | "running" | "completed" | "failed" | "cancelled";
1121
+ /**
1122
+ * Workflow execution
1123
+ */
1124
+ interface WorkflowExecution {
1125
+ id: string;
1126
+ workflow_Id: string;
1127
+ status: WorkflowExecutionStatus;
1128
+ triggeredBy?: string;
1129
+ triggerData?: Record<string, unknown>;
1130
+ result?: Record<string, unknown>;
1131
+ error?: string;
1132
+ durationMs?: number;
1133
+ startedAt?: string;
1134
+ completedAt?: string;
1135
+ createdAt: string;
1136
+ updatedAt?: string;
1137
+ }
1138
+ /**
1139
+ * Workflow execution log
1140
+ */
1141
+ interface WorkflowExecutionLog {
1142
+ id: string;
1143
+ execution_Id: string;
1144
+ nodeId: string;
1145
+ nodeType: string;
1146
+ status: "pending" | "running" | "completed" | "failed" | "skipped";
1147
+ input?: Record<string, unknown>;
1148
+ output?: Record<string, unknown>;
1149
+ error?: string;
1150
+ durationMs?: number;
1151
+ startedAt?: string;
1152
+ completedAt?: string;
1153
+ }
1154
+
1155
+ /**
1156
+ * Notification Types
1157
+ * Shared across core, sdk, and app packages
1158
+ */
1159
+ /**
1160
+ * Notification type
1161
+ */
1162
+ type NotificationType = "info" | "success" | "warning" | "error" | string;
1163
+ /**
1164
+ * Notification
1165
+ */
1166
+ interface Notification {
1167
+ id: string;
1168
+ type: NotificationType;
1169
+ title: string;
1170
+ message: string;
1171
+ data?: Record<string, unknown>;
1172
+ seen: boolean;
1173
+ user_Id: string;
1174
+ tenant_Id?: string;
1175
+ createdAt: string;
1176
+ updatedAt?: string;
1177
+ }
1178
+ /**
1179
+ * Notification options (for creating)
1180
+ */
1181
+ interface NotificationOptions {
1182
+ type?: NotificationType;
1183
+ title: string;
1184
+ message: string;
1185
+ data?: Record<string, unknown>;
1186
+ userIds?: string[];
1187
+ tenant_Id?: string;
1188
+ }
1189
+ /**
1190
+ * Send notification data
1191
+ */
1192
+ interface SendNotificationData {
1193
+ type?: NotificationType;
1194
+ title: string;
1195
+ message: string;
1196
+ data?: Record<string, unknown>;
1197
+ userIds: string[];
1198
+ }
1199
+
1200
+ /**
1201
+ * Spatial/GeoJSON Types
1202
+ * Types for geospatial data (PostGIS compatible)
1203
+ */
1204
+ /**
1205
+ * GeoJSON Point
1206
+ */
1207
+ interface GeoJSONPoint {
1208
+ type: "Point";
1209
+ coordinates: [number, number];
1210
+ }
1211
+ /**
1212
+ * GeoJSON LineString
1213
+ */
1214
+ interface GeoJSONLineString {
1215
+ type: "LineString";
1216
+ coordinates: [number, number][];
1217
+ }
1218
+ /**
1219
+ * GeoJSON Polygon
1220
+ */
1221
+ interface GeoJSONPolygon {
1222
+ type: "Polygon";
1223
+ coordinates: [number, number][][];
1224
+ }
1225
+ /**
1226
+ * GeoJSON Geometry (union type)
1227
+ */
1228
+ type GeoJSONGeometry = GeoJSONPoint | GeoJSONLineString | GeoJSONPolygon;
1229
+
1230
+ /**
1231
+ * Cache Types
1232
+ * Types for caching functionality
1233
+ */
1234
+ /**
1235
+ * Cache configuration (SDK/app level)
1236
+ */
1237
+ interface CacheConfig {
1238
+ enabled?: boolean;
1239
+ ttl?: number;
1240
+ prefix?: string;
1241
+ }
1242
+ /**
1243
+ * Cache set options (Redis-style options for cache.set operations)
1244
+ */
1245
+ interface CacheSetOptions {
1246
+ /** Expiration in seconds */
1247
+ ex?: number;
1248
+ [key: string]: unknown;
1249
+ }
1250
+ /**
1251
+ * Cache strategy
1252
+ */
1253
+ type CacheStrategy = "explicit" | "all";
1254
+ /**
1255
+ * Cache entry structure
1256
+ */
1257
+ interface CacheEntry {
1258
+ value: any;
1259
+ expiry: number;
1260
+ tables: string[];
1261
+ tags: string[];
1262
+ tenant?: string | null;
1263
+ }
1264
+ /**
1265
+ * Base interface for all cache adapters
1266
+ * Implement this interface to create custom cache adapters
1267
+ */
1268
+ interface ICacheAdapter {
1269
+ get(key: string): Promise<any | null>;
1270
+ set(key: string, value: any, ttl?: number, metadata?: {
1271
+ tables: string[];
1272
+ tags: string[];
1273
+ tenant?: string | null;
1274
+ }): Promise<void>;
1275
+ delete(key: string): Promise<void>;
1276
+ clear(): Promise<void>;
1277
+ invalidateByPattern(pattern: string): Promise<void>;
1278
+ invalidateByTables(tables: string[], tenant?: string | null): Promise<void>;
1279
+ invalidateByTags(tags: string[], tenant?: string | null): Promise<void>;
1280
+ getStats(): Promise<{
1281
+ keys: number;
1282
+ size?: number;
1283
+ }>;
1284
+ close(): Promise<void>;
1285
+ }
1286
+
1287
+ /**
1288
+ * Common/Utility Types
1289
+ * Shared across all packages
1290
+ */
1291
+ /**
1292
+ * Generic record type with ID
1293
+ */
1294
+ interface BaseItem {
1295
+ id: string;
1296
+ createdAt?: string;
1297
+ updatedAt?: string;
1298
+ deletedAt?: string;
1299
+ [key: string]: unknown;
1300
+ }
1301
+ /**
1302
+ * Timestamped item
1303
+ */
1304
+ interface TimestampedItem {
1305
+ createdAt: string;
1306
+ updatedAt?: string;
1307
+ }
1308
+ /**
1309
+ * Soft deletable item
1310
+ */
1311
+ interface SoftDeletableItem {
1312
+ deletedAt?: string | null;
1313
+ }
1314
+ /**
1315
+ * Make all properties of T optional recursively
1316
+ */
1317
+ type DeepPartial<T> = {
1318
+ [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
1319
+ };
1320
+ /**
1321
+ * Extract the item type from a collection
1322
+ */
1323
+ type CollectionItem<T> = T extends Array<infer U> ? U : T;
1324
+ /**
1325
+ * Make specific properties required
1326
+ */
1327
+ type WithRequired<T, K extends keyof T> = T & {
1328
+ [P in K]-?: T[P];
1329
+ };
1330
+ /**
1331
+ * Make specific properties optional
1332
+ */
1333
+ type WithOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
1334
+ /**
1335
+ * Extract keys of T that have values of type V
1336
+ */
1337
+ type KeysOfType<T, V> = {
1338
+ [K in keyof T]: T[K] extends V ? K : never;
1339
+ }[keyof T];
1340
+ /**
1341
+ * Record with string keys and unknown values
1342
+ */
1343
+ type AnyRecord = Record<string, unknown>;
1344
+ /**
1345
+ * Generic settings
1346
+ */
1347
+ interface Settings {
1348
+ [key: string]: unknown;
1349
+ }
1350
+ /**
1351
+ * Tenant settings
1352
+ */
1353
+ interface TenantSettings {
1354
+ tenant_Id?: string | number | null;
1355
+ project_name?: string;
1356
+ title?: string;
1357
+ project_url?: string | null;
1358
+ app_url?: string | null;
1359
+ project_color?: string;
1360
+ secondary_color?: string;
1361
+ description?: string;
1362
+ keywords?: string;
1363
+ from_email_name?: string;
1364
+ smtp_enabled?: boolean;
1365
+ smtp_host?: string;
1366
+ smtp_port?: number;
1367
+ smtp_secure?: boolean;
1368
+ smtp_user?: string;
1369
+ smtp_pass?: string;
1370
+ smtp_from_address?: string;
1371
+ timezone?: string;
1372
+ language?: string;
1373
+ date_format?: string;
1374
+ currency?: string;
1375
+ email_signature?: string;
1376
+ email_icon?: any;
1377
+ metadata?: Record<string, any>;
1378
+ modules?: Record<string, any>;
1379
+ [key: string]: any;
1380
+ }
1381
+ /**
1382
+ * Background task
1383
+ */
1384
+ interface BackgroundTask {
1385
+ id: string | number;
1386
+ task_status: string;
1387
+ scheduled_time: Date;
1388
+ [key: string]: unknown;
1389
+ }
1390
+ /**
1391
+ * Hook events
1392
+ */
1393
+ type HookEvent = "items.create" | "items.read" | "items.update" | "items.delete" | "auth.login" | "auth.logout" | "auth.register";
1394
+ /**
1395
+ * Hook handler context
1396
+ */
1397
+ interface HookContext {
1398
+ event: HookEvent;
1399
+ collection?: string;
1400
+ payload?: unknown;
1401
+ keys?: string[];
1402
+ accountability?: {
1403
+ user?: {
1404
+ id: string;
1405
+ };
1406
+ role?: {
1407
+ id: string;
1408
+ name: string;
1409
+ };
1410
+ tenant?: {
1411
+ id: string;
1412
+ };
1413
+ };
1414
+ }
1415
+ /**
1416
+ * Hook handler function
1417
+ */
1418
+ type HookHandler = (context: HookContext) => void | Promise<void>;
1419
+ /**
1420
+ * Hook definition
1421
+ */
1422
+ interface Hook {
1423
+ event: HookEvent;
1424
+ collection?: string;
1425
+ handler: HookHandler;
1426
+ }
1427
+ /**
1428
+ * HTTP methods
1429
+ */
1430
+ type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "OPTIONS" | "HEAD";
1431
+ /**
1432
+ * Mail options for sending emails
1433
+ */
1434
+ interface MailOptions {
1435
+ to: string | string[];
1436
+ subject: string;
1437
+ html?: string;
1438
+ text?: string;
1439
+ from?: string;
1440
+ cc?: string | string[];
1441
+ bcc?: string | string[];
1442
+ replyTo?: string;
1443
+ attachments?: Array<{
1444
+ filename: string;
1445
+ content?: string | Buffer;
1446
+ path?: string;
1447
+ contentType?: string;
1448
+ }>;
1449
+ }
1450
+ /**
1451
+ * Sender configuration for email
1452
+ */
1453
+ interface SenderConfig {
1454
+ from: string;
1455
+ name?: string;
1456
+ replyTo?: string;
1457
+ }
1458
+ /**
1459
+ * Seed data configuration
1460
+ */
1461
+ interface SeedData {
1462
+ collection: string;
1463
+ data: Record<string, unknown> | Record<string, unknown>[];
1464
+ /** Whether to clear existing data before seeding */
1465
+ clearBefore?: boolean;
1466
+ /** Whether to skip if data already exists (check by unique fields) */
1467
+ skipDuplicates?: boolean;
1468
+ }
1469
+ /**
1470
+ * Seed operation result
1471
+ */
1472
+ interface SeedResult {
1473
+ collection: string;
1474
+ created: number;
1475
+ skipped: number;
1476
+ errors: number;
1477
+ errorDetails?: Array<{
1478
+ item: unknown;
1479
+ error: string;
1480
+ }>;
1481
+ }
1482
+
1483
+ /**
1484
+ * Plugin System Types
1485
+ * Shared types for Baasix plugin development
1486
+ */
1487
+
1488
+ /** Express Request type */
1489
+ type Request = Request$1;
1490
+ /** Express Response type */
1491
+ type Response = Response$1;
1492
+ /** Express NextFunction type */
1493
+ type NextFunction = NextFunction$1;
1494
+ /** Express Application type */
1495
+ type Express = Express$1;
1496
+ /** Express Router type */
1497
+ type Router = Router$1;
1498
+ /** Type aliases for clarity */
1499
+ type ExpressRequest = Request$1;
1500
+ type ExpressResponse = Response$1;
1501
+ type ExpressNextFunction = NextFunction$1;
1502
+ type ExpressApp = Express$1;
1503
+ type ExpressRouter = Router$1;
1504
+ /**
1505
+ * Generic request type (compatible with Express Request)
1506
+ */
1507
+ interface PluginRequest {
1508
+ params: Record<string, string>;
1509
+ query: Record<string, any>;
1510
+ body: any;
1511
+ headers: Record<string, string | string[] | undefined>;
1512
+ method: string;
1513
+ path: string;
1514
+ url: string;
1515
+ originalUrl: string;
1516
+ baseUrl: string;
1517
+ cookies?: Record<string, string>;
1518
+ signedCookies?: Record<string, string>;
1519
+ ip?: string;
1520
+ ips?: string[];
1521
+ hostname?: string;
1522
+ protocol?: string;
1523
+ secure?: boolean;
1524
+ xhr?: boolean;
1525
+ accountability?: Accountability;
1526
+ get(header: string): string | undefined;
1527
+ header(header: string): string | undefined;
1528
+ accepts(...types: string[]): string | false;
1529
+ is(type: string): string | false | null;
1530
+ [key: string]: any;
1531
+ }
1532
+ /**
1533
+ * Generic response type (compatible with Express Response)
1534
+ */
1535
+ interface PluginResponse {
1536
+ status(code: number): PluginResponse;
1537
+ sendStatus(code: number): PluginResponse;
1538
+ json(data: any): PluginResponse;
1539
+ send(data: any): PluginResponse;
1540
+ end(data?: any): PluginResponse;
1541
+ set(header: string, value: string | string[]): PluginResponse;
1542
+ set(headers: Record<string, string | string[]>): PluginResponse;
1543
+ header(header: string, value: string | string[]): PluginResponse;
1544
+ get(header: string): string | undefined;
1545
+ type(type: string): PluginResponse;
1546
+ contentType(type: string): PluginResponse;
1547
+ redirect(url: string): void;
1548
+ redirect(status: number, url: string): void;
1549
+ cookie(name: string, value: string, options?: Record<string, any>): PluginResponse;
1550
+ clearCookie(name: string, options?: Record<string, any>): PluginResponse;
1551
+ attachment(filename?: string): PluginResponse;
1552
+ download(path: string, filename?: string): void;
1553
+ locals: Record<string, any>;
1554
+ headersSent: boolean;
1555
+ statusCode: number;
1556
+ [key: string]: any;
1557
+ }
1558
+ /**
1559
+ * Generic next function type (compatible with Express NextFunction)
1560
+ */
1561
+ type PluginNextFunction = (error?: any) => void;
1562
+ /**
1563
+ * Generic Express application type
1564
+ */
1565
+ interface PluginApp {
1566
+ use(...handlers: any[]): PluginApp;
1567
+ get(path: string, ...handlers: any[]): PluginApp;
1568
+ post(path: string, ...handlers: any[]): PluginApp;
1569
+ put(path: string, ...handlers: any[]): PluginApp;
1570
+ patch(path: string, ...handlers: any[]): PluginApp;
1571
+ delete(path: string, ...handlers: any[]): PluginApp;
1572
+ options(path: string, ...handlers: any[]): PluginApp;
1573
+ all(path: string, ...handlers: any[]): PluginApp;
1574
+ listen(port: number, callback?: () => void): any;
1575
+ set(setting: string, value: any): PluginApp;
1576
+ get(setting: string): any;
1577
+ locals: Record<string, any>;
1578
+ [key: string]: any;
1579
+ }
1580
+ /**
1581
+ * Generic Router type (compatible with Express Router)
1582
+ */
1583
+ interface PluginRouter {
1584
+ use(...handlers: any[]): PluginRouter;
1585
+ get(path: string, ...handlers: any[]): PluginRouter;
1586
+ post(path: string, ...handlers: any[]): PluginRouter;
1587
+ put(path: string, ...handlers: any[]): PluginRouter;
1588
+ patch(path: string, ...handlers: any[]): PluginRouter;
1589
+ delete(path: string, ...handlers: any[]): PluginRouter;
1590
+ options(path: string, ...handlers: any[]): PluginRouter;
1591
+ all(path: string, ...handlers: any[]): PluginRouter;
1592
+ [key: string]: any;
1593
+ }
1594
+ /**
1595
+ * Base service options with accountability
1596
+ */
1597
+ interface ServiceOptions {
1598
+ accountability?: Accountability;
1599
+ [key: string]: any;
1600
+ }
1601
+ /**
1602
+ * Items service interface for CRUD operations
1603
+ * Note: Actual implementations may have additional methods and different signatures.
1604
+ * The index signature provides flexibility for all implementations.
1605
+ */
1606
+ interface IItemsService {
1607
+ [key: string]: any;
1608
+ }
1609
+ /**
1610
+ * Permission service interface
1611
+ */
1612
+ interface IPermissionService {
1613
+ [key: string]: any;
1614
+ }
1615
+ /**
1616
+ * Mail service interface
1617
+ */
1618
+ interface IMailService {
1619
+ [key: string]: any;
1620
+ }
1621
+ /**
1622
+ * Storage service interface
1623
+ */
1624
+ interface IStorageService {
1625
+ [key: string]: any;
1626
+ }
1627
+ /**
1628
+ * Settings service interface
1629
+ */
1630
+ interface ISettingsService {
1631
+ [key: string]: any;
1632
+ }
1633
+ /**
1634
+ * Socket service interface
1635
+ */
1636
+ interface ISocketService {
1637
+ [key: string]: any;
1638
+ }
1639
+ /**
1640
+ * Realtime service interface
1641
+ */
1642
+ interface IRealtimeService {
1643
+ [key: string]: any;
1644
+ }
1645
+ /**
1646
+ * Tasks service interface
1647
+ */
1648
+ interface ITasksService {
1649
+ [key: string]: any;
1650
+ }
1651
+ /**
1652
+ * Workflow service interface
1653
+ */
1654
+ interface IWorkflowService {
1655
+ [key: string]: any;
1656
+ }
1657
+ /**
1658
+ * Migration service interface
1659
+ */
1660
+ interface IMigrationService {
1661
+ [key: string]: any;
1662
+ }
1663
+ /**
1664
+ * Hook function type - called during lifecycle events
1665
+ */
1666
+ type HookFunction = (context: PluginHookContext) => Promise<PluginHookContext> | PluginHookContext;
1667
+ /**
1668
+ * Hooks manager interface - manages lifecycle hooks for collections
1669
+ */
1670
+ interface IHooksManager {
1671
+ /**
1672
+ * Register a hook for a collection and event
1673
+ * @param collection - Collection name (use '*' for all collections)
1674
+ * @param event - Event name (e.g., 'items.create', 'items.update')
1675
+ * @param hookFunction - Function to execute
1676
+ */
1677
+ registerHook(collection: string, event: string, hookFunction: HookFunction): void;
1678
+ /**
1679
+ * Get hooks for a collection and event
1680
+ * @param collection - Collection name
1681
+ * @param event - Event name
1682
+ * @returns Array of registered hook functions
1683
+ */
1684
+ getHooks(collection: string, event: string): HookFunction[];
1685
+ /**
1686
+ * Execute hooks for a collection and event
1687
+ * @param collection - Collection name
1688
+ * @param event - Event name
1689
+ * @param accountability - User/role accountability info
1690
+ * @param context - Hook context with data
1691
+ * @returns Modified context after all hooks execute
1692
+ */
1693
+ executeHooks(collection: string, event: string, accountability: Accountability | undefined, context: PluginHookContext): Promise<PluginHookContext>;
1694
+ /**
1695
+ * Load hooks from extensions directory
1696
+ * @param context - Plugin context
1697
+ * @param directory - Optional directory path
1698
+ */
1699
+ loadHooksFromDirectory?(context: any, directory?: string): Promise<void>;
1700
+ /**
1701
+ * Load schedules from extensions directory
1702
+ * @param context - Plugin context
1703
+ * @param schedule - Schedule manager
1704
+ * @param directory - Optional directory path
1705
+ */
1706
+ loadSchedulesFromDirectory?(context: any, schedule: any, directory?: string): Promise<void>;
1707
+ /** Allow additional methods/properties */
1708
+ [key: string]: any;
1709
+ }
1710
+ /**
1711
+ * Cache service interface
1712
+ */
1713
+ interface ICacheService {
1714
+ [key: string]: any;
1715
+ }
1716
+ /**
1717
+ * Files service interface
1718
+ */
1719
+ interface IFilesService {
1720
+ [key: string]: any;
1721
+ }
1722
+ /**
1723
+ * Assets service interface
1724
+ */
1725
+ interface IAssetsService {
1726
+ [key: string]: any;
1727
+ }
1728
+ /**
1729
+ * Notification service interface
1730
+ */
1731
+ interface INotificationService {
1732
+ [key: string]: any;
1733
+ }
1734
+ /**
1735
+ * Report service interface
1736
+ */
1737
+ interface IReportService {
1738
+ [key: string]: any;
1739
+ }
1740
+ /**
1741
+ * Stats service interface
1742
+ */
1743
+ interface IStatsService {
1744
+ [key: string]: any;
1745
+ }
1746
+ /**
1747
+ * Plugin types categorize plugins by their primary function
1748
+ */
1749
+ type PluginType = "feature" | "auth" | "payment" | "storage" | "ai" | "notification" | "integration";
1750
+ /**
1751
+ * Plugin metadata - information about the plugin
1752
+ */
1753
+ interface PluginMeta {
1754
+ /** Unique plugin name (used as identifier) */
1755
+ name: string;
1756
+ /** Plugin version (semver) */
1757
+ version: string;
1758
+ /** Plugin type/category */
1759
+ type: PluginType;
1760
+ /** Human-readable description */
1761
+ description?: string;
1762
+ /** Plugin author */
1763
+ author?: string;
1764
+ /** Plugin dependencies (names of other plugins that must be loaded first) */
1765
+ dependencies?: string[];
1766
+ }
1767
+ /**
1768
+ * Schema definition for plugin collections
1769
+ */
1770
+ interface PluginSchemaDefinition {
1771
+ collectionName: string;
1772
+ schema: SchemaDefinition;
1773
+ }
1774
+ /**
1775
+ * Plugin route handler context - available in route handlers
1776
+ */
1777
+ interface PluginRouteContext {
1778
+ /** Database connection */
1779
+ db: any;
1780
+ /** ItemsService class for CRUD operations */
1781
+ ItemsService: new (...args: any[]) => IItemsService;
1782
+ /** Registered plugin services */
1783
+ services: Record<string, any>;
1784
+ /** Permission service (singleton) */
1785
+ permissionService?: IPermissionService;
1786
+ /** Mail service (singleton) */
1787
+ mailService?: IMailService;
1788
+ /** Storage service (singleton) */
1789
+ storageService?: IStorageService;
1790
+ /** Settings service (singleton) */
1791
+ settingsService?: ISettingsService;
1792
+ /** Socket service (singleton) */
1793
+ socketService?: ISocketService;
1794
+ /** Realtime service (singleton) */
1795
+ realtimeService?: IRealtimeService;
1796
+ /** Tasks service (singleton) */
1797
+ tasksService?: ITasksService;
1798
+ /** Workflow service (singleton) */
1799
+ workflowService?: IWorkflowService;
1800
+ /** Migration service (singleton) */
1801
+ migrationService?: IMigrationService;
1802
+ /** Get cache service instance */
1803
+ getCacheService?: () => ICacheService;
1804
+ /** FilesService class */
1805
+ FilesService?: new (...args: any[]) => IFilesService;
1806
+ /** AssetsService class */
1807
+ AssetsService?: new (...args: any[]) => IAssetsService;
1808
+ /** NotificationService class */
1809
+ NotificationService?: new (...args: any[]) => INotificationService;
1810
+ /** ReportService class */
1811
+ ReportService?: new (...args: any[]) => IReportService;
1812
+ /** StatsService class */
1813
+ StatsService?: new (...args: any[]) => IStatsService;
1814
+ /** Plugin configuration */
1815
+ config: Record<string, any>;
1816
+ }
1817
+ /**
1818
+ * Plugin route handler function
1819
+ */
1820
+ type PluginRouteHandler<TReq = PluginRequest, TRes = PluginResponse> = (req: TReq, res: TRes, context: PluginRouteContext) => Promise<any> | any;
1821
+ /**
1822
+ * Plugin route definition
1823
+ */
1824
+ interface PluginRoute<TReq = PluginRequest, TRes = PluginResponse> {
1825
+ /** Route path (e.g., '/payments/stripe/checkout') */
1826
+ path: string;
1827
+ /** HTTP method */
1828
+ method: HttpMethod;
1829
+ /** Route handler */
1830
+ handler: PluginRouteHandler<TReq, TRes>;
1831
+ /** Whether authentication is required */
1832
+ requireAuth?: boolean;
1833
+ /** Whether to parse raw body (for webhooks) */
1834
+ rawBody?: boolean;
1835
+ /** Custom middleware for this route */
1836
+ middleware?: Array<(req: TReq, res: TRes, next: PluginNextFunction) => void>;
1837
+ /** Route description for documentation */
1838
+ description?: string;
1839
+ }
1840
+ /**
1841
+ * Plugin hook event types
1842
+ */
1843
+ type PluginHookEvent = "items.create" | "items.read" | "items.update" | "items.delete" | "items.create.after" | "items.read.after" | "items.update.after" | "items.delete.after";
1844
+ /**
1845
+ * Plugin hook context - passed to hook handlers
1846
+ * All properties are optional to allow flexibility in different contexts
1847
+ */
1848
+ interface PluginHookContext {
1849
+ collection?: string;
1850
+ accountability?: Accountability;
1851
+ db?: any;
1852
+ data?: any;
1853
+ id?: string | number;
1854
+ query?: any;
1855
+ schema?: any;
1856
+ transaction?: any;
1857
+ [key: string]: any;
1858
+ }
1859
+ /**
1860
+ * Plugin hook handler function
1861
+ */
1862
+ type PluginHookHandler = (context: PluginHookContext) => Promise<PluginHookContext> | PluginHookContext;
1863
+ /**
1864
+ * Plugin hook definition
1865
+ */
1866
+ interface PluginHook {
1867
+ /** Collection name (use '*' for all collections) */
1868
+ collection: string;
1869
+ /** Hook event */
1870
+ event: PluginHookEvent;
1871
+ /** Hook handler */
1872
+ handler: PluginHookHandler;
1873
+ /** Hook priority (lower runs first) */
1874
+ priority?: number;
1875
+ }
1876
+ /**
1877
+ * Plugin context - passed to lifecycle hooks and service factories
1878
+ */
1879
+ interface PluginContext extends PluginRouteContext {
1880
+ /** Hooks manager (singleton) */
1881
+ hooksManager?: IHooksManager;
1882
+ /** Invalidate cache for a collection */
1883
+ invalidateCache?: (collection?: string) => Promise<void>;
1884
+ /** Express app instance (when available) */
1885
+ app?: PluginApp;
1886
+ /** Get another plugin's service */
1887
+ getPluginService: (pluginName: string, serviceName: string) => any;
1888
+ }
1889
+ /**
1890
+ * Plugin service factory function
1891
+ */
1892
+ type PluginServiceFactory = (context: PluginContext) => any;
1893
+ /**
1894
+ * Plugin service definition
1895
+ */
1896
+ interface PluginService {
1897
+ /** Service name (used to access via context.services.name) */
1898
+ name: string;
1899
+ /** Service factory function */
1900
+ factory: PluginServiceFactory;
1901
+ }
1902
+ /**
1903
+ * Plugin auth provider type
1904
+ */
1905
+ type AuthProviderType = "oauth2" | "otp" | "passkey" | "custom";
1906
+ /**
1907
+ * OAuth2 configuration
1908
+ */
1909
+ interface OAuth2Config {
1910
+ authorizationUrl: string;
1911
+ tokenUrl: string;
1912
+ userInfoUrl: string;
1913
+ clientId: string;
1914
+ clientSecret: string;
1915
+ scope?: string[];
1916
+ }
1917
+ /**
1918
+ * Plugin auth provider definition
1919
+ */
1920
+ interface PluginAuthProvider {
1921
+ /** Provider identifier (e.g., 'github', 'otp') */
1922
+ id: string;
1923
+ /** Display name */
1924
+ name: string;
1925
+ /** Provider type */
1926
+ type: AuthProviderType;
1927
+ /** OAuth2 configuration (for oauth2 type) */
1928
+ oauth2Config?: OAuth2Config;
1929
+ /** Custom authentication handler */
1930
+ authenticate?: (credentials: Record<string, any>, context: PluginContext) => Promise<{
1931
+ user: any;
1932
+ account?: any;
1933
+ } | null>;
1934
+ /** Custom routes for this provider */
1935
+ routes?: PluginRoute[];
1936
+ }
1937
+ /**
1938
+ * Plugin middleware definition
1939
+ */
1940
+ interface PluginMiddleware<TReq = PluginRequest, TRes = PluginResponse> {
1941
+ /** Middleware name (for debugging) */
1942
+ name: string;
1943
+ /** Path pattern (optional, defaults to all routes) */
1944
+ path?: string;
1945
+ /** Middleware handler */
1946
+ handler: (req: TReq, res: TRes, next: PluginNextFunction) => void;
1947
+ /** Priority (lower runs first) */
1948
+ priority?: number;
1949
+ }
1950
+ /**
1951
+ * Plugin schedule definition
1952
+ */
1953
+ interface PluginSchedule {
1954
+ /** Schedule name */
1955
+ name: string;
1956
+ /** Cron expression */
1957
+ cron: string;
1958
+ /** Schedule handler */
1959
+ handler: (context: PluginContext) => Promise<void> | void;
1960
+ /** Whether to run immediately on startup */
1961
+ runOnStart?: boolean;
1962
+ }
1963
+ /**
1964
+ * Plugin definition - what a plugin provides
1965
+ */
1966
+ interface PluginDefinition {
1967
+ /** Plugin metadata */
1968
+ meta: PluginMeta;
1969
+ /** Schema extensions - new collections/tables */
1970
+ schemas?: PluginSchemaDefinition[];
1971
+ /** Route extensions - new API endpoints */
1972
+ routes?: PluginRoute[];
1973
+ /** Hook extensions - lifecycle hooks */
1974
+ hooks?: PluginHook[];
1975
+ /** Service extensions - new services */
1976
+ services?: PluginService[];
1977
+ /** Auth provider extensions */
1978
+ authProviders?: PluginAuthProvider[];
1979
+ /** Middleware extensions */
1980
+ middleware?: PluginMiddleware[];
1981
+ /** Scheduled tasks */
1982
+ schedules?: PluginSchedule[];
1983
+ /** Called when the plugin is initialized */
1984
+ onInit?: (context: PluginContext) => Promise<void>;
1985
+ /** Called when all plugins are loaded and server is ready */
1986
+ onReady?: (context: PluginContext) => Promise<void>;
1987
+ /** Called when the server is shutting down */
1988
+ onShutdown?: (context: PluginContext) => Promise<void>;
1989
+ }
1990
+ /**
1991
+ * Plugin factory function - creates a plugin with configuration
1992
+ */
1993
+ type PluginFactory<TConfig = Record<string, any>> = (config: TConfig) => PluginDefinition;
1994
+ /**
1995
+ * Baasix plugin type
1996
+ */
1997
+ type BaasixPlugin = PluginDefinition;
1998
+ /**
1999
+ * Loaded plugin - plugin with runtime state
2000
+ */
2001
+ interface LoadedPlugin {
2002
+ /** Plugin definition */
2003
+ definition: PluginDefinition;
2004
+ /** Plugin configuration */
2005
+ config: Record<string, any>;
2006
+ /** Plugin services (instantiated) */
2007
+ services: Record<string, any>;
2008
+ /** Whether the plugin has been initialized */
2009
+ initialized: boolean;
2010
+ /** Whether the plugin is ready */
2011
+ ready: boolean;
2012
+ }
2013
+ /**
2014
+ * Plugin manager options
2015
+ */
2016
+ interface PluginManagerOptions {
2017
+ /** Whether to log plugin loading */
2018
+ verbose?: boolean;
2019
+ }
2020
+ /**
2021
+ * Start server options with plugin support
2022
+ */
2023
+ interface StartServerOptions {
2024
+ /** Server port */
2025
+ port?: number;
2026
+ /** Plugins to load */
2027
+ plugins?: BaasixPlugin[];
2028
+ /** Plugin manager options */
2029
+ pluginOptions?: PluginManagerOptions;
2030
+ }
2031
+ /**
2032
+ * Plugin route handler function with Express types
2033
+ */
2034
+ type ExpressPluginRouteHandler = (req: Request, res: Response, context: PluginRouteContext) => Promise<any> | any;
2035
+ /**
2036
+ * Plugin route definition with Express types
2037
+ */
2038
+ interface ExpressPluginRoute extends Omit<PluginRoute, 'handler' | 'middleware'> {
2039
+ /** Route handler */
2040
+ handler: ExpressPluginRouteHandler;
2041
+ /** Custom middleware for this route */
2042
+ middleware?: Array<(req: Request, res: Response, next: NextFunction) => void>;
2043
+ }
2044
+ /**
2045
+ * Plugin middleware definition with Express types
2046
+ */
2047
+ interface ExpressPluginMiddleware extends Omit<PluginMiddleware, 'handler'> {
2048
+ /** Middleware handler */
2049
+ handler: (req: Request, res: Response, next: NextFunction) => void;
2050
+ }
2051
+ /**
2052
+ * Plugin context with Express types
2053
+ */
2054
+ interface ExpressPluginContext extends PluginRouteContext {
2055
+ /** Hooks manager (singleton) - lifecycle hooks for collections */
2056
+ hooksManager?: IHooksManager;
2057
+ /** Invalidate cache for a collection */
2058
+ invalidateCache?: (collection?: string) => Promise<void>;
2059
+ /** Express app instance */
2060
+ app?: Express;
2061
+ /** Get another plugin's service */
2062
+ getPluginService: (pluginName: string, serviceName: string) => any;
2063
+ }
2064
+
2065
+ 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, 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 };