@stoker-platform/types 0.2.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,1074 @@
1
+ import { FieldValue } from "firebase-admin/firestore"
2
+ import { Timestamp, WhereFilterOp, WriteBatch } from "firebase/firestore"
3
+ import { NodeUtilities, WebUtilities } from "./app"
4
+ import { CalendarOptions } from "@fullcalendar/core"
5
+ import { SearchResult } from "minisearch"
6
+
7
+ export type StokerRole = string
8
+ export type StokerCollection = string
9
+
10
+ export type FirebaseTimestamp = Timestamp | FieldValue
11
+
12
+ /* eslint-disable @typescript-eslint/no-explicit-any */
13
+
14
+ export interface StokerRelation {
15
+ Collection_Path: string[]
16
+ [key: string]: any
17
+ }
18
+
19
+ export interface StokerRelationObject {
20
+ [id: string]: StokerRelation
21
+ }
22
+ export type StokerRelationArray = string[]
23
+
24
+ export interface StokerRecord {
25
+ Collection_Path: string[]
26
+ Last_Write_At: Timestamp | FieldValue
27
+ Last_Save_At: Timestamp | FieldValue
28
+ Last_Write_By: string
29
+ Last_Write_App: string
30
+ Last_Write_Connection_Status: "Online" | "Offline"
31
+ Last_Write_Version: number
32
+ Created_At: Timestamp | FieldValue
33
+ Saved_At: Timestamp | FieldValue
34
+ Created_By: string
35
+ [key: string]: any
36
+ }
37
+ /* eslint-enable @typescript-eslint/no-explicit-any */
38
+
39
+ export interface CollectionPermissions {
40
+ auth?: boolean
41
+ operations: ("Read" | "Create" | "Update" | "Delete")[]
42
+ recordOwner?: {
43
+ active: boolean
44
+ }
45
+ recordUser?: {
46
+ active: boolean
47
+ }
48
+ recordProperty?: {
49
+ active: boolean
50
+ }
51
+ restrictEntities?: boolean
52
+ individualEntities?: string[]
53
+ parentEntities?: string[]
54
+ parentPropertyEntities?: Record<string, string[]>
55
+ }
56
+
57
+ export interface StokerPermissions {
58
+ User_ID?: string
59
+ Doc_ID?: string
60
+ Collection?: StokerCollection
61
+ Role?: StokerRole
62
+ Enabled?: boolean
63
+ collections?: {
64
+ [collection: string]: CollectionPermissions
65
+ }
66
+ }
67
+
68
+ export type SystemField =
69
+ | "id"
70
+ | "Collection_Path"
71
+ | "Last_Write_At"
72
+ | "Last_Save_At"
73
+ | "Last_Write_By"
74
+ | "Last_Write_App"
75
+ | "Last_Write_Connection_Status"
76
+ | "Last_Write_Version"
77
+ | "Created_At"
78
+ | "Saved_At"
79
+ | "Created_By"
80
+
81
+ export interface CollectionLabels {
82
+ collection: string
83
+ record: string
84
+ }
85
+
86
+ export type OperationType = "Read" | "Create" | "Update" | "Delete"
87
+ export type OperationTypeLower = "read" | "create" | "update" | "delete"
88
+
89
+ export interface PermissionWriteCollection {
90
+ collection: StokerCollection
91
+ operations: OperationType[]
92
+ attributeRestrictions?: AttributeRestriction["type"][]
93
+ restrictEntities?: boolean
94
+ auth?: boolean
95
+ }
96
+
97
+ export interface PermissionWriteRestriction {
98
+ userRole: StokerRole
99
+ recordRole: StokerRole
100
+ collections: PermissionWriteCollection[]
101
+ }
102
+
103
+ export interface AttributeRestrictionRole {
104
+ role: StokerRole
105
+ assignable?: boolean
106
+ values?: string[]
107
+ }
108
+ export interface EntityRestrictionRole {
109
+ role: StokerRole
110
+ }
111
+
112
+ export type AccessRole = AttributeRestrictionRole | EntityRestrictionRole
113
+
114
+ export interface IndividualEntityRestriction {
115
+ type: "Individual"
116
+ roles: EntityRestrictionRole[]
117
+ singleQuery?: number
118
+ }
119
+ export interface ParentEntityRestriction {
120
+ type: "Parent"
121
+ roles: EntityRestrictionRole[]
122
+ collectionField: string
123
+ singleQuery?: number
124
+ }
125
+ export interface ParentPropertyEntityRestriction {
126
+ type: "Parent_Property"
127
+ roles: EntityRestrictionRole[]
128
+ collectionField: string
129
+ propertyField: string
130
+ }
131
+ export type AttributeRestriction = RecordUserRestriction | RecordOwnerRestriction | RecordPropertyRestriction
132
+
133
+ export interface RecordUserRestriction {
134
+ type: "Record_User"
135
+ roles: AttributeRestrictionRole[]
136
+ collectionField: string
137
+ operations?: ("Read" | "Create" | "Update" | "Delete")[]
138
+ }
139
+ export interface RecordOwnerRestriction {
140
+ type: "Record_Owner"
141
+ roles: AttributeRestrictionRole[]
142
+ operations?: ("Read" | "Create" | "Update" | "Delete")[]
143
+ }
144
+ export interface RecordPropertyRestriction {
145
+ type: "Record_Property"
146
+ roles: AttributeRestrictionRole[]
147
+ propertyField: string
148
+ operations?: ("Read" | "Create" | "Update" | "Delete")[]
149
+ }
150
+
151
+ export type EntityRestriction = IndividualEntityRestriction | ParentEntityRestriction | ParentPropertyEntityRestriction
152
+ export type AccessRestriction = AttributeRestriction | EntityRestriction
153
+
154
+ export interface IndividualEntityParentFilter {
155
+ type: "Individual"
156
+ collectionField: string
157
+ roles: EntityRestrictionRole[]
158
+ }
159
+ export interface ParentEntityParentFilter {
160
+ type: "Parent"
161
+ collectionField: string
162
+ parentCollectionField: string
163
+ roles: EntityRestrictionRole[]
164
+ }
165
+ export interface ParentPropertyEntityParentFilter {
166
+ type: "Parent_Property"
167
+ collectionField: string
168
+ parentCollectionField: string
169
+ parentPropertyField: string
170
+ roles: EntityRestrictionRole[]
171
+ }
172
+ export type EntityParentFilter =
173
+ | IndividualEntityParentFilter
174
+ | ParentEntityParentFilter
175
+ | ParentPropertyEntityParentFilter
176
+
177
+ export interface AccessOperations {
178
+ assignable?: boolean | StokerRole[]
179
+ read?: StokerRole[]
180
+ create?: StokerRole[]
181
+ update?: StokerRole[]
182
+ delete?: StokerRole[]
183
+ }
184
+
185
+ export interface AccessFilesAssignmentRoles {
186
+ read?: StokerRole[]
187
+ update?: StokerRole[]
188
+ delete?: StokerRole[]
189
+ }
190
+ export interface AccessFilesAssignment {
191
+ optional?: AccessFilesAssignmentRoles
192
+ required?: AccessFilesAssignmentRoles
193
+ }
194
+ export interface AccessFiles {
195
+ assignment?: {
196
+ [role: StokerRole]: AccessFilesAssignment
197
+ }
198
+ metadata?: {
199
+ [key: string]: string
200
+ }
201
+ customMetadata?: {
202
+ [key: string]: string
203
+ }
204
+ }
205
+
206
+ export interface EntityRestrictions {
207
+ assignable?: StokerRole[]
208
+ restrictions?: EntityRestriction[]
209
+ parentFilters?: EntityParentFilter[]
210
+ }
211
+ export interface CollectionAccess {
212
+ serverReadOnly?: StokerRole[]
213
+ serverWriteOnly?: boolean
214
+ customSecurityRules?: boolean
215
+ customStorageRules?: boolean
216
+ attributeRestrictions?: AttributeRestriction[]
217
+ entityRestrictions?: EntityRestrictions
218
+ permissionWriteRestrictions?: PermissionWriteRestriction[]
219
+ operations: AccessOperations
220
+ auth?: StokerRole[]
221
+ files?: AccessFiles
222
+ }
223
+
224
+ export type PreOperationHookArgs = [
225
+ operation: "read" | "create" | "update" | "delete",
226
+ data?: StokerRecord,
227
+ docId?: string,
228
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
229
+ context?: any,
230
+ batch?: WriteBatch,
231
+ originalRecord?: StokerRecord,
232
+ ]
233
+ export type PreReadHookArgs = [
234
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
235
+ context: any,
236
+ refs: unknown[],
237
+ multiple?: boolean,
238
+ listener?: boolean,
239
+ ]
240
+ export type PostReadHookArgs = [
241
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
242
+ context: any,
243
+ refs: unknown[],
244
+ doc: StokerRecord | undefined,
245
+ listener?: boolean,
246
+ ]
247
+ export type PreDuplicateHookArgs = [data: Partial<StokerRecord>]
248
+ export type PreValidateHookArgs = [
249
+ operation: "create" | "update",
250
+ record: StokerRecord,
251
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
252
+ context: any,
253
+ batch?: WriteBatch,
254
+ originalRecord?: StokerRecord,
255
+ ]
256
+ export type PreWriteHookArgs = [
257
+ operation: "create" | "update" | "delete",
258
+ data: StokerRecord,
259
+ docId: string,
260
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
261
+ context: any,
262
+ batch?: WriteBatch,
263
+ originalRecord?: StokerRecord,
264
+ ]
265
+ export type PostWriteHookArgs = [
266
+ operation: "create" | "update" | "delete",
267
+ data: StokerRecord,
268
+ docId: string,
269
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
270
+ context: any,
271
+ retry?: boolean,
272
+ originalRecord?: StokerRecord,
273
+ ]
274
+ export type PostWriteErrorHookArgs = [
275
+ operation: "create" | "update" | "delete",
276
+ data: StokerRecord,
277
+ docId: string,
278
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
279
+ context: any,
280
+ error: unknown,
281
+ retry?: boolean,
282
+ retries?: number,
283
+ originalRecord?: StokerRecord,
284
+ ]
285
+ export type PostOperationHookArgs = [
286
+ operation: "read" | "create" | "update" | "delete",
287
+ data?: StokerRecord,
288
+ docId?: string,
289
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
290
+ context?: any,
291
+ retry?: boolean,
292
+ originalRecord?: StokerRecord,
293
+ ]
294
+
295
+ export type FilePermissions = {
296
+ read?: string
297
+ update?: string
298
+ delete?: string
299
+ }
300
+
301
+ export type PreFileAddHookArgs = [
302
+ record: StokerRecord,
303
+ fullPath: string,
304
+ filename: string,
305
+ permissions: FilePermissions,
306
+ ]
307
+
308
+ export type PreFileUpdateHookArgs = [
309
+ record: StokerRecord,
310
+ update:
311
+ | { type: "rename"; oldPath: string; newPath: string }
312
+ | {
313
+ type: "permissions"
314
+ path: string
315
+ originalPermissions: FilePermissions
316
+ permissions: FilePermissions
317
+ },
318
+ ]
319
+
320
+ export type PostFileAddHookArgs = [
321
+ record: StokerRecord,
322
+ fullPath: string,
323
+ filename: string,
324
+ permissions: FilePermissions,
325
+ ]
326
+
327
+ export type PostFileUpdateHookArgs = [
328
+ record: StokerRecord,
329
+ update:
330
+ | { type: "rename"; oldPath: string; newPath: string }
331
+ | {
332
+ type: "permissions"
333
+ path: string
334
+ originalPermissions: FilePermissions
335
+ permissions: FilePermissions
336
+ },
337
+ ]
338
+
339
+ export type HookArgs =
340
+ | PreOperationHookArgs
341
+ | PreReadHookArgs
342
+ | PostReadHookArgs
343
+ | PreDuplicateHookArgs
344
+ | PreValidateHookArgs
345
+ | PreWriteHookArgs
346
+ | PostWriteHookArgs
347
+ | PostWriteErrorHookArgs
348
+ | PostOperationHookArgs
349
+ | PreFileAddHookArgs
350
+ | PreFileUpdateHookArgs
351
+ | PostFileAddHookArgs
352
+ | PostFileUpdateHookArgs
353
+
354
+ export type PreOperationHook = (...args: PreOperationHookArgs) => boolean | void | Promise<boolean | void>
355
+ export type PreReadHook = (...args: PreReadHookArgs) => void | Promise<void>
356
+ export type PostReadHook = (...args: PostReadHookArgs) => void | Promise<void>
357
+ export type PreDuplicateHook = (...args: PreDuplicateHookArgs) => boolean | void | Promise<boolean | void>
358
+ export type PreValidateHook = (
359
+ ...args: PreValidateHookArgs
360
+ ) => { valid: boolean; message?: string } | Promise<{ valid: boolean; message?: string }>
361
+ export type PreWriteHook = (...args: PreWriteHookArgs) => boolean | void | Promise<boolean | void>
362
+ export type PostWriteHook = (...args: PostWriteHookArgs) => boolean | void | Promise<boolean | void>
363
+ export type PostWriteErrorHook = (...args: PostWriteErrorHookArgs) => boolean | void | Promise<boolean | void>
364
+ export type PostOperationHook = (...args: PostOperationHookArgs) => boolean | void | Promise<boolean | void>
365
+
366
+ export type PreFileAddHook = (...args: PreFileAddHookArgs) => boolean | void | Promise<boolean | void>
367
+ export type PreFileUpdateHook = (...args: PreFileUpdateHookArgs) => boolean | void | Promise<boolean | void>
368
+ export type PostFileAddHook = (...args: PostFileAddHookArgs) => boolean | void | Promise<boolean | void>
369
+ export type PostFileUpdateHook = (...args: PostFileUpdateHookArgs) => boolean | void | Promise<boolean | void>
370
+
371
+ export type Hook =
372
+ | PreOperationHook
373
+ | PreReadHook
374
+ | PostReadHook
375
+ | PreDuplicateHook
376
+ | PreValidateHook
377
+ | PreWriteHook
378
+ | PostWriteHook
379
+ | PostWriteErrorHook
380
+ | PostOperationHook
381
+ | PreFileAddHook
382
+ | PreFileUpdateHook
383
+ | PostFileAddHook
384
+ | PostFileUpdateHook
385
+
386
+ export type Hooks = {
387
+ preOperation?: PreOperationHook
388
+ preRead?: PreReadHook
389
+ postRead?: PostReadHook
390
+ preDuplicate?: PreDuplicateHook
391
+ preValidate?: PreValidateHook
392
+ preWrite?: PreWriteHook
393
+ postWrite?: PostWriteHook
394
+ postWriteError?: PostWriteErrorHook
395
+ postOperation?: PostOperationHook
396
+ preFileAdd?: PreFileAddHook
397
+ preFileUpdate?: PreFileUpdateHook
398
+ postFileAdd?: PostFileAddHook
399
+ postFileUpdate?: PostFileUpdateHook
400
+ }
401
+
402
+ export interface PreloadCacheRange {
403
+ fields: string[]
404
+ ranges?: [string, string][]
405
+ labels?: string[]
406
+ start: "Today" | "Week" | "Month" | "Year" | Date | number
407
+ startOffsetDays?: number
408
+ startOffsetHours?: number
409
+ end?: Date | number
410
+ endOffsetDays?: number
411
+ endOffsetHours?: number
412
+ selector?: "range" | "week" | "month" | ("range" | "week" | "month")[]
413
+ }
414
+
415
+ export interface PreloadCache {
416
+ roles: StokerRole[]
417
+ relationCollections?: boolean | (() => boolean | Promise<boolean>)
418
+ range?: PreloadCacheRange
419
+ constraints?:
420
+ | [string, WhereFilterOp, unknown][]
421
+ | (() => [string, WhereFilterOp, unknown][] | Promise<[string, WhereFilterOp, unknown][]>)
422
+ }
423
+
424
+ export interface PreloadCacheInitial {
425
+ [collection: string]: {
426
+ roles: StokerRole[]
427
+ range?: PreloadCacheRange
428
+ constraints?: [string, WhereFilterOp, unknown][]
429
+ orQueries?: [string, WhereFilterOp, unknown][]
430
+ }
431
+ }
432
+
433
+ export interface CollectionCustom extends Hooks {
434
+ serverAccess?: {
435
+ read?: (role: StokerRole, record?: StokerRecord) => boolean | Promise<boolean>
436
+ create?: (role: StokerRole, record: StokerRecord) => boolean | Promise<boolean>
437
+ update?: (role: StokerRole, record: StokerRecord, originalRecord?: StokerRecord) => boolean | Promise<boolean>
438
+ delete?: (role: StokerRole, record: StokerRecord) => boolean | Promise<boolean>
439
+ }
440
+ preloadCacheConstraints?:
441
+ | [string, WhereFilterOp, unknown][]
442
+ | (() => [string, WhereFilterOp, unknown][] | Promise<[string, WhereFilterOp, unknown][]>)
443
+ preloadCacheOrQueries?:
444
+ | [string, WhereFilterOp, unknown][]
445
+ | (() => [string, WhereFilterOp, unknown][] | Promise<[string, WhereFilterOp, unknown][]>)
446
+ autoCorrectUnique?: boolean | (() => boolean | Promise<boolean>)
447
+ disableOfflineCreate?: boolean | (() => boolean | Promise<boolean>)
448
+ disableOfflineUpdate?: boolean | (() => boolean | Promise<boolean>)
449
+ disableOfflineDelete?: boolean | (() => boolean | Promise<boolean>)
450
+ }
451
+ export interface CollectionCustomCache {
452
+ preloadCacheConstraints?: [string, WhereFilterOp, unknown][]
453
+ preloadCacheOrQueries?: [string, WhereFilterOp, unknown][]
454
+ autoCorrectUnique?: boolean
455
+ disableOfflineCreate?: boolean
456
+ disableOfflineUpdate?: boolean
457
+ disableOfflineDelete?: boolean
458
+ }
459
+
460
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
461
+ export interface ListConfig {
462
+ title?: string
463
+ }
464
+
465
+ export interface CardsConfig {
466
+ roles?: StokerRole[]
467
+ statusField?: string
468
+ excludeValues?: string[] | number[]
469
+ headerField: string
470
+ maxHeaderLines?: 1 | 2
471
+ sections: {
472
+ title?: string
473
+ fields: string[]
474
+ blocks?: boolean
475
+ large?: boolean
476
+ maxSectionLines?: 1 | 2 | 3 | 4
477
+ collapse?: "sm" | "md" | "lg" | "xl" | "2xl" | ((record?: StokerRecord) => "sm" | "md" | "lg" | "xl" | "2xl")
478
+ }[]
479
+ footerField?: string
480
+ maxFooterLines?: 1 | 2
481
+ title?: string
482
+ cardClass?: string
483
+ }
484
+
485
+ export interface ImagesConfig {
486
+ roles?: StokerRole[]
487
+ imageField: string
488
+ size: "sm" | "md" | "lg"
489
+ maxHeaderLines?: 1 | 2
490
+ title?: string
491
+ }
492
+
493
+ export interface MapConfig {
494
+ roles?: StokerRole[]
495
+ coordinatesField?: string
496
+ addressField?: string
497
+ center: {
498
+ lat: number
499
+ lng: number
500
+ }
501
+ zoom: number
502
+ noLocation?: {
503
+ title: string
504
+ }
505
+ title?: string
506
+ }
507
+
508
+ export interface CalendarConfig {
509
+ roles?: StokerRole[]
510
+ startField: string
511
+ endField?: string
512
+ allDayField?: string
513
+ fullCalendarLarge?: CalendarOptions
514
+ fullCalendarSmall?: CalendarOptions
515
+ resourceField?: string
516
+ resourceTitleField?: string
517
+ unscheduled?: {
518
+ title: string
519
+ roles?: StokerRole[]
520
+ }
521
+ title?: string
522
+ dataStart?: { days: number } | { weeks: number } | { months: number } | { years: number }
523
+ dataEnd?: { days: number } | { weeks: number } | { months: number } | { years: number }
524
+ dataStartOffset?: { days: number } | { weeks: number } | { months: number } | { years: number }
525
+ dataEndOffset?: { days: number } | { weeks: number } | { months: number } | { years: number }
526
+ color?: string | ((record: StokerRecord) => string)
527
+ }
528
+
529
+ export type StatusFilter = {
530
+ type: "status"
531
+ value?: string | number
532
+ roles?: StokerRole[]
533
+ }
534
+
535
+ export type RangeFilter = {
536
+ type: "range"
537
+ field: string
538
+ selector?:
539
+ | "range"
540
+ | "week"
541
+ | "month"
542
+ | ("range" | "week" | "month")[]
543
+ | (() => "range" | "week" | "month" | ("range" | "week" | "month")[])
544
+ value?: string
545
+ startOffsetDays?: number
546
+ startOffsetHours?: number
547
+ endOffsetDays?: number
548
+ endOffsetHours?: number
549
+ }
550
+
551
+ export type SelectFilter = {
552
+ type: "select"
553
+ field: string
554
+ title?: string | (() => string)
555
+ roles?: StokerRole[]
556
+ condition?: (value: boolean | string | number | undefined) => boolean
557
+ value?: string | number
558
+ style?: "select" | "radio" | "buttons"
559
+ }
560
+
561
+ export type RelationFilter = {
562
+ type: "relation"
563
+ field: string
564
+ title?: string | (() => string)
565
+ roles?: StokerRole[]
566
+ constraints?: [string, "==" | "in", unknown][]
567
+ value?: string
568
+ }
569
+
570
+ export type Filter = StatusFilter | RangeFilter | SelectFilter | RelationFilter
571
+
572
+ export interface Metric {
573
+ type: "sum" | "average" | "count"
574
+ field?: string
575
+ roles?: StokerRole[]
576
+ title?: string
577
+ decimal?: number
578
+ prefix?: string
579
+ suffix?: string
580
+ textSize?: "text-xl" | "text-2xl" | "text-3xl"
581
+ }
582
+ export interface Chart {
583
+ type: "area"
584
+ dateField: string
585
+ metricField1?: string
586
+ metricField2?: string
587
+ defaultRange: "90d" | "30d" | "7d"
588
+ roles?: StokerRole[]
589
+ title?: string
590
+ }
591
+ export interface CollectionMeta {
592
+ title?: string
593
+ description?: string
594
+ }
595
+ export interface RowHighlight {
596
+ condition: (record: StokerRecord) => boolean
597
+ className: string
598
+ roles?: StokerRole[]
599
+ }
600
+ export interface Convert {
601
+ collection: string
602
+ convert: (record: StokerRecord) => Partial<StokerRecord> | Promise<Partial<StokerRecord>>
603
+ roles?: StokerRole[]
604
+ }
605
+ export interface CustomField {
606
+ position?: number | ((record?: StokerRecord) => number)
607
+ component?: React.FC
608
+ props?: Record<string, unknown>
609
+ condition?: (operation: "create" | "update" | "update-many", record?: StokerRecord) => boolean
610
+ }
611
+ export interface FormList {
612
+ collection: StokerCollection
613
+ fields: string[]
614
+ sortField?: string
615
+ sortDirection?: "asc" | "desc"
616
+ label?: string
617
+ }
618
+
619
+ export interface FormButton {
620
+ title: string
621
+ icon?: React.FC<{ className?: string }>
622
+ variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link"
623
+ action: (
624
+ operation: "create" | "update" | "update-many",
625
+ formValues: StokerRecord,
626
+ originalRecord?: StokerRecord,
627
+ ) => void | Promise<void>
628
+ condition?: boolean | ((operation: "create" | "update" | "update-many", record?: StokerRecord) => boolean)
629
+ setIsLoading?: (isLoading: boolean) => void
630
+ }
631
+
632
+ export interface CustomRecordPage {
633
+ title: string
634
+ url: string
635
+ component: React.FC<{
636
+ record: StokerRecord | undefined
637
+ collection: CollectionSchema
638
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
639
+ components: any
640
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
641
+ hooks: any
642
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
643
+ utils: any
644
+ }>
645
+ condition?: (record: StokerRecord | undefined) => boolean
646
+ icon?: React.FC<{ className?: string }>
647
+ }
648
+ export interface CollectionAdmin {
649
+ hidden?: boolean | (() => boolean | Promise<boolean>)
650
+ navbarPosition?: number | (() => number)
651
+ titles?:
652
+ | {
653
+ collection: string
654
+ record: string
655
+ }
656
+ | (() => { collection: string; record: string } | Promise<{ collection: string; record: string }>)
657
+ icon?: React.FC | (() => React.FC | Promise<React.FC>)
658
+ duplicate?: boolean | (() => boolean | Promise<boolean>)
659
+ convert?: Convert[] | (() => Convert[] | Promise<Convert[]>)
660
+ live?: boolean | (() => boolean | Promise<boolean>)
661
+ statusField?: {
662
+ field: string
663
+ active?: unknown[]
664
+ archived?: unknown[]
665
+ }
666
+ defaultRoute?: string | (() => string)
667
+ defaultSort?:
668
+ | {
669
+ field: string
670
+ direction?: "asc" | "desc"
671
+ }
672
+ | (() =>
673
+ | {
674
+ field: string
675
+ direction?: "asc" | "desc"
676
+ }
677
+ | Promise<{
678
+ field: string
679
+ direction?: "asc" | "desc"
680
+ }>)
681
+ itemsPerPage?: number | (() => number | Promise<number>)
682
+ list?: ListConfig | (() => ListConfig | Promise<ListConfig>)
683
+ cards?: CardsConfig | (() => CardsConfig | Promise<CardsConfig>)
684
+ images?: ImagesConfig | (() => ImagesConfig | Promise<ImagesConfig>)
685
+ map?: MapConfig | (() => MapConfig | Promise<MapConfig>)
686
+ calendar?: CalendarConfig | (() => CalendarConfig | Promise<CalendarConfig>)
687
+ filters?: Filter[]
688
+ rangeSelectorValues?:
689
+ | "range"
690
+ | "week"
691
+ | "month"
692
+ | ("range" | "week" | "month")[]
693
+ | (() => "range" | "week" | "month" | ("range" | "week" | "month")[])
694
+ defaultRangeSelector?: "range" | "week" | "month" | (() => "range" | "week" | "month")
695
+ restrictExport?: StokerRole[] | (() => StokerRole[] | Promise<StokerRole[]>)
696
+ metrics?: (Metric | Chart)[] | (() => (Metric | Chart)[] | Promise<(Metric | Chart)[]>)
697
+ meta?: CollectionMeta | (() => CollectionMeta | Promise<CollectionMeta>)
698
+ rowHighlight?: RowHighlight[] | (() => RowHighlight[])
699
+ breadcrumbs?: string[] | (() => string[] | Promise<string[]>)
700
+ customFields?: CustomField[] | (() => CustomField[] | Promise<CustomField[]>)
701
+ customRecordPages?: CustomRecordPage[] | (() => CustomRecordPage[] | Promise<CustomRecordPage[]>)
702
+ formButtons?: FormButton[] | (() => FormButton[] | Promise<FormButton[]>)
703
+ formUpload?: boolean | (() => boolean | Promise<boolean>)
704
+ formImages?: boolean | (() => boolean | Promise<boolean>)
705
+ formLists?: FormList[] | (() => FormList[] | Promise<FormList[]>)
706
+ hideCreate?: boolean | ((relationList?: StokerCollection) => boolean | Promise<boolean>)
707
+ disableUpdate?: boolean | ((operation: "create" | "update", record: StokerRecord) => boolean | Promise<boolean>)
708
+ onFormOpen?: (operation: "create" | "update", record: StokerRecord) => void | Promise<void>
709
+ onChange?: (
710
+ operation: "create" | "update",
711
+ record: StokerRecord,
712
+ originalRecord: StokerRecord,
713
+ ) => Partial<StokerRecord> | void | Promise<Partial<StokerRecord> | void>
714
+ addRecordButtonOverride?: (record?: StokerRecord) => void | Promise<void>
715
+ disableRangeSelector?: boolean | (() => boolean)
716
+ }
717
+ export interface CollectionAdminCache {
718
+ navbarPosition?: number
719
+ titles?: {
720
+ collection: string
721
+ record: string
722
+ }
723
+ icon?: React.FC
724
+ duplicate?: boolean
725
+ live?: boolean
726
+ statusField?: {
727
+ field: string
728
+ active?: unknown[]
729
+ archived?: unknown[]
730
+ }
731
+ defaultSort?: {
732
+ field: string
733
+ direction?: "asc" | "desc"
734
+ }
735
+ itemsPerPage?: number
736
+ list?: ListConfig
737
+ cards?: CardsConfig
738
+ images?: ImagesConfig
739
+ map?: MapConfig
740
+ calendar?: CalendarConfig
741
+ filters?: Filter[]
742
+ restrictExport?: StokerRole[]
743
+ metrics?: (Metric | Chart)[]
744
+ meta?: CollectionMeta
745
+ rowHighlight?: RowHighlight[]
746
+ breadcrumbs?: string[]
747
+ customFields?: CustomField[]
748
+ customRecordPages?: CustomRecordPage[]
749
+ formButtons?: FormButton[]
750
+ formUpload?: boolean
751
+ formImages?: boolean
752
+ hideCreate?: boolean
753
+ }
754
+
755
+ export interface FieldCustom extends Hooks {
756
+ initialValue?: unknown | ((record?: StokerRecord) => unknown | Promise<unknown>)
757
+ serverAccess?: {
758
+ read?: (role: StokerRole, record?: StokerRecord) => boolean | Promise<boolean>
759
+ create?: (role: StokerRole, record: StokerRecord) => boolean | Promise<boolean>
760
+ update?: (role: StokerRole, record: StokerRecord, originalRecord?: StokerRecord) => boolean | Promise<boolean>
761
+ }
762
+ }
763
+
764
+ export interface FieldDescription {
765
+ message: string | ((record?: StokerRecord) => string | Promise<string>)
766
+ condition?: boolean | ((record?: StokerRecord) => boolean | Promise<boolean>)
767
+ }
768
+
769
+ export interface LocationFieldAdmin {
770
+ center: {
771
+ lat: number
772
+ lng: number
773
+ }
774
+ zoom: number
775
+ }
776
+
777
+ export interface FormFieldIcon {
778
+ component: React.FC
779
+ className?: string
780
+ }
781
+
782
+ export interface FieldAdmin {
783
+ label?: string | (() => string)
784
+ listLabel?: string | (() => string)
785
+ icon?: FormFieldIcon | (() => FormFieldIcon | Promise<FormFieldIcon>)
786
+ condition?: {
787
+ list?: boolean | ((parentCollection?: CollectionSchema, parentRecord?: StokerRecord) => boolean)
788
+ form?: boolean | ((operation?: "create" | "update", record?: StokerRecord) => boolean)
789
+ }
790
+ readOnly?: boolean | ((operation?: "create" | "update", record?: StokerRecord) => boolean | Promise<boolean>)
791
+ description?: FieldDescription
792
+ textarea?: boolean | (() => boolean | Promise<boolean>)
793
+ radio?: boolean | (() => boolean | Promise<boolean>)
794
+ switch?: boolean | (() => boolean | Promise<boolean>)
795
+ time?: boolean | (() => boolean | Promise<boolean>)
796
+ slider?: boolean | (() => boolean | Promise<boolean>)
797
+ richText?: boolean | (() => boolean | Promise<boolean>)
798
+ location?: LocationFieldAdmin | (() => LocationFieldAdmin | Promise<LocationFieldAdmin>)
799
+ image?: boolean | (() => boolean)
800
+ tags?: string[] | (() => string[])
801
+ live?: boolean | (() => boolean | Promise<boolean>)
802
+ column?: boolean | number | (() => boolean | number)
803
+ badge?: boolean | string | ((record?: StokerRecord) => boolean | string)
804
+ hidden?: "sm" | "md" | "lg" | "xl" | "2xl" | ((record?: StokerRecord) => "sm" | "md" | "lg" | "xl" | "2xl")
805
+ italic?: boolean | ((record?: StokerRecord) => boolean)
806
+ currency?: string | ((record?: StokerRecord) => string)
807
+ sort?: (record?: StokerRecord) => unknown
808
+ noExport?: boolean | (() => boolean)
809
+ exportSeparator?: string | (() => string)
810
+ skipFormRequiredValidation?: boolean | (() => boolean)
811
+ overrideFormRequiredValidation?: (operation: "create" | "update", record?: StokerRecord) => boolean
812
+ filterValues?: (value: string | number, parentCollection: CollectionSchema, parentRecord?: StokerRecord) => boolean
813
+ filterResults?: (result: SearchResult, parentCollection: CollectionSchema, parentRecord?: StokerRecord) => boolean
814
+ modifyResultTitle?: (
815
+ record: StokerRecord,
816
+ parentCollection: CollectionSchema,
817
+ parentRecord?: StokerRecord,
818
+ ) => string
819
+ modifyDisplayValue?: (record?: StokerRecord, context?: "card" | "form" | "list") => unknown
820
+ customListView?: (
821
+ record?: StokerRecord,
822
+ parentCollection?: CollectionSchema,
823
+ parentRecord?: StokerRecord,
824
+ ) =>
825
+ | {
826
+ component: React.FC
827
+ props?: Record<string, unknown>
828
+ receiveClick?: boolean
829
+ }
830
+ | undefined
831
+ }
832
+
833
+ export interface DependencyField {
834
+ field: string
835
+ roles: StokerRole[]
836
+ }
837
+ export interface EnforceHierarchy {
838
+ field: string
839
+ recordLinkField: string
840
+ }
841
+ export interface SingleFieldExemption {
842
+ queryScope: "COLLECTION" | "COLLECTION_GROUP"
843
+ order?: "ASCENDING" | "DESCENDING"
844
+ arrayConfig?: "CONTAINS" | "CONTAINS_ANY"
845
+ }
846
+
847
+ export interface StandardField {
848
+ name: string
849
+ description?: string | (() => string | Promise<string>)
850
+
851
+ singleFieldExemption?: SingleFieldExemption[] | boolean
852
+ sorting?:
853
+ | boolean
854
+ | {
855
+ direction?: "asc" | "desc"
856
+ roles?: StokerRole[]
857
+ }
858
+
859
+ required?: boolean
860
+ nullable?: boolean
861
+
862
+ access?: StokerRole[]
863
+ restrictCreate?: StokerRole[] | boolean
864
+ restrictUpdate?: StokerRole[] | boolean
865
+ skipRulesValidation?: boolean
866
+
867
+ custom?: FieldCustom
868
+ admin?: FieldAdmin
869
+ }
870
+ export interface BooleanField extends StandardField {
871
+ type: "Boolean"
872
+ }
873
+ export interface StringField extends StandardField {
874
+ type: "String"
875
+ values?: string[]
876
+ unique?: boolean
877
+
878
+ length?: number
879
+ minlength?: number
880
+ maxlength?: number
881
+ pattern?: string
882
+
883
+ email?: boolean
884
+ url?: boolean
885
+ emoji?: boolean
886
+ uuid?: boolean
887
+ ip?: boolean
888
+ }
889
+ export interface NumberField extends StandardField {
890
+ type: "Number"
891
+ values?: number[]
892
+ unique?: boolean
893
+
894
+ autoIncrement?: boolean
895
+ decimal?: number
896
+
897
+ max?: number
898
+ min?: number
899
+ }
900
+ export interface TimestampField extends StandardField {
901
+ type: "Timestamp"
902
+ values?: number[]
903
+
904
+ max?: number
905
+ min?: number
906
+ }
907
+ export interface ArrayField extends StandardField {
908
+ type: "Array"
909
+ values?: string[]
910
+
911
+ length?: number
912
+ minlength?: number
913
+ maxlength?: number
914
+ }
915
+ export interface MapField extends StandardField {
916
+ type: "Map"
917
+ }
918
+ export interface RelationField extends StandardField {
919
+ type: "OneToOne" | "OneToMany" | "ManyToOne" | "ManyToMany"
920
+ collection: StokerCollection
921
+ twoWay?: string
922
+ includeFields?: string[]
923
+ titleField?: string
924
+ preserve?: boolean
925
+ writeAny?: boolean
926
+ dependencyFields?: DependencyField[]
927
+ enforceHierarchy?: EnforceHierarchy
928
+ min?: number
929
+ max?: number
930
+ length?: number
931
+ constraints?: [string, "==" | "in", unknown][]
932
+ }
933
+ export interface EmbeddingField extends StandardField {
934
+ type: "Embedding"
935
+ }
936
+ export interface ComputedField extends StandardField {
937
+ type: "Computed"
938
+ formula: (record: StokerRecord) => string | number | Promise<string | number>
939
+ }
940
+ export type CollectionField =
941
+ | BooleanField
942
+ | StringField
943
+ | NumberField
944
+ | TimestampField
945
+ | ArrayField
946
+ | MapField
947
+ | RelationField
948
+ | EmbeddingField
949
+ | ComputedField
950
+
951
+ export interface RoleSystemField {
952
+ field: string
953
+ roles?: StokerRole[]
954
+ }
955
+
956
+ export interface CollectionCustomization {
957
+ custom?: CollectionCustom
958
+ admin?: CollectionAdmin
959
+ fields: {
960
+ name: string
961
+ custom?: FieldCustom
962
+ admin?: FieldAdmin
963
+ formula?: (record: StokerRecord) => string | number
964
+ }[]
965
+ }
966
+
967
+ export interface Query {
968
+ field: string
969
+ range?: boolean
970
+ standalone?: boolean
971
+ roles?: StokerRole[]
972
+ }
973
+
974
+ export interface RelationList {
975
+ collection: StokerCollection
976
+ field: string
977
+ roles?: StokerRole[]
978
+ }
979
+
980
+ export interface CollectionSchema {
981
+ labels: CollectionLabels
982
+ access: CollectionAccess
983
+ fields: (CollectionField | RelationField)[]
984
+ recordTitleField: string
985
+
986
+ auth?: boolean
987
+ singleton?: boolean
988
+ parentCollection?: StokerCollection
989
+
990
+ preloadCache?: PreloadCache
991
+ softDelete?: {
992
+ archivedField: string
993
+ timestampField: string
994
+ retentionPeriod: number
995
+ }
996
+
997
+ queries?: Query[]
998
+ relationLists?: RelationList[]
999
+ allowSchemalessFields?: boolean
1000
+ enableWriteLog?: boolean
1001
+ fullTextSearch?: string[]
1002
+ searchOptions?: Record<string, unknown>
1003
+ ttl?: string
1004
+ indexExemption?: boolean
1005
+ roleSystemFields?: RoleSystemField[]
1006
+ skipRulesValidation?: boolean
1007
+ ai?: {
1008
+ embedding?: {
1009
+ inputField: string
1010
+ outputField: string
1011
+ defaultQueryLimit?: number
1012
+ }
1013
+ chat?: {
1014
+ name: string
1015
+ roles: StokerRole[]
1016
+ }
1017
+ }
1018
+ seedOrder?: number
1019
+
1020
+ custom?: CollectionCustom
1021
+ admin?: CollectionAdmin
1022
+ }
1023
+
1024
+ export interface CollectionsConfig {
1025
+ roles: StokerRole[]
1026
+ permissionsIndexExemption: boolean
1027
+ writeLogIndexExemption?: string[]
1028
+ writeLogTTL?: number
1029
+ }
1030
+
1031
+ export interface CollectionsSchema {
1032
+ collections: {
1033
+ [key: string]: CollectionSchema
1034
+ }
1035
+ config: CollectionsConfig
1036
+ published_time: number | object
1037
+ version: number
1038
+ }
1039
+
1040
+ export type GenerateSchema = (
1041
+ sdk: "web" | "node",
1042
+ config?: WebUtilities | NodeUtilities,
1043
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1044
+ context?: any,
1045
+ ) => CollectionSchema
1046
+
1047
+ export interface RoleGroup {
1048
+ key: string
1049
+ roles: StokerRole[]
1050
+ fields: CollectionField[]
1051
+ }
1052
+
1053
+ export interface WriteLogEntry {
1054
+ operation: "create" | "update" | "delete"
1055
+ collection: string
1056
+ docId: string
1057
+ user: string
1058
+ status: "started" | "written" | "success" | "failed" | "verified"
1059
+ Collection_Path: string[]
1060
+ Last_Write_At: Timestamp | FieldValue
1061
+ Last_Save_At?: Timestamp | FieldValue
1062
+ Last_Write_By: string
1063
+ Last_Write_Connection_Status: "Online" | "Offline"
1064
+ Last_Write_App: string
1065
+ Last_Write_Version: number
1066
+ TTL?: Timestamp | FieldValue
1067
+ data: {
1068
+ data?: Partial<StokerRecord>
1069
+ originalRecord?: StokerRecord
1070
+ finalRecord?: StokerRecord
1071
+ finalOriginal?: StokerRecord
1072
+ error?: unknown
1073
+ }
1074
+ }