@stndrds/schema 0.1.0-alpha.14

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.
Files changed (128) hide show
  1. package/dist/chunk-3ABIOLKO.mjs +4624 -0
  2. package/dist/chunk-3IRX2BDY.mjs +3970 -0
  3. package/dist/chunk-4OTLPWSP.mjs +4448 -0
  4. package/dist/chunk-54ODQBUN.mjs +3867 -0
  5. package/dist/chunk-6HIA3FR2.mjs +4230 -0
  6. package/dist/chunk-6P3XHNLD.mjs +4171 -0
  7. package/dist/chunk-7LJECNAS.mjs +4167 -0
  8. package/dist/chunk-A2WNLUKV.mjs +4475 -0
  9. package/dist/chunk-AA3234RM.mjs +4475 -0
  10. package/dist/chunk-ADNXDLLD.mjs +3136 -0
  11. package/dist/chunk-B4DCDQUI.mjs +4695 -0
  12. package/dist/chunk-B4PSXY6I.mjs +4527 -0
  13. package/dist/chunk-BJHJBZCM.mjs +4228 -0
  14. package/dist/chunk-C3ZWTO6G.mjs +4474 -0
  15. package/dist/chunk-CLOGNKDD.mjs +4040 -0
  16. package/dist/chunk-EW4V63PA.mjs +3053 -0
  17. package/dist/chunk-FR2LCO6R.mjs +2485 -0
  18. package/dist/chunk-GJSF2RKL.mjs +2786 -0
  19. package/dist/chunk-GO5NPP2X.mjs +4726 -0
  20. package/dist/chunk-H3ZYJUDS.mjs +3050 -0
  21. package/dist/chunk-IDDLSFSK.mjs +4230 -0
  22. package/dist/chunk-JRADUJQ7.mjs +4726 -0
  23. package/dist/chunk-NEDR6N7R.mjs +3118 -0
  24. package/dist/chunk-NESPRMDF.mjs +2482 -0
  25. package/dist/chunk-NWFGRJBW.mjs +4612 -0
  26. package/dist/chunk-NXJ57GSN.mjs +2918 -0
  27. package/dist/chunk-O4C5FCTS.mjs +3961 -0
  28. package/dist/chunk-O4PRB27Q.mjs +2513 -0
  29. package/dist/chunk-OJDFNUCR.mjs +4463 -0
  30. package/dist/chunk-OSEKVBHC.mjs +4627 -0
  31. package/dist/chunk-QX4U6U6K.mjs +2484 -0
  32. package/dist/chunk-RMDQ6LKV.mjs +3046 -0
  33. package/dist/chunk-SBXKDATH.mjs +2673 -0
  34. package/dist/chunk-SKMP3AP3.mjs +2918 -0
  35. package/dist/chunk-STMS7WZD.mjs +2623 -0
  36. package/dist/chunk-T3T6PTFG.mjs +3057 -0
  37. package/dist/chunk-TPW72RAH.mjs +4624 -0
  38. package/dist/chunk-TUQEGNGV.mjs +2534 -0
  39. package/dist/chunk-TVKFS3YN.mjs +2449 -0
  40. package/dist/chunk-TZTH3BHG.mjs +3110 -0
  41. package/dist/chunk-W6MU3XPG.mjs +4612 -0
  42. package/dist/chunk-WL7Z3YFR.mjs +4603 -0
  43. package/dist/chunk-XNVVYHH3.mjs +4602 -0
  44. package/dist/chunk-XTA3WY64.mjs +2918 -0
  45. package/dist/chunk-YV7DEZFZ.mjs +2528 -0
  46. package/dist/chunk-ZLJPJND6.mjs +4474 -0
  47. package/dist/chunk-ZNZXTCEX.mjs +4234 -0
  48. package/dist/index.d.mts +1222 -0
  49. package/dist/index.d.ts +1222 -0
  50. package/dist/index.js +5320 -0
  51. package/dist/index.mjs +635 -0
  52. package/dist/runtime-2iKarXtl.d.mts +1924 -0
  53. package/dist/runtime-2iKarXtl.d.ts +1924 -0
  54. package/dist/runtime-4l2ddHZ7.d.mts +2242 -0
  55. package/dist/runtime-4l2ddHZ7.d.ts +2243 -0
  56. package/dist/runtime-8hKS6zAv.d.mts +2226 -0
  57. package/dist/runtime-8hKS6zAv.d.ts +2226 -0
  58. package/dist/runtime-B6yjtoR3.d.mts +4142 -0
  59. package/dist/runtime-B6yjtoR3.d.ts +4142 -0
  60. package/dist/runtime-BGCShrZB.d.mts +2001 -0
  61. package/dist/runtime-BGCShrZB.d.ts +2001 -0
  62. package/dist/runtime-BRW4NGAk.d.mts +1668 -0
  63. package/dist/runtime-BRW4NGAk.d.ts +1668 -0
  64. package/dist/runtime-BnfBr314.d.mts +1683 -0
  65. package/dist/runtime-BnfBr314.d.ts +1683 -0
  66. package/dist/runtime-BrqhiJUF.d.mts +4151 -0
  67. package/dist/runtime-BrqhiJUF.d.ts +4151 -0
  68. package/dist/runtime-Bvj8c-BE.d.mts +4277 -0
  69. package/dist/runtime-Bvj8c-BE.d.ts +4277 -0
  70. package/dist/runtime-C03qT4qU.d.mts +4267 -0
  71. package/dist/runtime-C03qT4qU.d.ts +4267 -0
  72. package/dist/runtime-CaCZ7mSf.d.mts +2974 -0
  73. package/dist/runtime-CaCZ7mSf.d.ts +2974 -0
  74. package/dist/runtime-CaIzNX0Z.d.mts +4091 -0
  75. package/dist/runtime-CaIzNX0Z.d.ts +4091 -0
  76. package/dist/runtime-ChPTgmLP.d.mts +4320 -0
  77. package/dist/runtime-ChPTgmLP.d.ts +4320 -0
  78. package/dist/runtime-CnImZ1Vv.d.mts +4267 -0
  79. package/dist/runtime-CnImZ1Vv.d.ts +4267 -0
  80. package/dist/runtime-Cp-B26Nj.d.mts +2890 -0
  81. package/dist/runtime-Cp-B26Nj.d.ts +2890 -0
  82. package/dist/runtime-Cq8jfk3c.d.mts +4277 -0
  83. package/dist/runtime-Cq8jfk3c.d.ts +4277 -0
  84. package/dist/runtime-CqDFXhhP.d.mts +1685 -0
  85. package/dist/runtime-CqDFXhhP.d.ts +1685 -0
  86. package/dist/runtime-CqtpZLdL.d.mts +4280 -0
  87. package/dist/runtime-CqtpZLdL.d.ts +4280 -0
  88. package/dist/runtime-D-4DblaZ.d.mts +4147 -0
  89. package/dist/runtime-D-4DblaZ.d.ts +4147 -0
  90. package/dist/runtime-D59sSqNl.d.mts +4146 -0
  91. package/dist/runtime-D59sSqNl.d.ts +4146 -0
  92. package/dist/runtime-DEfPk3wT.d.mts +1840 -0
  93. package/dist/runtime-DEfPk3wT.d.ts +1840 -0
  94. package/dist/runtime-DGV-7vES.d.mts +1685 -0
  95. package/dist/runtime-DGV-7vES.d.ts +1685 -0
  96. package/dist/runtime-DNacghqc.d.mts +3971 -0
  97. package/dist/runtime-DNacghqc.d.ts +3971 -0
  98. package/dist/runtime-DPLsUHYK.d.mts +3977 -0
  99. package/dist/runtime-DPLsUHYK.d.ts +3977 -0
  100. package/dist/runtime-DTxCw60F.d.mts +2973 -0
  101. package/dist/runtime-DTxCw60F.d.ts +2973 -0
  102. package/dist/runtime-DUXJ-zNS.d.mts +2788 -0
  103. package/dist/runtime-DUXJ-zNS.d.ts +2788 -0
  104. package/dist/runtime-DbljInhV.d.mts +2237 -0
  105. package/dist/runtime-DbljInhV.d.ts +2237 -0
  106. package/dist/runtime-DcH3y6Yu.d.mts +4272 -0
  107. package/dist/runtime-DcH3y6Yu.d.ts +4272 -0
  108. package/dist/runtime-DdBFz85g.d.mts +4229 -0
  109. package/dist/runtime-DdBFz85g.d.ts +4229 -0
  110. package/dist/runtime-DjMWhjkm.d.mts +4321 -0
  111. package/dist/runtime-DjMWhjkm.d.ts +4321 -0
  112. package/dist/runtime-Djz3fOBE.d.mts +2078 -0
  113. package/dist/runtime-Djz3fOBE.d.ts +2078 -0
  114. package/dist/runtime-Dli8g3Aq.d.mts +2082 -0
  115. package/dist/runtime-Dli8g3Aq.d.ts +2082 -0
  116. package/dist/runtime-a8J378im.d.mts +4123 -0
  117. package/dist/runtime-a8J378im.d.ts +4123 -0
  118. package/dist/runtime-dp3rb3Lf.d.mts +2968 -0
  119. package/dist/runtime-dp3rb3Lf.d.ts +2968 -0
  120. package/dist/runtime-iWXlSN_H.d.mts +1683 -0
  121. package/dist/runtime-iWXlSN_H.d.ts +1683 -0
  122. package/dist/runtime-yMql0npY.d.mts +4321 -0
  123. package/dist/runtime-yMql0npY.d.ts +4321 -0
  124. package/dist/runtime.d.mts +3 -0
  125. package/dist/runtime.d.ts +3 -0
  126. package/dist/runtime.js +3626 -0
  127. package/dist/runtime.mjs +48 -0
  128. package/package.json +58 -0
@@ -0,0 +1,4267 @@
1
+ import { ColorId, IconName, CountryIso3, CurrencyCode, MimeType } from '@stndrds/constants';
2
+ import { z } from 'zod';
3
+
4
+ /**
5
+ * UUID string type for all identifiers
6
+ */
7
+ type Uuid = string;
8
+ /**
9
+ * Tenant identifier for multi-tenant isolation
10
+ * Phase 1: Type defined but not yet used in interfaces
11
+ * Phase 2+: Will be added to ObjectRecord and services for SaaS mode
12
+ */
13
+ type TenantId = string;
14
+ /**
15
+ * Generate a unique UUID v4
16
+ * Uses crypto.randomUUID() when available (Node.js 19+, modern browsers)
17
+ * Falls back to a manual implementation for older environments
18
+ *
19
+ * @returns A UUID v4 string
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * const id = generateId();
24
+ * // "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"
25
+ * ```
26
+ */
27
+ declare function generateId(): Uuid;
28
+ /**
29
+ * Generate a prefixed ID for better debugging and readability
30
+ *
31
+ * @param prefix - Prefix for the ID (e.g., "obj", "attr", "rec")
32
+ * @returns A prefixed UUID string
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * const objectId = generatePrefixedId("obj");
37
+ * // "obj_a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"
38
+ *
39
+ * const attrId = generatePrefixedId("attr");
40
+ * // "attr_a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"
41
+ * ```
42
+ */
43
+ declare function generatePrefixedId(prefix: string): Uuid;
44
+
45
+ type AttributeType = "text" | "textarea" | "number" | "checkbox" | "date" | "phone" | "currency" | "status" | "location" | "timestamp" | "select" | "multiselect" | "file" | "user" | "relation" | "rating";
46
+ /**
47
+ * Status group categorization
48
+ */
49
+ type StatusGroup = "idle" | "in_progress" | "finished";
50
+ /**
51
+ * Unified option type for select-like fields
52
+ */
53
+ interface Option {
54
+ id: string;
55
+ label: string;
56
+ value: string;
57
+ color?: ColorId;
58
+ icon?: IconName;
59
+ description?: string;
60
+ group?: StatusGroup;
61
+ }
62
+ /**
63
+ * Attribute grouping for UI organization
64
+ */
65
+ interface AttributeGroup {
66
+ id: string;
67
+ label: string;
68
+ description?: string;
69
+ attributeIds: string[];
70
+ collapsible?: boolean;
71
+ collapsed?: boolean;
72
+ order?: number;
73
+ }
74
+ interface BaseAttribute<DefaultValueType = unknown> {
75
+ id: Uuid;
76
+ name: string;
77
+ label: string;
78
+ type: AttributeType;
79
+ required: boolean;
80
+ disabled?: boolean;
81
+ placeholder?: string;
82
+ description?: string;
83
+ defaultValue?: DefaultValueType;
84
+ icon?: IconName;
85
+ order?: number;
86
+ hidden?: boolean;
87
+ archived?: boolean;
88
+ deprecated?: boolean;
89
+ system?: boolean;
90
+ metadata?: Record<string, unknown>;
91
+ }
92
+ interface TextAttribute extends BaseAttribute<string> {
93
+ type: "text";
94
+ minLength?: number;
95
+ maxLength?: number;
96
+ pattern?: string;
97
+ }
98
+ type NumberUnit = "integer" | "decimal" | "percentage";
99
+ interface NumberAttribute extends BaseAttribute<number> {
100
+ type: "number";
101
+ min?: number;
102
+ max?: number;
103
+ unit?: NumberUnit;
104
+ decimals?: number;
105
+ }
106
+ interface CheckboxAttribute extends BaseAttribute<boolean> {
107
+ type: "checkbox";
108
+ }
109
+ type DateFormat = "short" | "long" | "full" | "relative";
110
+ type DateValue = string | "today";
111
+ interface DateAttribute extends BaseAttribute<string> {
112
+ type: "date";
113
+ dateFormat?: DateFormat;
114
+ minDate?: DateValue;
115
+ maxDate?: DateValue;
116
+ }
117
+ interface Phone {
118
+ countryCode: CountryIso3;
119
+ phoneNumber: string;
120
+ }
121
+ interface PhoneAttribute extends BaseAttribute<Phone> {
122
+ type: "phone";
123
+ defaultCountryCode?: CountryIso3;
124
+ }
125
+ interface Currency {
126
+ code: CurrencyCode;
127
+ value: number;
128
+ }
129
+ interface CurrencyAttribute extends BaseAttribute<Currency> {
130
+ type: "currency";
131
+ defaultCurrency?: CurrencyCode;
132
+ allowedCurrencies?: CurrencyCode[];
133
+ }
134
+ /**
135
+ * StatusAttribute - For workflow states with semantic grouping (idle/in_progress/finished)
136
+ * Use this for: Task status, Order status, Project phases, Process states
137
+ * Use SelectAttribute for: Categories, Types, simple choices without workflow
138
+ */
139
+ interface StatusAttribute extends BaseAttribute<string> {
140
+ type: "status";
141
+ options: Option[];
142
+ }
143
+ interface Location {
144
+ address?: string;
145
+ address2?: string;
146
+ city?: string;
147
+ state?: string;
148
+ postalCode?: string;
149
+ country?: CountryIso3;
150
+ latitude?: number;
151
+ longitude?: number;
152
+ }
153
+ type LocationGranularity = "full" | "address" | "city" | "state" | "country" | "coordinates";
154
+ interface LocationAttribute extends BaseAttribute<Location> {
155
+ type: "location";
156
+ granularity: LocationGranularity;
157
+ enableAutocomplete?: boolean;
158
+ enableMap?: boolean;
159
+ defaultCountry?: CountryIso3;
160
+ allowedCountries?: CountryIso3[];
161
+ displayFormat?: "single_line" | "multi_line" | "compact";
162
+ }
163
+ interface TimestampAttribute extends BaseAttribute<number> {
164
+ type: "timestamp";
165
+ autoUpdate?: boolean;
166
+ }
167
+ /**
168
+ * SelectAttribute - For simple single-choice selection
169
+ * Use this for: Categories, Document types, Departments, Priorities
170
+ * Options can be grouped (e.g., countries by continent) but no workflow logic
171
+ */
172
+ interface SelectAttribute extends BaseAttribute<string> {
173
+ type: "select";
174
+ options: Option[];
175
+ }
176
+ interface MultiselectAttribute extends BaseAttribute<string[]> {
177
+ type: "multiselect";
178
+ options: Option[];
179
+ }
180
+ type DocumentType = "id_card" | "passport" | "incorporation_certificate" | "driver_license" | "birth_certificate" | "residence_permit" | "bank_statement" | "proof_of_address" | "custom";
181
+ type DocumentFace = "front" | "back" | "single";
182
+ interface DocumentTypeConfig {
183
+ type: DocumentType;
184
+ label: string;
185
+ faces: DocumentFace[];
186
+ attributeMapping?: {
187
+ attributeId: string;
188
+ extractedKey: string;
189
+ face?: DocumentFace;
190
+ required?: boolean;
191
+ }[];
192
+ }
193
+ interface FileVerificationConfig {
194
+ enabled: boolean;
195
+ documentTypes: DocumentTypeConfig[];
196
+ autoExtract?: boolean;
197
+ autoValidate?: boolean;
198
+ }
199
+ interface FileAttribute extends BaseAttribute<string> {
200
+ type: "file";
201
+ maxFiles?: number;
202
+ maxSize?: number;
203
+ allowedTypes?: MimeType[] | readonly MimeType[];
204
+ verification?: FileVerificationConfig;
205
+ }
206
+ interface UserAttribute extends BaseAttribute<string> {
207
+ type: "user";
208
+ allowedRoles?: string[];
209
+ }
210
+ /**
211
+ * Target object for a relation - defines which objects can be linked
212
+ */
213
+ interface RelationTarget {
214
+ /** Object name (e.g., "companies", "contacts") */
215
+ object: string;
216
+ /**
217
+ * Display template for the label using mustache-like syntax
218
+ * @example "{name}" or "{firstName} {lastName} — {email}"
219
+ */
220
+ displayTemplate?: string;
221
+ /**
222
+ * Optional filter to restrict available records
223
+ * @example { status: "active" }
224
+ */
225
+ filter?: Record<string, unknown>;
226
+ }
227
+ /**
228
+ * Strategy when a target record is deleted
229
+ * - "restrict": Prevent deletion if relations exist (default)
230
+ * - "cascade": Delete this record too
231
+ * - "set_null": Set the relation value to null
232
+ */
233
+ type RelationOnDelete = "restrict" | "cascade" | "set_null";
234
+ /**
235
+ * Base properties shared by both single and multi relation attributes
236
+ */
237
+ interface RelationAttributeBase extends Omit<BaseAttribute<unknown>, "defaultValue"> {
238
+ type: "relation";
239
+ /** Target objects that can be linked */
240
+ targets: RelationTarget[];
241
+ /** Deletion strategy when target record is deleted */
242
+ onDelete?: RelationOnDelete;
243
+ }
244
+ /**
245
+ * Single relation attribute (one-to-one or many-to-one)
246
+ * Stores a single record ID or null
247
+ */
248
+ interface SingleRelationAttribute extends RelationAttributeBase {
249
+ cardinality: "one";
250
+ defaultValue?: string | null;
251
+ }
252
+ /**
253
+ * Multi relation attribute (one-to-many or many-to-many)
254
+ * Stores an array of record IDs
255
+ */
256
+ interface MultiRelationAttribute extends RelationAttributeBase {
257
+ cardinality: "many";
258
+ defaultValue?: string[];
259
+ /** Minimum number of relations required */
260
+ minItems?: number;
261
+ /** Maximum number of relations allowed */
262
+ maxItems?: number;
263
+ }
264
+ /**
265
+ * RelationAttribute links to other objects/records
266
+ * Discriminated union by cardinality for type-safe value handling
267
+ *
268
+ * @example Single relation (many-to-one)
269
+ * ```typescript
270
+ * relation({ name: "company", label: "Company" })
271
+ * .to("companies")
272
+ * .required()
273
+ * // → Value: "rec-uuid-123" | null
274
+ * ```
275
+ *
276
+ * @example Multi relation (many-to-many)
277
+ * ```typescript
278
+ * relation({ name: "contacts", label: "Contacts" })
279
+ * .to("contacts", { displayTemplate: "{firstName} {lastName}" })
280
+ * .many()
281
+ * .maxItems(5)
282
+ * // → Value: ["rec-1", "rec-2", ...]
283
+ * ```
284
+ *
285
+ * @example Polymorphic relation (multiple target objects)
286
+ * ```typescript
287
+ * relation({ name: "linked", label: "Linked Items" })
288
+ * .to("companies")
289
+ * .to("contacts")
290
+ * .to("deals")
291
+ * .many()
292
+ * // → Can link to records from any of these objects
293
+ * ```
294
+ */
295
+ type RelationAttribute = SingleRelationAttribute | MultiRelationAttribute;
296
+ interface TextAreaAttribute extends BaseAttribute<string> {
297
+ type: "textarea";
298
+ }
299
+ interface RatingAttribute extends BaseAttribute<number> {
300
+ type: "rating";
301
+ max?: number;
302
+ iconType?: "star" | "heart" | "thumbs" | "number";
303
+ }
304
+ type Attribute = TextAttribute | TextAreaAttribute | NumberAttribute | CheckboxAttribute | DateAttribute | PhoneAttribute | CurrencyAttribute | StatusAttribute | LocationAttribute | TimestampAttribute | SelectAttribute | MultiselectAttribute | FileAttribute | UserAttribute | RelationAttribute | RatingAttribute;
305
+
306
+ /**
307
+ * Timestamps for tracking creation and updates
308
+ */
309
+ interface Timestamps {
310
+ createdAt: Date;
311
+ updatedAt: Date;
312
+ }
313
+ /**
314
+ * Object definition - Represents a database table/entity
315
+ */
316
+ interface ObjectDefinition {
317
+ id?: Uuid;
318
+ name: string;
319
+ label: string;
320
+ pluralLabel?: string;
321
+ description?: string;
322
+ icon?: IconName;
323
+ /**
324
+ * Template expression used to compute the object's display label.
325
+ * Supports variable interpolation and pipes for formatting.
326
+ *
327
+ * @example
328
+ * ```typescript
329
+ * // Simple attribute reference
330
+ * labelExpression: "{{ name }}"
331
+ *
332
+ * // Multiple attributes
333
+ * labelExpression: "{{ firstName }} {{ lastName }}"
334
+ *
335
+ * // With pipes for formatting
336
+ * labelExpression: "{{ code | UPPER }} - {{ name | capitalize }}"
337
+ * ```
338
+ *
339
+ * Available pipes: UPPER, LOWER, capitalize, trim
340
+ */
341
+ labelExpression: string;
342
+ attributes: Attribute[];
343
+ system?: boolean;
344
+ metadata?: Record<string, unknown>;
345
+ }
346
+ /**
347
+ * Links an attribute to an object
348
+ */
349
+ interface ObjectAttribute {
350
+ objectId: Uuid;
351
+ attributeId: Uuid;
352
+ order?: number;
353
+ required?: boolean;
354
+ }
355
+ /**
356
+ * Completion status of a record based on data completeness.
357
+ *
358
+ * - `draft`: Record is missing one or more required attribute values.
359
+ * Can be saved but is considered incomplete.
360
+ * - `complete`: All required attribute values are present and valid.
361
+ * Record is ready for use.
362
+ *
363
+ * This is different from workflow status (e.g., "pending", "approved").
364
+ * Completion status is computed dynamically based on the object schema.
365
+ */
366
+ type CompletionStatus = "draft" | "complete";
367
+ /**
368
+ * Record - Instance of an Object (a row in the database)
369
+ */
370
+ interface ObjectRecord extends Timestamps {
371
+ id: Uuid;
372
+ objectId: Uuid;
373
+ /**
374
+ * Display label computed from the object's labelExpression.
375
+ * Computed dynamically based on record values.
376
+ *
377
+ * @example "John Doe" (from "{{ firstName }} {{ lastName }}")
378
+ */
379
+ label: string;
380
+ /**
381
+ * Completion status of the record.
382
+ * - `draft`: Missing required values, record is incomplete
383
+ * - `complete`: All required values present and valid
384
+ *
385
+ * Computed dynamically based on the object's schema.
386
+ */
387
+ completionStatus: CompletionStatus;
388
+ values: Record<string, unknown>;
389
+ }
390
+
391
+ /**
392
+ * Storage provider type
393
+ */
394
+ type StorageProvider = "s3" | "gcs" | "azure" | "local" | "cloudflare-r2" | string;
395
+ /**
396
+ * File visibility level
397
+ */
398
+ type FileVisibility = "public" | "private" | "restricted";
399
+ /**
400
+ * File - Represents uploaded file metadata and storage info
401
+ *
402
+ * ARCHITECTURE:
403
+ * - Fixed table (no custom attributes)
404
+ * - Manages file storage, permissions, and metadata
405
+ * - uploadedBy links to user_profiles table
406
+ * - Supports soft delete via deletedAt
407
+ *
408
+ * @example
409
+ * ```typescript
410
+ * const file: File = {
411
+ * id: "file-123",
412
+ * tenantId: "tenant-456",
413
+ * name: "contract-2025.pdf",
414
+ * originalName: "Contract Acme Corp 2025.pdf",
415
+ * mimeType: "application/pdf",
416
+ * size: 2458624,
417
+ * storageProvider: "s3",
418
+ * storagePath: "tenants/456/files/2025/11/contract-2025.pdf",
419
+ * storageBucket: "my-app-files",
420
+ * url: "https://cdn.example.com/files/file-123",
421
+ * uploadedBy: "profile-789",
422
+ * folderPath: "/contracts/2025",
423
+ * tags: ["contract", "legal"],
424
+ * visibility: "restricted",
425
+ * allowedUsers: ["profile-789", "profile-456"],
426
+ * createdAt: new Date(),
427
+ * updatedAt: new Date(),
428
+ * };
429
+ * ```
430
+ */
431
+ interface File extends Timestamps {
432
+ id: Uuid;
433
+ tenantId: Uuid;
434
+ /**
435
+ * File name (sanitized for storage)
436
+ */
437
+ name: string;
438
+ /**
439
+ * Original file name (as uploaded by user)
440
+ */
441
+ originalName: string;
442
+ /**
443
+ * MIME type (e.g., "application/pdf", "image/jpeg")
444
+ */
445
+ mimeType: MimeType | string;
446
+ /**
447
+ * File size in bytes
448
+ */
449
+ size: number;
450
+ /**
451
+ * Storage provider (s3, gcs, azure, local, etc.)
452
+ */
453
+ storageProvider: StorageProvider;
454
+ /**
455
+ * Path in the storage bucket
456
+ */
457
+ storagePath: string;
458
+ /**
459
+ * Storage bucket name (if applicable)
460
+ */
461
+ storageBucket?: string;
462
+ /**
463
+ * Public or signed URL to access the file
464
+ */
465
+ url: string;
466
+ /**
467
+ * User who uploaded the file (FK to user_profiles)
468
+ */
469
+ uploadedBy: Uuid;
470
+ /**
471
+ * Folder path for organization (e.g., "/contracts/2025")
472
+ */
473
+ folderPath?: string;
474
+ /**
475
+ * Tags for search and categorization
476
+ */
477
+ tags?: string[];
478
+ /**
479
+ * File visibility level
480
+ * - public: Anyone with the URL can access
481
+ * - private: Only uploadedBy can access
482
+ * - restricted: Only specific users (allowedUsers) can access
483
+ */
484
+ visibility: FileVisibility;
485
+ /**
486
+ * List of user IDs authorized to access this file (if visibility = "restricted")
487
+ */
488
+ allowedUsers?: Uuid[];
489
+ /**
490
+ * Soft delete timestamp (null = not deleted)
491
+ */
492
+ deletedAt?: Date;
493
+ }
494
+ /**
495
+ * Data required to create a new file record
496
+ */
497
+ interface CreateFile {
498
+ tenantId: Uuid;
499
+ name: string;
500
+ originalName: string;
501
+ mimeType: MimeType | string;
502
+ size: number;
503
+ storageProvider: StorageProvider;
504
+ storagePath: string;
505
+ storageBucket?: string;
506
+ url: string;
507
+ uploadedBy: Uuid;
508
+ folderPath?: string;
509
+ tags?: string[];
510
+ visibility?: FileVisibility;
511
+ allowedUsers?: Uuid[];
512
+ }
513
+ /**
514
+ * Data for updating an existing file record
515
+ */
516
+ interface UpdateFile {
517
+ name?: string;
518
+ folderPath?: string;
519
+ tags?: string[];
520
+ visibility?: FileVisibility;
521
+ allowedUsers?: Uuid[];
522
+ }
523
+
524
+ /** Operators for text-based attributes */
525
+ type TextFilterOperator = "is" | "is_not" | "contains" | "not_contains" | "starts_with" | "ends_with" | "is_empty" | "is_not_empty";
526
+ /** Operators for number-based attributes */
527
+ type NumberFilterOperator = "eq" | "neq" | "lt" | "gt" | "lte" | "gte" | "is_empty" | "is_not_empty";
528
+ /** Operators for checkbox */
529
+ type CheckboxFilterOperator = "is_checked" | "is_not_checked";
530
+ /** Operators for date-based attributes */
531
+ type DateFilterOperator = "is" | "is_not" | "before" | "after" | "on_or_before" | "on_or_after" | "is_within" | "is_empty" | "is_not_empty";
532
+ /** Operators for select-based attributes (supports single or multi-value filtering) */
533
+ type SelectFilterOperator = "is" | "is_not" | "any_of" | "none_of" | "is_empty" | "is_not_empty";
534
+ /** Operators for multiselect-based attributes */
535
+ type MultiselectFilterOperator = "contains" | "not_contains" | "is_empty" | "is_not_empty";
536
+ /** Operators for relation-based attributes */
537
+ type RelationFilterOperator = "contains" | "not_contains" | "is_empty" | "is_not_empty";
538
+ /** All possible filter operators */
539
+ type FilterOperator = TextFilterOperator | NumberFilterOperator | CheckboxFilterOperator | DateFilterOperator | SelectFilterOperator | MultiselectFilterOperator | RelationFilterOperator;
540
+ /** Relative date value for "is_within" operator */
541
+ interface RelativeDateValue {
542
+ amount: number;
543
+ unit: "days" | "weeks" | "months" | "years";
544
+ direction: "past" | "future";
545
+ }
546
+ /** Filter value can be various types depending on the attribute */
547
+ type FilterValue = string | number | boolean | string[] | RelativeDateValue | null;
548
+ /** A single filter rule */
549
+ interface FilterRule {
550
+ /** Attribute name to filter on */
551
+ attribute: string;
552
+ /** Filter operator */
553
+ operator: FilterOperator;
554
+ /** Filter value (null for operators like is_empty) */
555
+ value: FilterValue;
556
+ }
557
+ /** Combinator for filter rules */
558
+ type FilterCombinator = "and" | "or";
559
+ /** Complete filter state (simple mode) */
560
+ interface FilterState {
561
+ /** How to combine rules */
562
+ combinator: FilterCombinator;
563
+ /** List of filter rules */
564
+ rules: FilterRule[];
565
+ }
566
+ /**
567
+ * A filter group containing rules (used in advanced mode)
568
+ * Groups can be nested up to 2 levels deep
569
+ */
570
+ interface FilterGroup {
571
+ /** Unique identifier for this group */
572
+ id: string;
573
+ /** How to combine rules within this group */
574
+ combinator: FilterCombinator;
575
+ /** List of filter rules in this group */
576
+ rules: FilterRule[];
577
+ }
578
+ /**
579
+ * Advanced filter state with nested groups
580
+ * Structure: AdvancedFilterState -> FilterGroup[] -> FilterRule[]
581
+ * Maximum 2 levels of nesting
582
+ */
583
+ interface AdvancedFilterState {
584
+ /** How to combine groups at the top level */
585
+ combinator: FilterCombinator;
586
+ /** List of filter groups */
587
+ groups: FilterGroup[];
588
+ }
589
+ /**
590
+ * Type guard to check if a filter state is advanced
591
+ */
592
+ declare function isAdvancedFilterState(state: FilterState | AdvancedFilterState): state is AdvancedFilterState;
593
+ /**
594
+ * Convert simple filter state to advanced filter state
595
+ */
596
+ declare function toAdvancedFilterState(state: FilterState): AdvancedFilterState;
597
+ /**
598
+ * Convert advanced filter state to simple filter state (flattens groups)
599
+ * Note: This loses group structure - use with caution
600
+ */
601
+ declare function toSimpleFilterState(state: AdvancedFilterState): FilterState;
602
+ /** Sort direction */
603
+ type SortDirection = "asc" | "desc";
604
+ /** A single sort rule */
605
+ interface SortRule {
606
+ /** Attribute name to sort by */
607
+ attribute: string;
608
+ /** Sort direction */
609
+ direction: SortDirection;
610
+ }
611
+ /** Complete query state with search, filters, sorts, and pagination */
612
+ interface QueryState {
613
+ /** Full-text search query */
614
+ search?: string;
615
+ /** Filter configuration (simple mode) */
616
+ filters?: FilterState;
617
+ /** Advanced filter configuration (grouped mode) */
618
+ advancedFilters?: AdvancedFilterState;
619
+ /** Sort configuration (multiple sorts supported) */
620
+ sorts?: SortRule[];
621
+ /** Pagination */
622
+ limit?: number;
623
+ offset?: number;
624
+ }
625
+ /** Mapping of attribute types to their valid operators */
626
+ declare const OPERATORS_BY_TYPE: Record<AttributeType, readonly FilterOperator[]>;
627
+ /** Check if an operator requires a value */
628
+ type NoValueOperator = "is_empty" | "is_not_empty" | "is_checked" | "is_not_checked";
629
+ /** Operators that don't require a value */
630
+ declare const NO_VALUE_OPERATORS: readonly NoValueOperator[];
631
+ /**
632
+ * Check if an operator requires a value
633
+ */
634
+ declare function isNoValueOperator(operator: FilterOperator): operator is NoValueOperator;
635
+
636
+ /**
637
+ * Autocomplete suggestion from geocoding service
638
+ */
639
+ interface GeocodingSuggestion {
640
+ /** Unique identifier from the provider */
641
+ id: string;
642
+ /** Human-readable label for display */
643
+ label: string;
644
+ /** Structured location data */
645
+ location: Location;
646
+ /** Optional match score/confidence (0-1) */
647
+ score?: number;
648
+ /** Optional additional metadata from the provider */
649
+ metadata?: Record<string, unknown>;
650
+ }
651
+ /**
652
+ * Parameters for autocomplete search
653
+ */
654
+ interface GeocodingAutocompleteParams {
655
+ /** Search query */
656
+ query: string;
657
+ /** Restrict results to specific countries */
658
+ countries?: CountryIso3[];
659
+ /** Preferred language for results (ISO 639-1) */
660
+ language?: string;
661
+ /** Maximum number of results */
662
+ limit?: number;
663
+ /** Bias results toward a specific location */
664
+ biasLocation?: {
665
+ latitude: number;
666
+ longitude: number;
667
+ };
668
+ /** Session token for billing optimization (some providers) */
669
+ sessionToken?: string;
670
+ /**
671
+ * Level of address detail expected
672
+ * Adapters can use this to filter/optimize results
673
+ * - "full": Full address with street, city, postal code, etc.
674
+ * - "address": Street address without postal code
675
+ * - "city": City level only
676
+ * - "state": State/region level only
677
+ * - "country": Country level only
678
+ * - "coordinates": Only coordinates (lat/lng)
679
+ */
680
+ granularity?: LocationGranularity;
681
+ }
682
+ /**
683
+ * Parameters for reverse geocoding
684
+ */
685
+ interface ReverseGeocodingParams {
686
+ /** Latitude */
687
+ latitude: number;
688
+ /** Longitude */
689
+ longitude: number;
690
+ /** Preferred language for results */
691
+ language?: string;
692
+ }
693
+ /**
694
+ * Parameters for geocoding a structured address
695
+ */
696
+ interface GeocodingParams {
697
+ /** Structured address components */
698
+ address: Partial<Location>;
699
+ /** Preferred language for results */
700
+ language?: string;
701
+ }
702
+ /**
703
+ * Abstract geocoding adapter interface
704
+ * Implement this interface for different geocoding providers
705
+ *
706
+ * @example Google Maps implementation
707
+ * ```typescript
708
+ * class GoogleMapsGeocodingAdapter implements GeocodingAdapter {
709
+ * async autocomplete(params) {
710
+ * const response = await fetch(
711
+ * `https://maps.googleapis.com/maps/api/place/autocomplete/json?input=${params.query}&key=${this.apiKey}`
712
+ * );
713
+ * // Transform response to GeocodingSuggestion[]
714
+ * }
715
+ * }
716
+ * ```
717
+ *
718
+ * @example Mapbox implementation
719
+ * ```typescript
720
+ * class MapboxGeocodingAdapter implements GeocodingAdapter {
721
+ * async autocomplete(params) {
722
+ * const response = await fetch(
723
+ * `https://api.mapbox.com/geocoding/v5/mapbox.places/${params.query}.json?access_token=${this.token}`
724
+ * );
725
+ * // Transform response to GeocodingSuggestion[]
726
+ * }
727
+ * }
728
+ * ```
729
+ */
730
+ interface GeocodingAdapter {
731
+ /**
732
+ * Autocomplete address search
733
+ * Returns suggestions as the user types
734
+ */
735
+ autocomplete(params: GeocodingAutocompleteParams): Promise<GeocodingSuggestion[]>;
736
+ /**
737
+ * Reverse geocode coordinates to an address
738
+ * Optional - some providers may not support this
739
+ */
740
+ reverse?(params: ReverseGeocodingParams): Promise<GeocodingSuggestion | null>;
741
+ /**
742
+ * Geocode a structured address to coordinates
743
+ * Optional - some providers may not support this
744
+ */
745
+ geocode?(params: GeocodingParams): Promise<GeocodingSuggestion | null>;
746
+ }
747
+ /**
748
+ * No-op geocoding adapter
749
+ * Returns empty results when no geocoding provider is configured
750
+ */
751
+ declare class NoopGeocodingAdapter implements GeocodingAdapter {
752
+ autocomplete(): Promise<GeocodingSuggestion[]>;
753
+ reverse(): Promise<null>;
754
+ geocode(): Promise<null>;
755
+ }
756
+
757
+ /**
758
+ * User role in the application
759
+ * Can be extended with custom roles as needed
760
+ */
761
+ type UserRole = "admin" | "member" | "guest" | string;
762
+ /**
763
+ * User status for account management
764
+ */
765
+ type UserStatus = "active" | "pending" | "inactive" | "suspended";
766
+ /**
767
+ * User Profile - Represents application user data (authorization)
768
+ *
769
+ * ARCHITECTURE:
770
+ * - authId links to external auth provider (Supabase, Clerk, Auth0, etc.)
771
+ * - email is denormalized from auth provider for performance
772
+ * - Auth provider handles authentication (passwords, sessions, OAuth)
773
+ * - This type handles authorization (roles, permissions, tenant membership)
774
+ *
775
+ * @example
776
+ * ```typescript
777
+ * const profile: UserProfile = {
778
+ * id: "profile-123",
779
+ * tenantId: "tenant-456",
780
+ * authId: "supabase-auth-uuid-789",
781
+ * email: "john@example.com",
782
+ * firstName: "John",
783
+ * lastName: "Doe",
784
+ * role: "admin",
785
+ * status: "active",
786
+ * createdAt: new Date(),
787
+ * updatedAt: new Date(),
788
+ * };
789
+ * ```
790
+ */
791
+ interface UserProfile extends Timestamps {
792
+ id: Uuid;
793
+ tenantId: Uuid;
794
+ /**
795
+ * Link to external auth provider (Supabase auth.users.id, Clerk user ID, etc.)
796
+ * This is the bridge between authentication (provider) and authorization (your app)
797
+ */
798
+ authId: string;
799
+ /**
800
+ * Email address (denormalized from auth provider)
801
+ * Allows efficient querying and filtering without hitting auth provider API
802
+ */
803
+ email: string;
804
+ /**
805
+ * User's first name
806
+ */
807
+ firstName?: string;
808
+ /**
809
+ * User's last name
810
+ */
811
+ lastName?: string;
812
+ /**
813
+ * Avatar/profile picture URL
814
+ */
815
+ avatarUrl?: string;
816
+ /**
817
+ * User role for authorization
818
+ * Common values: "admin", "member", "guest"
819
+ * Can be extended with custom roles
820
+ */
821
+ role: UserRole;
822
+ /**
823
+ * Account status
824
+ * - active: Normal user, full access
825
+ * - pending: Awaiting activation/approval
826
+ * - inactive: Deactivated account
827
+ * - suspended: Temporarily blocked
828
+ */
829
+ status: UserStatus;
830
+ /**
831
+ * Last login timestamp (updated on each successful auth)
832
+ */
833
+ lastLoginAt?: Date;
834
+ }
835
+ /**
836
+ * Data required to create a new user profile
837
+ */
838
+ interface CreateUserProfile {
839
+ tenantId: Uuid;
840
+ authId: string;
841
+ email: string;
842
+ firstName?: string;
843
+ lastName?: string;
844
+ avatarUrl?: string;
845
+ role?: UserRole;
846
+ status?: UserStatus;
847
+ }
848
+ /**
849
+ * Data for updating an existing user profile
850
+ */
851
+ interface UpdateUserProfile {
852
+ firstName?: string;
853
+ lastName?: string;
854
+ avatarUrl?: string;
855
+ role?: UserRole;
856
+ status?: UserStatus;
857
+ lastLoginAt?: Date;
858
+ }
859
+
860
+ /**
861
+ * Inline attribute group configuration
862
+ * Groups multiple attributes into a single composite field with dropdown editing
863
+ */
864
+ interface AttributeGroupField {
865
+ /** Unique identifier for the group */
866
+ id: string;
867
+ /** Display label for the composite field */
868
+ label: string;
869
+ /** Description shown in the dropdown */
870
+ description?: string;
871
+ /** Attribute names to include in this group */
872
+ attributes: string[];
873
+ /**
874
+ * Template for the display value
875
+ * Uses {attributeName} syntax for interpolation
876
+ * @example "{billing_street}, {billing_city} {billing_postal_code}"
877
+ */
878
+ displayTemplate?: string;
879
+ }
880
+ /**
881
+ * Field definition within a form group
882
+ * Can be either a single attribute or an inline attribute group
883
+ */
884
+ interface Field {
885
+ /** Attribute name to display (for single attribute fields) */
886
+ attribute?: string;
887
+ /** Inline attribute group (groups multiple attributes into one composite field) */
888
+ attributeGroup?: AttributeGroupField;
889
+ /** Grid span (1-12 columns) */
890
+ span?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
891
+ /** Override label for this view (only for single attribute fields) */
892
+ label?: string;
893
+ /** Force read-only display */
894
+ readOnly?: boolean;
895
+ }
896
+ /**
897
+ * Group of fields for organizing forms
898
+ */
899
+ interface Group {
900
+ id: string;
901
+ label: string;
902
+ description?: string;
903
+ fields: Field[];
904
+ collapsible?: boolean;
905
+ collapsed?: boolean;
906
+ order?: number;
907
+ }
908
+ type TabType = "form" | "table" | "custom";
909
+ /**
910
+ * Base properties shared by all tab types
911
+ */
912
+ interface BaseTab {
913
+ id: string;
914
+ name: string;
915
+ label: string;
916
+ icon?: IconName;
917
+ order?: number;
918
+ /** If true, tab is defined by developer (protected) */
919
+ system?: boolean;
920
+ }
921
+ /**
922
+ * Form tab - displays attributes organized in groups
923
+ */
924
+ interface FormTab extends BaseTab {
925
+ type: "form";
926
+ groups: Group[];
927
+ }
928
+ /**
929
+ * Table tab - displays records from a relation attribute
930
+ */
931
+ interface TableTab extends BaseTab {
932
+ type: "table";
933
+ /** Name of the relation attribute */
934
+ relation: string;
935
+ /** Columns to display (attribute names from target object) */
936
+ columns: string[];
937
+ /** Allow creating new records */
938
+ allowCreate?: boolean;
939
+ /** Allow inline editing */
940
+ allowEdit?: boolean;
941
+ /** Allow deleting records */
942
+ allowDelete?: boolean;
943
+ /** Default filters */
944
+ filters?: Record<string, unknown>;
945
+ /** Default sort */
946
+ sort?: {
947
+ field: string;
948
+ order: "asc" | "desc";
949
+ };
950
+ }
951
+ /**
952
+ * Custom tab - renders a developer-defined component
953
+ */
954
+ interface CustomTab extends BaseTab {
955
+ type: "custom";
956
+ /** Component identifier to render */
957
+ component: string;
958
+ /** Props to pass to the component */
959
+ props?: Record<string, unknown>;
960
+ }
961
+ /**
962
+ * Union of all tab types
963
+ */
964
+ type Tab = FormTab | TableTab | CustomTab;
965
+ /**
966
+ * View definition - organizes object attributes into tabs/pages
967
+ *
968
+ * @example
969
+ * ```typescript
970
+ * const companyView: ViewDefinition = {
971
+ * name: "detail",
972
+ * label: "Company Detail",
973
+ * object: "companies",
974
+ * tabs: [
975
+ * { type: "form", name: "general", label: "Info", groups: [...] },
976
+ * { type: "table", name: "contacts", label: "Contacts", relation: "contacts", columns: [...] }
977
+ * ],
978
+ * default: true,
979
+ * system: true
980
+ * };
981
+ * ```
982
+ */
983
+ interface ViewDefinition {
984
+ id?: Uuid;
985
+ /** Technical name (kebab-case) */
986
+ name: string;
987
+ /** Display label */
988
+ label: string;
989
+ /** Description */
990
+ description?: string;
991
+ /** Icon */
992
+ icon?: IconName;
993
+ /** Object this view belongs to (object name) */
994
+ object: string;
995
+ /** Tabs in this view */
996
+ tabs: Tab[];
997
+ /** Default view for this object */
998
+ default?: boolean;
999
+ /** System view (defined by developer, protected) */
1000
+ system?: boolean;
1001
+ /** Extensible metadata */
1002
+ metadata?: Record<string, unknown>;
1003
+ }
1004
+ /**
1005
+ * Check if a tab is a form tab
1006
+ */
1007
+ declare function isFormTab(tab: Tab): tab is FormTab;
1008
+ /**
1009
+ * Check if a tab is a table tab
1010
+ */
1011
+ declare function isTableTab(tab: Tab): tab is TableTab;
1012
+ /**
1013
+ * Check if a tab is a custom tab
1014
+ */
1015
+ declare function isCustomTab(tab: Tab): tab is CustomTab;
1016
+
1017
+ /**
1018
+ * Registry for native objects defined in code
1019
+ * Native objects are system objects that cannot be deleted/modified by clients
1020
+ * They are defined by developers and synced to the database at startup
1021
+ */
1022
+ declare class NativeObjectRegistryClass {
1023
+ private objects;
1024
+ /**
1025
+ * Register one or more native objects
1026
+ * Auto-builds if ObjectBuilder is passed instead of ObjectDefinition
1027
+ * @param objects - Single object/builder or array of objects/builders to register
1028
+ * @returns this (for chaining)
1029
+ * @throws Error if object is invalid or already registered
1030
+ *
1031
+ * @example
1032
+ * ```typescript
1033
+ * // No .build() needed - registry auto-builds!
1034
+ * const PRODUCT = object({ id: "obj-product", name: "products", label: "Product" })
1035
+ * .system()
1036
+ * .attribute(text({ id: "attr-name", name: "name", label: "Name" }));
1037
+ *
1038
+ * registry.register(PRODUCT); // ← Auto-builds here
1039
+ *
1040
+ * // Can still explicitly .build() if you want
1041
+ * registry.register(PRODUCT.build());
1042
+ *
1043
+ * // Register multiple
1044
+ * registry.register([PRODUCT, ORDER, CUSTOMER]);
1045
+ * ```
1046
+ */
1047
+ register(objects: ObjectDefinition | ObjectDefinition[] | {
1048
+ build: () => ObjectDefinition;
1049
+ } | Array<{
1050
+ build: () => ObjectDefinition;
1051
+ }>): this;
1052
+ /**
1053
+ * Validate and register a single object
1054
+ * @internal
1055
+ */
1056
+ private validateAndRegister;
1057
+ /**
1058
+ * Get a native object by its name
1059
+ * @param name - The object name
1060
+ * @returns The object definition or undefined if not found
1061
+ *
1062
+ * @example
1063
+ * ```typescript
1064
+ * const product = registry.getByName("products");
1065
+ * if (product) {
1066
+ * console.log(product.label); // "Product"
1067
+ * }
1068
+ * ```
1069
+ */
1070
+ getByName(name: string): ObjectDefinition | undefined;
1071
+ /**
1072
+ * Get a native object or throw if not found
1073
+ * @param name - The object name
1074
+ * @returns The object definition
1075
+ * @throws Error if not found
1076
+ */
1077
+ getByNameOrThrow(name: string): ObjectDefinition;
1078
+ /**
1079
+ * Get all registered native objects
1080
+ * @returns Array of all registered object definitions
1081
+ */
1082
+ getAll(): ObjectDefinition[];
1083
+ /**
1084
+ * Get all registered native object names
1085
+ * @returns Array of object names
1086
+ */
1087
+ listNames(): string[];
1088
+ /**
1089
+ * Check if a native object is registered
1090
+ * @param name - The object name
1091
+ * @returns true if registered, false otherwise
1092
+ */
1093
+ has(name: string): boolean;
1094
+ /**
1095
+ * Get the number of registered objects
1096
+ */
1097
+ get size(): number;
1098
+ /**
1099
+ * Clear all registered objects (useful for testing)
1100
+ * @internal
1101
+ */
1102
+ clear(): void;
1103
+ /**
1104
+ * Get registry summary for debugging
1105
+ */
1106
+ summary(): string;
1107
+ /**
1108
+ * Log registry summary to console
1109
+ */
1110
+ debug(): void;
1111
+ }
1112
+ /**
1113
+ * Singleton instance of the registry
1114
+ * Use this to register and retrieve native objects
1115
+ *
1116
+ * @example
1117
+ * ```typescript
1118
+ * import { registry } from "@stndrds/schema";
1119
+ *
1120
+ * // Register objects
1121
+ * registry.register([PRODUCT, ORDER, CUSTOMER]);
1122
+ *
1123
+ * // Get object by name
1124
+ * const product = registry.getByName("products");
1125
+ *
1126
+ * // List all
1127
+ * console.log(registry.listNames()); // ["products", "orders", ...]
1128
+ *
1129
+ * // Debug
1130
+ * registry.debug();
1131
+ * ```
1132
+ */
1133
+ declare const registry: NativeObjectRegistryClass;
1134
+
1135
+ /**
1136
+ * Registry for native view definitions
1137
+ *
1138
+ * Views registered here are considered "system" views, defined by the developer.
1139
+ * They are protected from modification by end-users and synced to the database
1140
+ * at application startup.
1141
+ *
1142
+ * @example
1143
+ * ```typescript
1144
+ * import { view, group, viewRegistry } from "@stndrds/schema";
1145
+ *
1146
+ * const COMPANY_DETAIL = view("detail", "Detail")
1147
+ * .for("companies")
1148
+ * .system()
1149
+ * .tab("general", "Info")
1150
+ * .form(group("main", "Main").fields("name", "status"))
1151
+ * .build();
1152
+ *
1153
+ * viewRegistry.register(COMPANY_DETAIL);
1154
+ * ```
1155
+ */
1156
+ declare class ViewRegistry {
1157
+ private views;
1158
+ private byObject;
1159
+ /**
1160
+ * Register a native view
1161
+ * @param viewOrViews - Single view or array of views
1162
+ * @throws Error if view is not marked as system
1163
+ * @throws Error if view with same name already exists for the object
1164
+ */
1165
+ register(viewOrViews: ViewDefinition | ViewDefinition[]): this;
1166
+ private registerSingle;
1167
+ /**
1168
+ * Get all views for an object
1169
+ */
1170
+ getByObjectName(objectName: string): ViewDefinition[];
1171
+ /**
1172
+ * Get a specific view by object and view name
1173
+ */
1174
+ get(objectName: string, viewName: string): ViewDefinition | undefined;
1175
+ /**
1176
+ * Get a view or throw if not found
1177
+ */
1178
+ getOrThrow(objectName: string, viewName: string): ViewDefinition;
1179
+ /**
1180
+ * Get all registered views
1181
+ */
1182
+ getAll(): ViewDefinition[];
1183
+ /**
1184
+ * Check if a view exists
1185
+ */
1186
+ has(objectName: string, viewName: string): boolean;
1187
+ /**
1188
+ * Check if any views exist for an object
1189
+ */
1190
+ hasObject(objectName: string): boolean;
1191
+ /**
1192
+ * Get number of registered views
1193
+ */
1194
+ get size(): number;
1195
+ /**
1196
+ * List all object names that have views
1197
+ */
1198
+ listObjectNames(): string[];
1199
+ /**
1200
+ * Get default view for an object (if any)
1201
+ */
1202
+ getDefault(objectName: string): ViewDefinition | undefined;
1203
+ /**
1204
+ * Clear all registered views (for testing)
1205
+ */
1206
+ clear(): void;
1207
+ /**
1208
+ * Generate summary string for debugging
1209
+ */
1210
+ summary(): string;
1211
+ /**
1212
+ * Log summary to console
1213
+ */
1214
+ debug(): void;
1215
+ private makeKey;
1216
+ }
1217
+ /**
1218
+ * Global registry for native views
1219
+ */
1220
+ declare const viewRegistry: ViewRegistry;
1221
+
1222
+ /**
1223
+ * Text attribute config schema
1224
+ */
1225
+ declare const textConfigSchema: z.ZodObject<{
1226
+ disabled: z.ZodOptional<z.ZodBoolean>;
1227
+ placeholder: z.ZodOptional<z.ZodString>;
1228
+ description: z.ZodOptional<z.ZodString>;
1229
+ defaultValue: z.ZodOptional<z.ZodUnknown>;
1230
+ icon: z.ZodOptional<z.ZodString>;
1231
+ order: z.ZodOptional<z.ZodNumber>;
1232
+ hidden: z.ZodOptional<z.ZodBoolean>;
1233
+ archived: z.ZodOptional<z.ZodBoolean>;
1234
+ deprecated: z.ZodOptional<z.ZodBoolean>;
1235
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1236
+ } & {
1237
+ minLength: z.ZodOptional<z.ZodNumber>;
1238
+ maxLength: z.ZodOptional<z.ZodNumber>;
1239
+ pattern: z.ZodOptional<z.ZodString>;
1240
+ }, "strip", z.ZodTypeAny, {
1241
+ defaultValue?: unknown;
1242
+ disabled?: boolean | undefined;
1243
+ placeholder?: string | undefined;
1244
+ description?: string | undefined;
1245
+ icon?: string | undefined;
1246
+ order?: number | undefined;
1247
+ hidden?: boolean | undefined;
1248
+ archived?: boolean | undefined;
1249
+ deprecated?: boolean | undefined;
1250
+ metadata?: Record<string, unknown> | undefined;
1251
+ minLength?: number | undefined;
1252
+ maxLength?: number | undefined;
1253
+ pattern?: string | undefined;
1254
+ }, {
1255
+ defaultValue?: unknown;
1256
+ disabled?: boolean | undefined;
1257
+ placeholder?: string | undefined;
1258
+ description?: string | undefined;
1259
+ icon?: string | undefined;
1260
+ order?: number | undefined;
1261
+ hidden?: boolean | undefined;
1262
+ archived?: boolean | undefined;
1263
+ deprecated?: boolean | undefined;
1264
+ metadata?: Record<string, unknown> | undefined;
1265
+ minLength?: number | undefined;
1266
+ maxLength?: number | undefined;
1267
+ pattern?: string | undefined;
1268
+ }>;
1269
+ /**
1270
+ * Textarea attribute config schema
1271
+ */
1272
+ declare const textareaConfigSchema: z.ZodObject<{
1273
+ disabled: z.ZodOptional<z.ZodBoolean>;
1274
+ placeholder: z.ZodOptional<z.ZodString>;
1275
+ description: z.ZodOptional<z.ZodString>;
1276
+ defaultValue: z.ZodOptional<z.ZodUnknown>;
1277
+ icon: z.ZodOptional<z.ZodString>;
1278
+ order: z.ZodOptional<z.ZodNumber>;
1279
+ hidden: z.ZodOptional<z.ZodBoolean>;
1280
+ archived: z.ZodOptional<z.ZodBoolean>;
1281
+ deprecated: z.ZodOptional<z.ZodBoolean>;
1282
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1283
+ }, "strip", z.ZodTypeAny, {
1284
+ defaultValue?: unknown;
1285
+ disabled?: boolean | undefined;
1286
+ placeholder?: string | undefined;
1287
+ description?: string | undefined;
1288
+ icon?: string | undefined;
1289
+ order?: number | undefined;
1290
+ hidden?: boolean | undefined;
1291
+ archived?: boolean | undefined;
1292
+ deprecated?: boolean | undefined;
1293
+ metadata?: Record<string, unknown> | undefined;
1294
+ }, {
1295
+ defaultValue?: unknown;
1296
+ disabled?: boolean | undefined;
1297
+ placeholder?: string | undefined;
1298
+ description?: string | undefined;
1299
+ icon?: string | undefined;
1300
+ order?: number | undefined;
1301
+ hidden?: boolean | undefined;
1302
+ archived?: boolean | undefined;
1303
+ deprecated?: boolean | undefined;
1304
+ metadata?: Record<string, unknown> | undefined;
1305
+ }>;
1306
+ /**
1307
+ * Number attribute config schema
1308
+ */
1309
+ declare const numberConfigSchema: z.ZodObject<{
1310
+ disabled: z.ZodOptional<z.ZodBoolean>;
1311
+ placeholder: z.ZodOptional<z.ZodString>;
1312
+ description: z.ZodOptional<z.ZodString>;
1313
+ defaultValue: z.ZodOptional<z.ZodUnknown>;
1314
+ icon: z.ZodOptional<z.ZodString>;
1315
+ order: z.ZodOptional<z.ZodNumber>;
1316
+ hidden: z.ZodOptional<z.ZodBoolean>;
1317
+ archived: z.ZodOptional<z.ZodBoolean>;
1318
+ deprecated: z.ZodOptional<z.ZodBoolean>;
1319
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1320
+ } & {
1321
+ min: z.ZodOptional<z.ZodNumber>;
1322
+ max: z.ZodOptional<z.ZodNumber>;
1323
+ unit: z.ZodOptional<z.ZodEnum<["integer", "decimal", "percentage"]>>;
1324
+ decimals: z.ZodOptional<z.ZodNumber>;
1325
+ }, "strip", z.ZodTypeAny, {
1326
+ defaultValue?: unknown;
1327
+ disabled?: boolean | undefined;
1328
+ placeholder?: string | undefined;
1329
+ description?: string | undefined;
1330
+ icon?: string | undefined;
1331
+ order?: number | undefined;
1332
+ hidden?: boolean | undefined;
1333
+ archived?: boolean | undefined;
1334
+ deprecated?: boolean | undefined;
1335
+ metadata?: Record<string, unknown> | undefined;
1336
+ min?: number | undefined;
1337
+ max?: number | undefined;
1338
+ unit?: "percentage" | "integer" | "decimal" | undefined;
1339
+ decimals?: number | undefined;
1340
+ }, {
1341
+ defaultValue?: unknown;
1342
+ disabled?: boolean | undefined;
1343
+ placeholder?: string | undefined;
1344
+ description?: string | undefined;
1345
+ icon?: string | undefined;
1346
+ order?: number | undefined;
1347
+ hidden?: boolean | undefined;
1348
+ archived?: boolean | undefined;
1349
+ deprecated?: boolean | undefined;
1350
+ metadata?: Record<string, unknown> | undefined;
1351
+ min?: number | undefined;
1352
+ max?: number | undefined;
1353
+ unit?: "percentage" | "integer" | "decimal" | undefined;
1354
+ decimals?: number | undefined;
1355
+ }>;
1356
+ /**
1357
+ * Checkbox attribute config schema
1358
+ */
1359
+ declare const checkboxConfigSchema: z.ZodObject<{
1360
+ disabled: z.ZodOptional<z.ZodBoolean>;
1361
+ placeholder: z.ZodOptional<z.ZodString>;
1362
+ description: z.ZodOptional<z.ZodString>;
1363
+ defaultValue: z.ZodOptional<z.ZodUnknown>;
1364
+ icon: z.ZodOptional<z.ZodString>;
1365
+ order: z.ZodOptional<z.ZodNumber>;
1366
+ hidden: z.ZodOptional<z.ZodBoolean>;
1367
+ archived: z.ZodOptional<z.ZodBoolean>;
1368
+ deprecated: z.ZodOptional<z.ZodBoolean>;
1369
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1370
+ }, "strip", z.ZodTypeAny, {
1371
+ defaultValue?: unknown;
1372
+ disabled?: boolean | undefined;
1373
+ placeholder?: string | undefined;
1374
+ description?: string | undefined;
1375
+ icon?: string | undefined;
1376
+ order?: number | undefined;
1377
+ hidden?: boolean | undefined;
1378
+ archived?: boolean | undefined;
1379
+ deprecated?: boolean | undefined;
1380
+ metadata?: Record<string, unknown> | undefined;
1381
+ }, {
1382
+ defaultValue?: unknown;
1383
+ disabled?: boolean | undefined;
1384
+ placeholder?: string | undefined;
1385
+ description?: string | undefined;
1386
+ icon?: string | undefined;
1387
+ order?: number | undefined;
1388
+ hidden?: boolean | undefined;
1389
+ archived?: boolean | undefined;
1390
+ deprecated?: boolean | undefined;
1391
+ metadata?: Record<string, unknown> | undefined;
1392
+ }>;
1393
+ /**
1394
+ * Date attribute config schema
1395
+ */
1396
+ declare const dateConfigSchema: z.ZodObject<{
1397
+ disabled: z.ZodOptional<z.ZodBoolean>;
1398
+ placeholder: z.ZodOptional<z.ZodString>;
1399
+ description: z.ZodOptional<z.ZodString>;
1400
+ defaultValue: z.ZodOptional<z.ZodUnknown>;
1401
+ icon: z.ZodOptional<z.ZodString>;
1402
+ order: z.ZodOptional<z.ZodNumber>;
1403
+ hidden: z.ZodOptional<z.ZodBoolean>;
1404
+ archived: z.ZodOptional<z.ZodBoolean>;
1405
+ deprecated: z.ZodOptional<z.ZodBoolean>;
1406
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1407
+ } & {
1408
+ dateFormat: z.ZodOptional<z.ZodEnum<["short", "long", "full", "relative"]>>;
1409
+ minDate: z.ZodOptional<z.ZodString>;
1410
+ maxDate: z.ZodOptional<z.ZodString>;
1411
+ }, "strip", z.ZodTypeAny, {
1412
+ defaultValue?: unknown;
1413
+ disabled?: boolean | undefined;
1414
+ placeholder?: string | undefined;
1415
+ description?: string | undefined;
1416
+ icon?: string | undefined;
1417
+ order?: number | undefined;
1418
+ hidden?: boolean | undefined;
1419
+ archived?: boolean | undefined;
1420
+ deprecated?: boolean | undefined;
1421
+ metadata?: Record<string, unknown> | undefined;
1422
+ dateFormat?: "short" | "long" | "full" | "relative" | undefined;
1423
+ minDate?: string | undefined;
1424
+ maxDate?: string | undefined;
1425
+ }, {
1426
+ defaultValue?: unknown;
1427
+ disabled?: boolean | undefined;
1428
+ placeholder?: string | undefined;
1429
+ description?: string | undefined;
1430
+ icon?: string | undefined;
1431
+ order?: number | undefined;
1432
+ hidden?: boolean | undefined;
1433
+ archived?: boolean | undefined;
1434
+ deprecated?: boolean | undefined;
1435
+ metadata?: Record<string, unknown> | undefined;
1436
+ dateFormat?: "short" | "long" | "full" | "relative" | undefined;
1437
+ minDate?: string | undefined;
1438
+ maxDate?: string | undefined;
1439
+ }>;
1440
+ /**
1441
+ * Phone attribute config schema
1442
+ */
1443
+ declare const phoneConfigSchema: z.ZodObject<{
1444
+ disabled: z.ZodOptional<z.ZodBoolean>;
1445
+ placeholder: z.ZodOptional<z.ZodString>;
1446
+ description: z.ZodOptional<z.ZodString>;
1447
+ defaultValue: z.ZodOptional<z.ZodUnknown>;
1448
+ icon: z.ZodOptional<z.ZodString>;
1449
+ order: z.ZodOptional<z.ZodNumber>;
1450
+ hidden: z.ZodOptional<z.ZodBoolean>;
1451
+ archived: z.ZodOptional<z.ZodBoolean>;
1452
+ deprecated: z.ZodOptional<z.ZodBoolean>;
1453
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1454
+ } & {
1455
+ defaultCountryCode: z.ZodOptional<z.ZodString>;
1456
+ }, "strip", z.ZodTypeAny, {
1457
+ defaultValue?: unknown;
1458
+ disabled?: boolean | undefined;
1459
+ placeholder?: string | undefined;
1460
+ description?: string | undefined;
1461
+ icon?: string | undefined;
1462
+ order?: number | undefined;
1463
+ hidden?: boolean | undefined;
1464
+ archived?: boolean | undefined;
1465
+ deprecated?: boolean | undefined;
1466
+ metadata?: Record<string, unknown> | undefined;
1467
+ defaultCountryCode?: string | undefined;
1468
+ }, {
1469
+ defaultValue?: unknown;
1470
+ disabled?: boolean | undefined;
1471
+ placeholder?: string | undefined;
1472
+ description?: string | undefined;
1473
+ icon?: string | undefined;
1474
+ order?: number | undefined;
1475
+ hidden?: boolean | undefined;
1476
+ archived?: boolean | undefined;
1477
+ deprecated?: boolean | undefined;
1478
+ metadata?: Record<string, unknown> | undefined;
1479
+ defaultCountryCode?: string | undefined;
1480
+ }>;
1481
+ /**
1482
+ * Currency attribute config schema
1483
+ */
1484
+ declare const currencyConfigSchema: z.ZodObject<{
1485
+ disabled: z.ZodOptional<z.ZodBoolean>;
1486
+ placeholder: z.ZodOptional<z.ZodString>;
1487
+ description: z.ZodOptional<z.ZodString>;
1488
+ defaultValue: z.ZodOptional<z.ZodUnknown>;
1489
+ icon: z.ZodOptional<z.ZodString>;
1490
+ order: z.ZodOptional<z.ZodNumber>;
1491
+ hidden: z.ZodOptional<z.ZodBoolean>;
1492
+ archived: z.ZodOptional<z.ZodBoolean>;
1493
+ deprecated: z.ZodOptional<z.ZodBoolean>;
1494
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1495
+ } & {
1496
+ defaultCurrency: z.ZodOptional<z.ZodString>;
1497
+ allowedCurrencies: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
1498
+ }, "strip", z.ZodTypeAny, {
1499
+ defaultValue?: unknown;
1500
+ disabled?: boolean | undefined;
1501
+ placeholder?: string | undefined;
1502
+ description?: string | undefined;
1503
+ icon?: string | undefined;
1504
+ order?: number | undefined;
1505
+ hidden?: boolean | undefined;
1506
+ archived?: boolean | undefined;
1507
+ deprecated?: boolean | undefined;
1508
+ metadata?: Record<string, unknown> | undefined;
1509
+ defaultCurrency?: string | undefined;
1510
+ allowedCurrencies?: string[] | undefined;
1511
+ }, {
1512
+ defaultValue?: unknown;
1513
+ disabled?: boolean | undefined;
1514
+ placeholder?: string | undefined;
1515
+ description?: string | undefined;
1516
+ icon?: string | undefined;
1517
+ order?: number | undefined;
1518
+ hidden?: boolean | undefined;
1519
+ archived?: boolean | undefined;
1520
+ deprecated?: boolean | undefined;
1521
+ metadata?: Record<string, unknown> | undefined;
1522
+ defaultCurrency?: string | undefined;
1523
+ allowedCurrencies?: string[] | undefined;
1524
+ }>;
1525
+ /**
1526
+ * Status attribute config schema
1527
+ */
1528
+ declare const statusConfigSchema: z.ZodObject<{
1529
+ disabled: z.ZodOptional<z.ZodBoolean>;
1530
+ placeholder: z.ZodOptional<z.ZodString>;
1531
+ description: z.ZodOptional<z.ZodString>;
1532
+ defaultValue: z.ZodOptional<z.ZodUnknown>;
1533
+ icon: z.ZodOptional<z.ZodString>;
1534
+ order: z.ZodOptional<z.ZodNumber>;
1535
+ hidden: z.ZodOptional<z.ZodBoolean>;
1536
+ archived: z.ZodOptional<z.ZodBoolean>;
1537
+ deprecated: z.ZodOptional<z.ZodBoolean>;
1538
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1539
+ } & {
1540
+ options: z.ZodArray<z.ZodObject<{
1541
+ id: z.ZodString;
1542
+ label: z.ZodString;
1543
+ value: z.ZodString;
1544
+ color: z.ZodOptional<z.ZodString>;
1545
+ icon: z.ZodOptional<z.ZodString>;
1546
+ description: z.ZodOptional<z.ZodString>;
1547
+ group: z.ZodOptional<z.ZodEnum<["idle", "in_progress", "finished"]>>;
1548
+ }, "strip", z.ZodTypeAny, {
1549
+ label: string;
1550
+ id: string;
1551
+ value: string;
1552
+ description?: string | undefined;
1553
+ icon?: string | undefined;
1554
+ color?: string | undefined;
1555
+ group?: "idle" | "in_progress" | "finished" | undefined;
1556
+ }, {
1557
+ label: string;
1558
+ id: string;
1559
+ value: string;
1560
+ description?: string | undefined;
1561
+ icon?: string | undefined;
1562
+ color?: string | undefined;
1563
+ group?: "idle" | "in_progress" | "finished" | undefined;
1564
+ }>, "many">;
1565
+ }, "strip", z.ZodTypeAny, {
1566
+ options: {
1567
+ label: string;
1568
+ id: string;
1569
+ value: string;
1570
+ description?: string | undefined;
1571
+ icon?: string | undefined;
1572
+ color?: string | undefined;
1573
+ group?: "idle" | "in_progress" | "finished" | undefined;
1574
+ }[];
1575
+ defaultValue?: unknown;
1576
+ disabled?: boolean | undefined;
1577
+ placeholder?: string | undefined;
1578
+ description?: string | undefined;
1579
+ icon?: string | undefined;
1580
+ order?: number | undefined;
1581
+ hidden?: boolean | undefined;
1582
+ archived?: boolean | undefined;
1583
+ deprecated?: boolean | undefined;
1584
+ metadata?: Record<string, unknown> | undefined;
1585
+ }, {
1586
+ options: {
1587
+ label: string;
1588
+ id: string;
1589
+ value: string;
1590
+ description?: string | undefined;
1591
+ icon?: string | undefined;
1592
+ color?: string | undefined;
1593
+ group?: "idle" | "in_progress" | "finished" | undefined;
1594
+ }[];
1595
+ defaultValue?: unknown;
1596
+ disabled?: boolean | undefined;
1597
+ placeholder?: string | undefined;
1598
+ description?: string | undefined;
1599
+ icon?: string | undefined;
1600
+ order?: number | undefined;
1601
+ hidden?: boolean | undefined;
1602
+ archived?: boolean | undefined;
1603
+ deprecated?: boolean | undefined;
1604
+ metadata?: Record<string, unknown> | undefined;
1605
+ }>;
1606
+ /**
1607
+ * Location attribute config schema
1608
+ */
1609
+ declare const locationConfigSchema: z.ZodObject<{
1610
+ disabled: z.ZodOptional<z.ZodBoolean>;
1611
+ placeholder: z.ZodOptional<z.ZodString>;
1612
+ description: z.ZodOptional<z.ZodString>;
1613
+ defaultValue: z.ZodOptional<z.ZodUnknown>;
1614
+ icon: z.ZodOptional<z.ZodString>;
1615
+ order: z.ZodOptional<z.ZodNumber>;
1616
+ hidden: z.ZodOptional<z.ZodBoolean>;
1617
+ archived: z.ZodOptional<z.ZodBoolean>;
1618
+ deprecated: z.ZodOptional<z.ZodBoolean>;
1619
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1620
+ } & {
1621
+ granularity: z.ZodEnum<["full", "address", "city", "state", "country", "coordinates"]>;
1622
+ enableAutocomplete: z.ZodOptional<z.ZodBoolean>;
1623
+ enableMap: z.ZodOptional<z.ZodBoolean>;
1624
+ defaultCountry: z.ZodOptional<z.ZodString>;
1625
+ allowedCountries: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
1626
+ displayFormat: z.ZodOptional<z.ZodEnum<["single_line", "multi_line", "compact"]>>;
1627
+ }, "strip", z.ZodTypeAny, {
1628
+ granularity: "full" | "address" | "city" | "state" | "country" | "coordinates";
1629
+ defaultValue?: unknown;
1630
+ disabled?: boolean | undefined;
1631
+ placeholder?: string | undefined;
1632
+ description?: string | undefined;
1633
+ icon?: string | undefined;
1634
+ order?: number | undefined;
1635
+ hidden?: boolean | undefined;
1636
+ archived?: boolean | undefined;
1637
+ deprecated?: boolean | undefined;
1638
+ metadata?: Record<string, unknown> | undefined;
1639
+ enableAutocomplete?: boolean | undefined;
1640
+ enableMap?: boolean | undefined;
1641
+ defaultCountry?: string | undefined;
1642
+ allowedCountries?: string[] | undefined;
1643
+ displayFormat?: "single_line" | "multi_line" | "compact" | undefined;
1644
+ }, {
1645
+ granularity: "full" | "address" | "city" | "state" | "country" | "coordinates";
1646
+ defaultValue?: unknown;
1647
+ disabled?: boolean | undefined;
1648
+ placeholder?: string | undefined;
1649
+ description?: string | undefined;
1650
+ icon?: string | undefined;
1651
+ order?: number | undefined;
1652
+ hidden?: boolean | undefined;
1653
+ archived?: boolean | undefined;
1654
+ deprecated?: boolean | undefined;
1655
+ metadata?: Record<string, unknown> | undefined;
1656
+ enableAutocomplete?: boolean | undefined;
1657
+ enableMap?: boolean | undefined;
1658
+ defaultCountry?: string | undefined;
1659
+ allowedCountries?: string[] | undefined;
1660
+ displayFormat?: "single_line" | "multi_line" | "compact" | undefined;
1661
+ }>;
1662
+ /**
1663
+ * Timestamp attribute config schema
1664
+ */
1665
+ declare const timestampConfigSchema: z.ZodObject<{
1666
+ disabled: z.ZodOptional<z.ZodBoolean>;
1667
+ placeholder: z.ZodOptional<z.ZodString>;
1668
+ description: z.ZodOptional<z.ZodString>;
1669
+ defaultValue: z.ZodOptional<z.ZodUnknown>;
1670
+ icon: z.ZodOptional<z.ZodString>;
1671
+ order: z.ZodOptional<z.ZodNumber>;
1672
+ hidden: z.ZodOptional<z.ZodBoolean>;
1673
+ archived: z.ZodOptional<z.ZodBoolean>;
1674
+ deprecated: z.ZodOptional<z.ZodBoolean>;
1675
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1676
+ } & {
1677
+ autoUpdate: z.ZodOptional<z.ZodBoolean>;
1678
+ }, "strip", z.ZodTypeAny, {
1679
+ defaultValue?: unknown;
1680
+ disabled?: boolean | undefined;
1681
+ placeholder?: string | undefined;
1682
+ description?: string | undefined;
1683
+ icon?: string | undefined;
1684
+ order?: number | undefined;
1685
+ hidden?: boolean | undefined;
1686
+ archived?: boolean | undefined;
1687
+ deprecated?: boolean | undefined;
1688
+ metadata?: Record<string, unknown> | undefined;
1689
+ autoUpdate?: boolean | undefined;
1690
+ }, {
1691
+ defaultValue?: unknown;
1692
+ disabled?: boolean | undefined;
1693
+ placeholder?: string | undefined;
1694
+ description?: string | undefined;
1695
+ icon?: string | undefined;
1696
+ order?: number | undefined;
1697
+ hidden?: boolean | undefined;
1698
+ archived?: boolean | undefined;
1699
+ deprecated?: boolean | undefined;
1700
+ metadata?: Record<string, unknown> | undefined;
1701
+ autoUpdate?: boolean | undefined;
1702
+ }>;
1703
+ /**
1704
+ * Select attribute config schema
1705
+ */
1706
+ declare const selectConfigSchema: z.ZodObject<{
1707
+ disabled: z.ZodOptional<z.ZodBoolean>;
1708
+ placeholder: z.ZodOptional<z.ZodString>;
1709
+ description: z.ZodOptional<z.ZodString>;
1710
+ defaultValue: z.ZodOptional<z.ZodUnknown>;
1711
+ icon: z.ZodOptional<z.ZodString>;
1712
+ order: z.ZodOptional<z.ZodNumber>;
1713
+ hidden: z.ZodOptional<z.ZodBoolean>;
1714
+ archived: z.ZodOptional<z.ZodBoolean>;
1715
+ deprecated: z.ZodOptional<z.ZodBoolean>;
1716
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1717
+ } & {
1718
+ options: z.ZodArray<z.ZodObject<{
1719
+ id: z.ZodString;
1720
+ label: z.ZodString;
1721
+ value: z.ZodString;
1722
+ color: z.ZodOptional<z.ZodString>;
1723
+ icon: z.ZodOptional<z.ZodString>;
1724
+ description: z.ZodOptional<z.ZodString>;
1725
+ group: z.ZodOptional<z.ZodEnum<["idle", "in_progress", "finished"]>>;
1726
+ }, "strip", z.ZodTypeAny, {
1727
+ label: string;
1728
+ id: string;
1729
+ value: string;
1730
+ description?: string | undefined;
1731
+ icon?: string | undefined;
1732
+ color?: string | undefined;
1733
+ group?: "idle" | "in_progress" | "finished" | undefined;
1734
+ }, {
1735
+ label: string;
1736
+ id: string;
1737
+ value: string;
1738
+ description?: string | undefined;
1739
+ icon?: string | undefined;
1740
+ color?: string | undefined;
1741
+ group?: "idle" | "in_progress" | "finished" | undefined;
1742
+ }>, "many">;
1743
+ }, "strip", z.ZodTypeAny, {
1744
+ options: {
1745
+ label: string;
1746
+ id: string;
1747
+ value: string;
1748
+ description?: string | undefined;
1749
+ icon?: string | undefined;
1750
+ color?: string | undefined;
1751
+ group?: "idle" | "in_progress" | "finished" | undefined;
1752
+ }[];
1753
+ defaultValue?: unknown;
1754
+ disabled?: boolean | undefined;
1755
+ placeholder?: string | undefined;
1756
+ description?: string | undefined;
1757
+ icon?: string | undefined;
1758
+ order?: number | undefined;
1759
+ hidden?: boolean | undefined;
1760
+ archived?: boolean | undefined;
1761
+ deprecated?: boolean | undefined;
1762
+ metadata?: Record<string, unknown> | undefined;
1763
+ }, {
1764
+ options: {
1765
+ label: string;
1766
+ id: string;
1767
+ value: string;
1768
+ description?: string | undefined;
1769
+ icon?: string | undefined;
1770
+ color?: string | undefined;
1771
+ group?: "idle" | "in_progress" | "finished" | undefined;
1772
+ }[];
1773
+ defaultValue?: unknown;
1774
+ disabled?: boolean | undefined;
1775
+ placeholder?: string | undefined;
1776
+ description?: string | undefined;
1777
+ icon?: string | undefined;
1778
+ order?: number | undefined;
1779
+ hidden?: boolean | undefined;
1780
+ archived?: boolean | undefined;
1781
+ deprecated?: boolean | undefined;
1782
+ metadata?: Record<string, unknown> | undefined;
1783
+ }>;
1784
+ /**
1785
+ * Multiselect attribute config schema
1786
+ */
1787
+ declare const multiselectConfigSchema: z.ZodObject<{
1788
+ disabled: z.ZodOptional<z.ZodBoolean>;
1789
+ placeholder: z.ZodOptional<z.ZodString>;
1790
+ description: z.ZodOptional<z.ZodString>;
1791
+ defaultValue: z.ZodOptional<z.ZodUnknown>;
1792
+ icon: z.ZodOptional<z.ZodString>;
1793
+ order: z.ZodOptional<z.ZodNumber>;
1794
+ hidden: z.ZodOptional<z.ZodBoolean>;
1795
+ archived: z.ZodOptional<z.ZodBoolean>;
1796
+ deprecated: z.ZodOptional<z.ZodBoolean>;
1797
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1798
+ } & {
1799
+ options: z.ZodArray<z.ZodObject<{
1800
+ id: z.ZodString;
1801
+ label: z.ZodString;
1802
+ value: z.ZodString;
1803
+ color: z.ZodOptional<z.ZodString>;
1804
+ icon: z.ZodOptional<z.ZodString>;
1805
+ description: z.ZodOptional<z.ZodString>;
1806
+ group: z.ZodOptional<z.ZodEnum<["idle", "in_progress", "finished"]>>;
1807
+ }, "strip", z.ZodTypeAny, {
1808
+ label: string;
1809
+ id: string;
1810
+ value: string;
1811
+ description?: string | undefined;
1812
+ icon?: string | undefined;
1813
+ color?: string | undefined;
1814
+ group?: "idle" | "in_progress" | "finished" | undefined;
1815
+ }, {
1816
+ label: string;
1817
+ id: string;
1818
+ value: string;
1819
+ description?: string | undefined;
1820
+ icon?: string | undefined;
1821
+ color?: string | undefined;
1822
+ group?: "idle" | "in_progress" | "finished" | undefined;
1823
+ }>, "many">;
1824
+ }, "strip", z.ZodTypeAny, {
1825
+ options: {
1826
+ label: string;
1827
+ id: string;
1828
+ value: string;
1829
+ description?: string | undefined;
1830
+ icon?: string | undefined;
1831
+ color?: string | undefined;
1832
+ group?: "idle" | "in_progress" | "finished" | undefined;
1833
+ }[];
1834
+ defaultValue?: unknown;
1835
+ disabled?: boolean | undefined;
1836
+ placeholder?: string | undefined;
1837
+ description?: string | undefined;
1838
+ icon?: string | undefined;
1839
+ order?: number | undefined;
1840
+ hidden?: boolean | undefined;
1841
+ archived?: boolean | undefined;
1842
+ deprecated?: boolean | undefined;
1843
+ metadata?: Record<string, unknown> | undefined;
1844
+ }, {
1845
+ options: {
1846
+ label: string;
1847
+ id: string;
1848
+ value: string;
1849
+ description?: string | undefined;
1850
+ icon?: string | undefined;
1851
+ color?: string | undefined;
1852
+ group?: "idle" | "in_progress" | "finished" | undefined;
1853
+ }[];
1854
+ defaultValue?: unknown;
1855
+ disabled?: boolean | undefined;
1856
+ placeholder?: string | undefined;
1857
+ description?: string | undefined;
1858
+ icon?: string | undefined;
1859
+ order?: number | undefined;
1860
+ hidden?: boolean | undefined;
1861
+ archived?: boolean | undefined;
1862
+ deprecated?: boolean | undefined;
1863
+ metadata?: Record<string, unknown> | undefined;
1864
+ }>;
1865
+ /**
1866
+ * File attribute config schema
1867
+ */
1868
+ declare const fileConfigSchema: z.ZodObject<{
1869
+ disabled: z.ZodOptional<z.ZodBoolean>;
1870
+ placeholder: z.ZodOptional<z.ZodString>;
1871
+ description: z.ZodOptional<z.ZodString>;
1872
+ defaultValue: z.ZodOptional<z.ZodUnknown>;
1873
+ icon: z.ZodOptional<z.ZodString>;
1874
+ order: z.ZodOptional<z.ZodNumber>;
1875
+ hidden: z.ZodOptional<z.ZodBoolean>;
1876
+ archived: z.ZodOptional<z.ZodBoolean>;
1877
+ deprecated: z.ZodOptional<z.ZodBoolean>;
1878
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1879
+ } & {
1880
+ maxFiles: z.ZodOptional<z.ZodNumber>;
1881
+ maxSize: z.ZodOptional<z.ZodNumber>;
1882
+ allowedTypes: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
1883
+ verification: z.ZodOptional<z.ZodObject<{
1884
+ enabled: z.ZodBoolean;
1885
+ documentTypes: z.ZodArray<z.ZodObject<{
1886
+ type: z.ZodEnum<["id_card", "passport", "incorporation_certificate", "driver_license", "birth_certificate", "residence_permit", "bank_statement", "proof_of_address", "custom"]>;
1887
+ label: z.ZodString;
1888
+ faces: z.ZodArray<z.ZodEnum<["front", "back", "single"]>, "many">;
1889
+ attributeMapping: z.ZodOptional<z.ZodArray<z.ZodObject<{
1890
+ attributeId: z.ZodString;
1891
+ extractedKey: z.ZodString;
1892
+ face: z.ZodOptional<z.ZodEnum<["front", "back", "single"]>>;
1893
+ required: z.ZodOptional<z.ZodBoolean>;
1894
+ }, "strip", z.ZodTypeAny, {
1895
+ attributeId: string;
1896
+ extractedKey: string;
1897
+ required?: boolean | undefined;
1898
+ face?: "front" | "back" | "single" | undefined;
1899
+ }, {
1900
+ attributeId: string;
1901
+ extractedKey: string;
1902
+ required?: boolean | undefined;
1903
+ face?: "front" | "back" | "single" | undefined;
1904
+ }>, "many">>;
1905
+ }, "strip", z.ZodTypeAny, {
1906
+ label: string;
1907
+ type: "id_card" | "passport" | "incorporation_certificate" | "driver_license" | "birth_certificate" | "residence_permit" | "bank_statement" | "proof_of_address" | "custom";
1908
+ faces: ("front" | "back" | "single")[];
1909
+ attributeMapping?: {
1910
+ attributeId: string;
1911
+ extractedKey: string;
1912
+ required?: boolean | undefined;
1913
+ face?: "front" | "back" | "single" | undefined;
1914
+ }[] | undefined;
1915
+ }, {
1916
+ label: string;
1917
+ type: "id_card" | "passport" | "incorporation_certificate" | "driver_license" | "birth_certificate" | "residence_permit" | "bank_statement" | "proof_of_address" | "custom";
1918
+ faces: ("front" | "back" | "single")[];
1919
+ attributeMapping?: {
1920
+ attributeId: string;
1921
+ extractedKey: string;
1922
+ required?: boolean | undefined;
1923
+ face?: "front" | "back" | "single" | undefined;
1924
+ }[] | undefined;
1925
+ }>, "many">;
1926
+ autoExtract: z.ZodOptional<z.ZodBoolean>;
1927
+ autoValidate: z.ZodOptional<z.ZodBoolean>;
1928
+ }, "strip", z.ZodTypeAny, {
1929
+ enabled: boolean;
1930
+ documentTypes: {
1931
+ label: string;
1932
+ type: "id_card" | "passport" | "incorporation_certificate" | "driver_license" | "birth_certificate" | "residence_permit" | "bank_statement" | "proof_of_address" | "custom";
1933
+ faces: ("front" | "back" | "single")[];
1934
+ attributeMapping?: {
1935
+ attributeId: string;
1936
+ extractedKey: string;
1937
+ required?: boolean | undefined;
1938
+ face?: "front" | "back" | "single" | undefined;
1939
+ }[] | undefined;
1940
+ }[];
1941
+ autoExtract?: boolean | undefined;
1942
+ autoValidate?: boolean | undefined;
1943
+ }, {
1944
+ enabled: boolean;
1945
+ documentTypes: {
1946
+ label: string;
1947
+ type: "id_card" | "passport" | "incorporation_certificate" | "driver_license" | "birth_certificate" | "residence_permit" | "bank_statement" | "proof_of_address" | "custom";
1948
+ faces: ("front" | "back" | "single")[];
1949
+ attributeMapping?: {
1950
+ attributeId: string;
1951
+ extractedKey: string;
1952
+ required?: boolean | undefined;
1953
+ face?: "front" | "back" | "single" | undefined;
1954
+ }[] | undefined;
1955
+ }[];
1956
+ autoExtract?: boolean | undefined;
1957
+ autoValidate?: boolean | undefined;
1958
+ }>>;
1959
+ }, "strip", z.ZodTypeAny, {
1960
+ defaultValue?: unknown;
1961
+ disabled?: boolean | undefined;
1962
+ placeholder?: string | undefined;
1963
+ description?: string | undefined;
1964
+ icon?: string | undefined;
1965
+ order?: number | undefined;
1966
+ hidden?: boolean | undefined;
1967
+ archived?: boolean | undefined;
1968
+ deprecated?: boolean | undefined;
1969
+ metadata?: Record<string, unknown> | undefined;
1970
+ maxFiles?: number | undefined;
1971
+ maxSize?: number | undefined;
1972
+ allowedTypes?: string[] | undefined;
1973
+ verification?: {
1974
+ enabled: boolean;
1975
+ documentTypes: {
1976
+ label: string;
1977
+ type: "id_card" | "passport" | "incorporation_certificate" | "driver_license" | "birth_certificate" | "residence_permit" | "bank_statement" | "proof_of_address" | "custom";
1978
+ faces: ("front" | "back" | "single")[];
1979
+ attributeMapping?: {
1980
+ attributeId: string;
1981
+ extractedKey: string;
1982
+ required?: boolean | undefined;
1983
+ face?: "front" | "back" | "single" | undefined;
1984
+ }[] | undefined;
1985
+ }[];
1986
+ autoExtract?: boolean | undefined;
1987
+ autoValidate?: boolean | undefined;
1988
+ } | undefined;
1989
+ }, {
1990
+ defaultValue?: unknown;
1991
+ disabled?: boolean | undefined;
1992
+ placeholder?: string | undefined;
1993
+ description?: string | undefined;
1994
+ icon?: string | undefined;
1995
+ order?: number | undefined;
1996
+ hidden?: boolean | undefined;
1997
+ archived?: boolean | undefined;
1998
+ deprecated?: boolean | undefined;
1999
+ metadata?: Record<string, unknown> | undefined;
2000
+ maxFiles?: number | undefined;
2001
+ maxSize?: number | undefined;
2002
+ allowedTypes?: string[] | undefined;
2003
+ verification?: {
2004
+ enabled: boolean;
2005
+ documentTypes: {
2006
+ label: string;
2007
+ type: "id_card" | "passport" | "incorporation_certificate" | "driver_license" | "birth_certificate" | "residence_permit" | "bank_statement" | "proof_of_address" | "custom";
2008
+ faces: ("front" | "back" | "single")[];
2009
+ attributeMapping?: {
2010
+ attributeId: string;
2011
+ extractedKey: string;
2012
+ required?: boolean | undefined;
2013
+ face?: "front" | "back" | "single" | undefined;
2014
+ }[] | undefined;
2015
+ }[];
2016
+ autoExtract?: boolean | undefined;
2017
+ autoValidate?: boolean | undefined;
2018
+ } | undefined;
2019
+ }>;
2020
+ /**
2021
+ * User attribute config schema
2022
+ */
2023
+ declare const userConfigSchema: z.ZodObject<{
2024
+ disabled: z.ZodOptional<z.ZodBoolean>;
2025
+ placeholder: z.ZodOptional<z.ZodString>;
2026
+ description: z.ZodOptional<z.ZodString>;
2027
+ defaultValue: z.ZodOptional<z.ZodUnknown>;
2028
+ icon: z.ZodOptional<z.ZodString>;
2029
+ order: z.ZodOptional<z.ZodNumber>;
2030
+ hidden: z.ZodOptional<z.ZodBoolean>;
2031
+ archived: z.ZodOptional<z.ZodBoolean>;
2032
+ deprecated: z.ZodOptional<z.ZodBoolean>;
2033
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
2034
+ } & {
2035
+ allowedRoles: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
2036
+ }, "strip", z.ZodTypeAny, {
2037
+ defaultValue?: unknown;
2038
+ disabled?: boolean | undefined;
2039
+ placeholder?: string | undefined;
2040
+ description?: string | undefined;
2041
+ icon?: string | undefined;
2042
+ order?: number | undefined;
2043
+ hidden?: boolean | undefined;
2044
+ archived?: boolean | undefined;
2045
+ deprecated?: boolean | undefined;
2046
+ metadata?: Record<string, unknown> | undefined;
2047
+ allowedRoles?: string[] | undefined;
2048
+ }, {
2049
+ defaultValue?: unknown;
2050
+ disabled?: boolean | undefined;
2051
+ placeholder?: string | undefined;
2052
+ description?: string | undefined;
2053
+ icon?: string | undefined;
2054
+ order?: number | undefined;
2055
+ hidden?: boolean | undefined;
2056
+ archived?: boolean | undefined;
2057
+ deprecated?: boolean | undefined;
2058
+ metadata?: Record<string, unknown> | undefined;
2059
+ allowedRoles?: string[] | undefined;
2060
+ }>;
2061
+ /**
2062
+ * Relation attribute config schema
2063
+ */
2064
+ declare const relationConfigSchema: z.ZodObject<{
2065
+ disabled: z.ZodOptional<z.ZodBoolean>;
2066
+ placeholder: z.ZodOptional<z.ZodString>;
2067
+ description: z.ZodOptional<z.ZodString>;
2068
+ defaultValue: z.ZodOptional<z.ZodUnknown>;
2069
+ icon: z.ZodOptional<z.ZodString>;
2070
+ order: z.ZodOptional<z.ZodNumber>;
2071
+ hidden: z.ZodOptional<z.ZodBoolean>;
2072
+ archived: z.ZodOptional<z.ZodBoolean>;
2073
+ deprecated: z.ZodOptional<z.ZodBoolean>;
2074
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
2075
+ } & {
2076
+ targets: z.ZodArray<z.ZodObject<{
2077
+ object: z.ZodString;
2078
+ displayTemplate: z.ZodOptional<z.ZodString>;
2079
+ filter: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
2080
+ }, "strip", z.ZodTypeAny, {
2081
+ object: string;
2082
+ filter?: Record<string, unknown> | undefined;
2083
+ displayTemplate?: string | undefined;
2084
+ }, {
2085
+ object: string;
2086
+ filter?: Record<string, unknown> | undefined;
2087
+ displayTemplate?: string | undefined;
2088
+ }>, "many">;
2089
+ onDelete: z.ZodOptional<z.ZodEnum<["restrict", "cascade", "set_null"]>>;
2090
+ cardinality: z.ZodEnum<["one", "many"]>;
2091
+ minItems: z.ZodOptional<z.ZodNumber>;
2092
+ maxItems: z.ZodOptional<z.ZodNumber>;
2093
+ }, "strip", z.ZodTypeAny, {
2094
+ cardinality: "one" | "many";
2095
+ targets: {
2096
+ object: string;
2097
+ filter?: Record<string, unknown> | undefined;
2098
+ displayTemplate?: string | undefined;
2099
+ }[];
2100
+ defaultValue?: unknown;
2101
+ disabled?: boolean | undefined;
2102
+ placeholder?: string | undefined;
2103
+ description?: string | undefined;
2104
+ icon?: string | undefined;
2105
+ order?: number | undefined;
2106
+ hidden?: boolean | undefined;
2107
+ archived?: boolean | undefined;
2108
+ deprecated?: boolean | undefined;
2109
+ metadata?: Record<string, unknown> | undefined;
2110
+ onDelete?: "restrict" | "cascade" | "set_null" | undefined;
2111
+ minItems?: number | undefined;
2112
+ maxItems?: number | undefined;
2113
+ }, {
2114
+ cardinality: "one" | "many";
2115
+ targets: {
2116
+ object: string;
2117
+ filter?: Record<string, unknown> | undefined;
2118
+ displayTemplate?: string | undefined;
2119
+ }[];
2120
+ defaultValue?: unknown;
2121
+ disabled?: boolean | undefined;
2122
+ placeholder?: string | undefined;
2123
+ description?: string | undefined;
2124
+ icon?: string | undefined;
2125
+ order?: number | undefined;
2126
+ hidden?: boolean | undefined;
2127
+ archived?: boolean | undefined;
2128
+ deprecated?: boolean | undefined;
2129
+ metadata?: Record<string, unknown> | undefined;
2130
+ onDelete?: "restrict" | "cascade" | "set_null" | undefined;
2131
+ minItems?: number | undefined;
2132
+ maxItems?: number | undefined;
2133
+ }>;
2134
+ /**
2135
+ * Rating attribute config schema
2136
+ */
2137
+ declare const ratingConfigSchema: z.ZodObject<{
2138
+ disabled: z.ZodOptional<z.ZodBoolean>;
2139
+ placeholder: z.ZodOptional<z.ZodString>;
2140
+ description: z.ZodOptional<z.ZodString>;
2141
+ defaultValue: z.ZodOptional<z.ZodUnknown>;
2142
+ icon: z.ZodOptional<z.ZodString>;
2143
+ order: z.ZodOptional<z.ZodNumber>;
2144
+ hidden: z.ZodOptional<z.ZodBoolean>;
2145
+ archived: z.ZodOptional<z.ZodBoolean>;
2146
+ deprecated: z.ZodOptional<z.ZodBoolean>;
2147
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
2148
+ } & {
2149
+ max: z.ZodOptional<z.ZodNumber>;
2150
+ iconType: z.ZodOptional<z.ZodEnum<["star", "heart", "thumbs", "number"]>>;
2151
+ }, "strip", z.ZodTypeAny, {
2152
+ defaultValue?: unknown;
2153
+ disabled?: boolean | undefined;
2154
+ placeholder?: string | undefined;
2155
+ description?: string | undefined;
2156
+ icon?: string | undefined;
2157
+ order?: number | undefined;
2158
+ hidden?: boolean | undefined;
2159
+ archived?: boolean | undefined;
2160
+ deprecated?: boolean | undefined;
2161
+ metadata?: Record<string, unknown> | undefined;
2162
+ max?: number | undefined;
2163
+ iconType?: "number" | "heart" | "star" | "thumbs" | undefined;
2164
+ }, {
2165
+ defaultValue?: unknown;
2166
+ disabled?: boolean | undefined;
2167
+ placeholder?: string | undefined;
2168
+ description?: string | undefined;
2169
+ icon?: string | undefined;
2170
+ order?: number | undefined;
2171
+ hidden?: boolean | undefined;
2172
+ archived?: boolean | undefined;
2173
+ deprecated?: boolean | undefined;
2174
+ metadata?: Record<string, unknown> | undefined;
2175
+ max?: number | undefined;
2176
+ iconType?: "number" | "heart" | "star" | "thumbs" | undefined;
2177
+ }>;
2178
+ /**
2179
+ * Map of attribute type to config schema
2180
+ */
2181
+ declare const attributeConfigSchemas: Record<AttributeType, z.ZodObject<z.ZodRawShape>>;
2182
+ /**
2183
+ * Get the config schema for a specific attribute type
2184
+ */
2185
+ declare function getAttributeConfigSchema(type: AttributeType): z.ZodObject<z.ZodRawShape>;
2186
+ /**
2187
+ * Validate attribute config for a specific type
2188
+ * Returns the validated config with only allowed properties
2189
+ */
2190
+ declare function validateAttributeConfig(type: AttributeType, config: Record<string, unknown>): {
2191
+ success: true;
2192
+ data: Record<string, unknown>;
2193
+ } | {
2194
+ success: false;
2195
+ errors: string[];
2196
+ };
2197
+ /**
2198
+ * Validate and strip unknown properties from attribute config
2199
+ * This ensures only allowed properties are stored in the database
2200
+ */
2201
+ declare function parseAttributeConfig(type: AttributeType, config: Record<string, unknown>): Record<string, unknown>;
2202
+ /**
2203
+ * Safely parse attribute config, returning undefined for invalid configs
2204
+ */
2205
+ declare function safeParseAttributeConfig(type: AttributeType, config: Record<string, unknown>): Record<string, unknown> | undefined;
2206
+ /**
2207
+ * Create a Zod schema for a text attribute
2208
+ */
2209
+ declare function createTextValidator(attr: TextAttribute): z.ZodString;
2210
+ /**
2211
+ * Create a Zod schema for a number attribute
2212
+ */
2213
+ declare function createNumberValidator(attr: NumberAttribute): z.ZodNumber;
2214
+ /**
2215
+ * Create a Zod schema for a checkbox attribute
2216
+ */
2217
+ declare function createCheckboxValidator(_attr: CheckboxAttribute): z.ZodBoolean;
2218
+ /**
2219
+ * Create a Zod schema for a date attribute
2220
+ */
2221
+ declare function createDateValidator(attr: DateAttribute): z.ZodString;
2222
+ /**
2223
+ * Create a Zod schema for a phone attribute
2224
+ */
2225
+ declare function createPhoneValidator(_attr: PhoneAttribute): z.ZodType<{
2226
+ countryCode: string;
2227
+ phoneNumber: string;
2228
+ }>;
2229
+ /**
2230
+ * Create a Zod schema for a currency attribute
2231
+ */
2232
+ declare function createCurrencyValidator(_attr: CurrencyAttribute): z.ZodType<{
2233
+ code: string;
2234
+ value: number;
2235
+ }>;
2236
+ /**
2237
+ * Create a Zod schema for a status attribute
2238
+ */
2239
+ declare function createStatusValidator(attr: StatusAttribute): z.ZodEnum<[string, ...string[]]>;
2240
+ /**
2241
+ * Create a Zod schema for a select attribute
2242
+ */
2243
+ declare function createSelectValidator(attr: SelectAttribute): z.ZodEnum<[string, ...string[]]>;
2244
+ /**
2245
+ * Create a Zod schema for a multiselect attribute
2246
+ */
2247
+ declare function createMultiselectValidator(attr: MultiselectAttribute): z.ZodArray<z.ZodEnum<[string, ...string[]]>>;
2248
+ /**
2249
+ * Create a Zod schema for a location attribute
2250
+ */
2251
+ type LocationShape = {
2252
+ address?: string;
2253
+ address2?: string;
2254
+ city?: string;
2255
+ state?: string;
2256
+ postalCode?: string;
2257
+ country?: string;
2258
+ latitude?: number;
2259
+ longitude?: number;
2260
+ };
2261
+ declare function createLocationValidator(_attr: LocationAttribute): z.ZodType<LocationShape>;
2262
+ /**
2263
+ * Create a Zod schema for a timestamp attribute
2264
+ */
2265
+ declare function createTimestampValidator(_attr: TimestampAttribute): z.ZodNumber;
2266
+ /**
2267
+ * Create a Zod schema for a file attribute
2268
+ */
2269
+ declare function createFileValidator(_attr: FileAttribute): z.ZodString;
2270
+ /**
2271
+ * Create a Zod schema for a user attribute
2272
+ */
2273
+ declare function createUserValidator(_attr: UserAttribute): z.ZodString;
2274
+ /**
2275
+ * Create a Zod schema for a single relation attribute (cardinality: "one")
2276
+ */
2277
+ declare function createSingleRelationValidator(attr: SingleRelationAttribute): z.ZodUnion<[z.ZodString, z.ZodNull]>;
2278
+ /**
2279
+ * Create a Zod schema for a multi relation attribute (cardinality: "many")
2280
+ */
2281
+ declare function createMultiRelationValidator(attr: MultiRelationAttribute): z.ZodArray<z.ZodString>;
2282
+ /**
2283
+ * Create a Zod schema for a relation attribute
2284
+ * Dispatches to single or multi validator based on cardinality
2285
+ */
2286
+ declare function createRelationValidator(attr: RelationAttribute): z.ZodUnion<[z.ZodString, z.ZodNull]> | z.ZodArray<z.ZodString>;
2287
+ /**
2288
+ * Create a Zod schema for a rating attribute
2289
+ */
2290
+ declare function createRatingValidator(attr: RatingAttribute): z.ZodNumber;
2291
+ /**
2292
+ * Create a Zod schema for any attribute type
2293
+ */
2294
+ declare function createAttributeValidator(attr: Attribute): z.ZodTypeAny;
2295
+ /**
2296
+ * Create a Zod schema for an entire object
2297
+ */
2298
+ declare function createObjectValidator(objectDef: ObjectDefinition): z.ZodType<Record<string, unknown>>;
2299
+ /**
2300
+ * Validation result
2301
+ */
2302
+ interface ValidationResult {
2303
+ success: boolean;
2304
+ data?: Record<string, unknown>;
2305
+ errors?: Array<{
2306
+ path: string[];
2307
+ message: string;
2308
+ }>;
2309
+ }
2310
+ /**
2311
+ * Validate data against an attribute schema
2312
+ */
2313
+ declare function validateAttribute(attr: Attribute, value: unknown): ValidationResult;
2314
+ /**
2315
+ * Validate data against an object schema
2316
+ */
2317
+ declare function validateObject(objectDef: ObjectDefinition, data: Record<string, unknown>): ValidationResult;
2318
+ /**
2319
+ * Validate and throw if invalid
2320
+ */
2321
+ declare function validateObjectOrThrow(objectDef: ObjectDefinition, data: Record<string, unknown>): Record<string, unknown>;
2322
+ /**
2323
+ * Create a Zod schema for draft validation.
2324
+ * All attributes become optional, but provided values are still validated.
2325
+ */
2326
+ declare function createDraftValidator(objectDef: ObjectDefinition): z.ZodType<Record<string, unknown>>;
2327
+ /**
2328
+ * Validate data in draft mode.
2329
+ * - All attributes are treated as optional (no required validation)
2330
+ * - Provided values are still validated for format/type correctness
2331
+ *
2332
+ * Use this when creating records that may be incomplete (drafts).
2333
+ *
2334
+ * @example
2335
+ * ```typescript
2336
+ * const result = validateDraft(PRODUCT, { name: "Draft" });
2337
+ * // → success even if "price" is required but missing
2338
+ *
2339
+ * const result2 = validateDraft(PRODUCT, { price: -10 });
2340
+ * // → fails because price must be >= 0 (format validation still applies)
2341
+ * ```
2342
+ */
2343
+ declare function validateDraft(objectDef: ObjectDefinition, data: Record<string, unknown>): ValidationResult;
2344
+ /**
2345
+ * Validate draft data and throw if format validation fails.
2346
+ */
2347
+ declare function validateDraftOrThrow(objectDef: ObjectDefinition, data: Record<string, unknown>): Record<string, unknown>;
2348
+ /**
2349
+ * Get the list of required attributes that are missing values.
2350
+ *
2351
+ * @example
2352
+ * ```typescript
2353
+ * const missing = getMissingRequiredAttributes(PRODUCT, { name: "Test" });
2354
+ * // → [priceAttribute, statusAttribute] if price and status are required but missing
2355
+ * ```
2356
+ */
2357
+ declare function getMissingRequiredAttributes(objectDef: ObjectDefinition, data: Record<string, unknown>): Attribute[];
2358
+ /**
2359
+ * Check if a record is complete (all required attributes have valid values).
2360
+ *
2361
+ * @returns `true` if all required values are present and valid, `false` otherwise
2362
+ */
2363
+ declare function isRecordComplete(objectDef: ObjectDefinition, data: Record<string, unknown>): boolean;
2364
+ /**
2365
+ * Compute the completion status of a record based on its data.
2366
+ *
2367
+ * - `"complete"`: All required values are present and valid
2368
+ * - `"draft"`: One or more required values are missing or invalid
2369
+ *
2370
+ * This function is used to dynamically determine the status when
2371
+ * creating or updating records.
2372
+ *
2373
+ * @example
2374
+ * ```typescript
2375
+ * const status = computeRecordStatus(PRODUCT, {
2376
+ * name: "Nike Air Max",
2377
+ * price: 129.99,
2378
+ * status: "active"
2379
+ * });
2380
+ * // → "complete"
2381
+ *
2382
+ * const status2 = computeRecordStatus(PRODUCT, { name: "Draft Product" });
2383
+ * // → "draft" (missing required fields)
2384
+ * ```
2385
+ */
2386
+ declare function computeRecordStatus(objectDef: ObjectDefinition, data: Record<string, unknown>): CompletionStatus;
2387
+
2388
+ /**
2389
+ * Object as stored in database (metadata)
2390
+ */
2391
+ interface DBObject extends Timestamps {
2392
+ id: Uuid;
2393
+ tenantId: TenantId;
2394
+ name: string;
2395
+ label: string;
2396
+ pluralLabel?: string;
2397
+ description?: string;
2398
+ icon?: IconName;
2399
+ labelExpression: string;
2400
+ system: boolean;
2401
+ metadata?: Record<string, unknown>;
2402
+ }
2403
+ interface CreateDBObject {
2404
+ tenantId: TenantId;
2405
+ name: string;
2406
+ label: string;
2407
+ pluralLabel?: string;
2408
+ description?: string;
2409
+ icon?: IconName;
2410
+ labelExpression: string;
2411
+ system?: boolean;
2412
+ metadata?: Record<string, unknown>;
2413
+ }
2414
+ interface UpdateDBObject {
2415
+ label?: string;
2416
+ pluralLabel?: string;
2417
+ description?: string;
2418
+ icon?: IconName;
2419
+ labelExpression?: string;
2420
+ metadata?: Record<string, unknown>;
2421
+ }
2422
+ interface UpsertDBObject extends CreateDBObject {
2423
+ system: boolean;
2424
+ }
2425
+ /**
2426
+ * Attribute as stored in database (metadata)
2427
+ */
2428
+ interface DBAttribute extends Timestamps {
2429
+ id: Uuid;
2430
+ objectId: Uuid;
2431
+ name: string;
2432
+ label: string;
2433
+ type: AttributeType;
2434
+ description?: string;
2435
+ icon?: IconName;
2436
+ system: boolean;
2437
+ required: boolean;
2438
+ unique: boolean;
2439
+ order: number;
2440
+ hidden?: boolean;
2441
+ archived?: boolean;
2442
+ deprecated?: boolean;
2443
+ defaultValue?: unknown;
2444
+ config: Record<string, unknown>;
2445
+ }
2446
+ interface CreateDBAttribute {
2447
+ objectId: Uuid;
2448
+ name: string;
2449
+ label: string;
2450
+ type: AttributeType;
2451
+ description?: string;
2452
+ icon?: IconName;
2453
+ system?: boolean;
2454
+ required?: boolean;
2455
+ unique?: boolean;
2456
+ order?: number;
2457
+ hidden?: boolean;
2458
+ archived?: boolean;
2459
+ deprecated?: boolean;
2460
+ defaultValue?: unknown;
2461
+ config?: Record<string, unknown>;
2462
+ }
2463
+ interface UpdateDBAttribute {
2464
+ label?: string;
2465
+ type?: AttributeType;
2466
+ description?: string;
2467
+ icon?: IconName;
2468
+ required?: boolean;
2469
+ order?: number;
2470
+ hidden?: boolean;
2471
+ archived?: boolean;
2472
+ deprecated?: boolean;
2473
+ defaultValue?: unknown;
2474
+ config?: Record<string, unknown>;
2475
+ }
2476
+ interface UpsertDBAttribute extends CreateDBAttribute {
2477
+ objectId: Uuid;
2478
+ name: string;
2479
+ }
2480
+
2481
+ /**
2482
+ * Object record creation data
2483
+ */
2484
+ interface CreateObjectRecord {
2485
+ tenantId: TenantId;
2486
+ objectId: Uuid;
2487
+ data: Record<string, unknown>;
2488
+ /**
2489
+ * Computed display label from labelExpression.
2490
+ * Stored for performance - avoids recomputation on every read.
2491
+ */
2492
+ label: string;
2493
+ /**
2494
+ * Completion status of the record.
2495
+ * - `draft`: Record is incomplete (missing required values)
2496
+ * - `complete`: All required values are present and valid
2497
+ */
2498
+ completionStatus: "draft" | "complete";
2499
+ }
2500
+ /**
2501
+ * Generic list options for pagination and sorting
2502
+ */
2503
+ interface ListOptions {
2504
+ limit?: number;
2505
+ offset?: number;
2506
+ /** @deprecated Use sorts instead */
2507
+ orderBy?: string;
2508
+ /** @deprecated Use sorts instead */
2509
+ orderDirection?: "asc" | "desc";
2510
+ /** Multiple sort rules */
2511
+ sorts?: SortRule[];
2512
+ /** Filter state */
2513
+ filters?: FilterState;
2514
+ }
2515
+ /**
2516
+ * Search options for full-text search
2517
+ */
2518
+ interface SearchOptions extends ListOptions {
2519
+ highlight?: boolean;
2520
+ }
2521
+ /**
2522
+ * Global search options
2523
+ */
2524
+ interface GlobalSearchOptions extends ListOptions {
2525
+ /**
2526
+ * Limit results to specific object names
2527
+ */
2528
+ objectNames?: string[];
2529
+ /**
2530
+ * Whether to include object metadata in results
2531
+ */
2532
+ includeObjectInfo?: boolean;
2533
+ }
2534
+ /**
2535
+ * Global search result item
2536
+ */
2537
+ interface GlobalSearchResultItem {
2538
+ objectId: string;
2539
+ objectName: string;
2540
+ objectLabel: string;
2541
+ /** Computed label from labelExpression */
2542
+ label: string;
2543
+ recordId: string;
2544
+ values: Record<string, unknown>;
2545
+ completionStatus: "draft" | "complete";
2546
+ createdAt: Date;
2547
+ updatedAt: Date;
2548
+ }
2549
+ /**
2550
+ * File-specific list options
2551
+ */
2552
+ interface FileListOptions extends ListOptions {
2553
+ folderPath?: string;
2554
+ mimeType?: string;
2555
+ uploadedBy?: Uuid;
2556
+ includeDeleted?: boolean;
2557
+ }
2558
+ /**
2559
+ * View as stored in database
2560
+ */
2561
+ interface DBView extends Timestamps {
2562
+ id: Uuid;
2563
+ tenantId: TenantId;
2564
+ objectId?: Uuid;
2565
+ objectName: string;
2566
+ name: string;
2567
+ label: string;
2568
+ description?: string;
2569
+ icon?: IconName;
2570
+ tabs: Tab[];
2571
+ default: boolean;
2572
+ system: boolean;
2573
+ metadata?: Record<string, unknown>;
2574
+ }
2575
+ interface CreateDBView {
2576
+ tenantId: TenantId;
2577
+ objectId?: Uuid;
2578
+ objectName: string;
2579
+ name: string;
2580
+ label: string;
2581
+ description?: string;
2582
+ icon?: IconName;
2583
+ tabs: Tab[];
2584
+ default?: boolean;
2585
+ system?: boolean;
2586
+ metadata?: Record<string, unknown>;
2587
+ }
2588
+ interface UpdateDBView {
2589
+ label?: string;
2590
+ description?: string;
2591
+ icon?: IconName;
2592
+ tabs?: Tab[];
2593
+ default?: boolean;
2594
+ metadata?: Record<string, unknown>;
2595
+ }
2596
+ interface UpsertDBView {
2597
+ tenantId: TenantId;
2598
+ objectName: string;
2599
+ name: string;
2600
+ label: string;
2601
+ description?: string;
2602
+ icon?: IconName;
2603
+ tabs: Tab[];
2604
+ default?: boolean;
2605
+ system?: boolean;
2606
+ metadata?: Record<string, unknown>;
2607
+ }
2608
+ /**
2609
+ * Result of an operation
2610
+ */
2611
+ interface OperationResult<T = unknown> {
2612
+ success: boolean;
2613
+ data?: T;
2614
+ error?: {
2615
+ code: string;
2616
+ message: string;
2617
+ details?: Record<string, unknown>;
2618
+ };
2619
+ }
2620
+
2621
+ /**
2622
+ * Repository for objects table (metadata)
2623
+ */
2624
+ interface ObjectsRepository {
2625
+ /**
2626
+ * Find object by ID
2627
+ */
2628
+ findById(id: Uuid): Promise<DBObject | null>;
2629
+ /**
2630
+ * Find object by name and tenant
2631
+ */
2632
+ findByName(tenantId: TenantId, name: string): Promise<DBObject | null>;
2633
+ /**
2634
+ * Find system/native object by name (system=true, for sync)
2635
+ */
2636
+ findSystemByName(name: string): Promise<DBObject | null>;
2637
+ /**
2638
+ * Create object
2639
+ */
2640
+ create(data: CreateDBObject): Promise<DBObject>;
2641
+ /**
2642
+ * Update object
2643
+ */
2644
+ update(id: Uuid, data: Partial<UpdateDBObject>): Promise<DBObject>;
2645
+ /**
2646
+ * Delete object
2647
+ */
2648
+ delete(id: Uuid): Promise<void>;
2649
+ /**
2650
+ * List all objects for a tenant
2651
+ */
2652
+ list(tenantId: TenantId): Promise<DBObject[]>;
2653
+ /**
2654
+ * Upsert object (create or update based on nativeObjectId)
2655
+ */
2656
+ upsert(data: UpsertDBObject): Promise<DBObject>;
2657
+ }
2658
+ /**
2659
+ * Repository for attributes table (metadata)
2660
+ */
2661
+ interface AttributesRepository {
2662
+ /**
2663
+ * Find attribute by ID
2664
+ */
2665
+ findById(id: Uuid): Promise<DBAttribute | null>;
2666
+ /**
2667
+ * Find attributes by object ID
2668
+ */
2669
+ findByObjectId(objectId: Uuid): Promise<DBAttribute[]>;
2670
+ /**
2671
+ * Create attribute
2672
+ */
2673
+ create(data: CreateDBAttribute): Promise<DBAttribute>;
2674
+ /**
2675
+ * Update attribute
2676
+ */
2677
+ update(id: Uuid, data: Partial<UpdateDBAttribute>): Promise<DBAttribute>;
2678
+ /**
2679
+ * Delete attribute
2680
+ */
2681
+ delete(id: Uuid): Promise<void>;
2682
+ /**
2683
+ * Delete multiple attributes by names (for sync cleanup)
2684
+ */
2685
+ deleteByNames(objectId: Uuid, excludeNames: string[]): Promise<number>;
2686
+ /**
2687
+ * Upsert attribute (create or update based on objectId + name)
2688
+ */
2689
+ upsert(data: UpsertDBAttribute): Promise<DBAttribute>;
2690
+ }
2691
+ /**
2692
+ * Repository for user_profiles table
2693
+ */
2694
+ interface UserProfilesRepository {
2695
+ /**
2696
+ * Find user profile by ID
2697
+ */
2698
+ findById(id: Uuid): Promise<UserProfile | null>;
2699
+ /**
2700
+ * Find user profile by auth ID (external auth provider)
2701
+ */
2702
+ findByAuthId(authId: string): Promise<UserProfile | null>;
2703
+ /**
2704
+ * Find user profile by email
2705
+ */
2706
+ findByEmail(tenantId: TenantId, email: string): Promise<UserProfile | null>;
2707
+ /**
2708
+ * Create user profile
2709
+ */
2710
+ create(data: CreateUserProfile): Promise<UserProfile>;
2711
+ /**
2712
+ * Update user profile
2713
+ */
2714
+ update(id: Uuid, data: UpdateUserProfile): Promise<UserProfile>;
2715
+ /**
2716
+ * Delete user profile
2717
+ */
2718
+ delete(id: Uuid): Promise<void>;
2719
+ /**
2720
+ * List all user profiles for a tenant
2721
+ */
2722
+ list(tenantId: TenantId, options?: ListOptions): Promise<UserProfile[]>;
2723
+ /**
2724
+ * Update last login timestamp
2725
+ */
2726
+ updateLastLogin(id: Uuid): Promise<void>;
2727
+ }
2728
+ /**
2729
+ * Repository for files table
2730
+ */
2731
+ interface FilesRepository {
2732
+ /**
2733
+ * Find file by ID
2734
+ */
2735
+ findById(id: Uuid): Promise<File | null>;
2736
+ /**
2737
+ * Create file
2738
+ */
2739
+ create(data: CreateFile): Promise<File>;
2740
+ /**
2741
+ * Update file
2742
+ */
2743
+ update(id: Uuid, data: UpdateFile): Promise<File>;
2744
+ /**
2745
+ * Delete file (soft delete)
2746
+ */
2747
+ delete(id: Uuid): Promise<void>;
2748
+ /**
2749
+ * Hard delete file (permanent)
2750
+ */
2751
+ hardDelete(id: Uuid): Promise<void>;
2752
+ /**
2753
+ * List files for a tenant
2754
+ */
2755
+ list(tenantId: TenantId, options?: FileListOptions): Promise<File[]>;
2756
+ /**
2757
+ * Find files by folder path
2758
+ */
2759
+ findByFolder(tenantId: TenantId, folderPath: string): Promise<File[]>;
2760
+ /**
2761
+ * Find files by uploader
2762
+ */
2763
+ findByUploader(uploadedBy: Uuid): Promise<File[]>;
2764
+ }
2765
+ /**
2766
+ * Repository for object_records table (unified JSONB)
2767
+ */
2768
+ interface ObjectRecordsRepository {
2769
+ /**
2770
+ * Find record by ID
2771
+ */
2772
+ findById(id: Uuid): Promise<ObjectRecord | null>;
2773
+ /**
2774
+ * Create record
2775
+ */
2776
+ create(data: CreateObjectRecord): Promise<ObjectRecord>;
2777
+ /**
2778
+ * Update record
2779
+ */
2780
+ update(id: Uuid, data: Partial<Record<string, unknown>>): Promise<ObjectRecord>;
2781
+ /**
2782
+ * Delete record
2783
+ */
2784
+ delete(id: Uuid): Promise<void>;
2785
+ /**
2786
+ * List records for an object
2787
+ */
2788
+ list(tenantId: TenantId, objectId: Uuid, options?: ListOptions): Promise<{
2789
+ records: ObjectRecord[];
2790
+ total: number;
2791
+ }>;
2792
+ /**
2793
+ * Search records using PostgreSQL full-text search
2794
+ */
2795
+ search(tenantId: TenantId, objectId: Uuid, query: string, options?: SearchOptions): Promise<{
2796
+ records: ObjectRecord[];
2797
+ total: number;
2798
+ }>;
2799
+ /**
2800
+ * Global search across all object records for a tenant
2801
+ * Searches in all objects or a subset specified by objectNames
2802
+ */
2803
+ globalSearch(tenantId: TenantId, query: string, options?: GlobalSearchOptions): Promise<{
2804
+ results: GlobalSearchResultItem[];
2805
+ total: number;
2806
+ }>;
2807
+ }
2808
+ /**
2809
+ * Repository for views table
2810
+ */
2811
+ interface ViewsRepository {
2812
+ /**
2813
+ * Find view by ID
2814
+ */
2815
+ findById(id: Uuid): Promise<DBView | null>;
2816
+ /**
2817
+ * Find view by name for an object and tenant
2818
+ */
2819
+ findByName(tenantId: TenantId, objectName: string, viewName: string): Promise<DBView | null>;
2820
+ /**
2821
+ * Find all views for an object and tenant
2822
+ */
2823
+ findByObjectName(tenantId: TenantId, objectName: string): Promise<DBView[]>;
2824
+ /**
2825
+ * Find all views for a tenant
2826
+ */
2827
+ findAllForTenant(tenantId: TenantId): Promise<DBView[]>;
2828
+ /**
2829
+ * Find system view by name (for sync)
2830
+ */
2831
+ findSystemByName(objectName: string, viewName: string): Promise<DBView | null>;
2832
+ /**
2833
+ * Find all system views for an object
2834
+ */
2835
+ findSystemByObjectName(objectName: string): Promise<DBView[]>;
2836
+ /**
2837
+ * Create view
2838
+ */
2839
+ create(data: CreateDBView): Promise<DBView>;
2840
+ /**
2841
+ * Update view
2842
+ */
2843
+ update(id: Uuid, data: Partial<UpdateDBView>): Promise<DBView>;
2844
+ /**
2845
+ * Delete view
2846
+ */
2847
+ delete(id: Uuid): Promise<void>;
2848
+ /**
2849
+ * Delete views not in the list (for sync cleanup)
2850
+ * @returns Number of deleted views
2851
+ */
2852
+ deleteNotIn(objectName: string, keepViewNames: string[]): Promise<number>;
2853
+ /**
2854
+ * Upsert view (create or update based on objectName + name)
2855
+ */
2856
+ upsert(data: UpsertDBView): Promise<DBView>;
2857
+ }
2858
+
2859
+ /**
2860
+ * Generic database adapter interface
2861
+ * Any ORM (Drizzle, Prisma, Kysely, TypeORM) can implement this interface
2862
+ * to work with @stndrds/schema runtime services
2863
+ *
2864
+ * @example
2865
+ * ```typescript
2866
+ * // Drizzle implementation
2867
+ * import { createDrizzleAdapter } from "./adapters/drizzle";
2868
+ * import { db } from "./db";
2869
+ *
2870
+ * const adapter = createDrizzleAdapter(db);
2871
+ *
2872
+ * // Prisma implementation
2873
+ * import { createPrismaAdapter } from "./adapters/prisma";
2874
+ * import { prisma } from "./db";
2875
+ *
2876
+ * const adapter = createPrismaAdapter(prisma);
2877
+ * ```
2878
+ */
2879
+ interface DatabaseAdapter {
2880
+ objects: ObjectsRepository;
2881
+ attributes: AttributesRepository;
2882
+ views: ViewsRepository;
2883
+ userProfiles: UserProfilesRepository;
2884
+ files: FilesRepository;
2885
+ objectRecords: ObjectRecordsRepository;
2886
+ transaction<T>(callback: (adapter: DatabaseAdapter) => Promise<T>): Promise<T>;
2887
+ }
2888
+
2889
+ /**
2890
+ * Types of hooks supported by the system
2891
+ */
2892
+ type HookType = "beforeCreate" | "afterCreate" | "beforeUpdate" | "afterUpdate" | "beforeDelete" | "afterDelete";
2893
+ /**
2894
+ * Change information for a specific attribute
2895
+ */
2896
+ interface AttributeChange<T = unknown> {
2897
+ oldValue: T | undefined;
2898
+ newValue: T | undefined;
2899
+ changed: boolean;
2900
+ }
2901
+ /**
2902
+ * Context passed to hooks - abstract, no framework dependencies
2903
+ *
2904
+ * This interface is designed to be extended by framework-specific implementations
2905
+ * (e.g., TriggerContext in schema-nestjs adds NestJS services)
2906
+ */
2907
+ interface HookContext<T = unknown> {
2908
+ objectId: string;
2909
+ objectName: string;
2910
+ recordId: string;
2911
+ tenantId: string;
2912
+ record: ObjectRecord;
2913
+ oldValues: Record<string, unknown>;
2914
+ newValues: Record<string, unknown>;
2915
+ changedAttributes: string[];
2916
+ /**
2917
+ * Get change information for a specific attribute
2918
+ * @param attributeName - The name of the attribute to check
2919
+ * @returns Change information including old value, new value, and whether it changed
2920
+ */
2921
+ getChange<V = T>(attributeName: string): AttributeChange<V>;
2922
+ metadata: Record<string, unknown>;
2923
+ timestamp: Date;
2924
+ }
2925
+ /**
2926
+ * Generic hook handler function
2927
+ */
2928
+ type HookHandler = (ctx: HookContext) => Promise<void> | void;
2929
+ /**
2930
+ * Definition of a hook for registration
2931
+ */
2932
+ interface HookDefinition {
2933
+ type: HookType;
2934
+ objectName: string;
2935
+ /** Attribute name to watch, or '*' for all attributes */
2936
+ attributeName?: string | "*";
2937
+ /** Execution priority (lower = earlier), default 0 */
2938
+ priority?: number;
2939
+ handler: HookHandler;
2940
+ }
2941
+
2942
+ /**
2943
+ * Abstract interface for hook registry
2944
+ *
2945
+ * This interface is implemented by TriggerRegistry in schema-nestjs
2946
+ * to provide NestJS-specific functionality like dependency injection
2947
+ * and automatic discovery of trigger classes.
2948
+ */
2949
+ interface HookRegistry {
2950
+ /**
2951
+ * Execute all hooks of a given type for an object
2952
+ *
2953
+ * @param type - The type of hook to execute (beforeUpdate, afterUpdate, etc.)
2954
+ * @param objectName - The name of the object being modified
2955
+ * @param ctx - The hook context containing record data and changes
2956
+ */
2957
+ execute(type: HookType, objectName: string, ctx: HookContext): Promise<void>;
2958
+ /**
2959
+ * Register a hook manually (optional)
2960
+ * Not all implementations need to support this (e.g., decorator-based discovery)
2961
+ */
2962
+ register?(hook: HookDefinition): void;
2963
+ }
2964
+ /**
2965
+ * No-op implementation of HookRegistry
2966
+ *
2967
+ * Used as default when no registry is provided to RecordService.
2968
+ * This allows the schema package to work independently without triggers.
2969
+ */
2970
+ declare class NoopHookRegistry implements HookRegistry {
2971
+ execute(): Promise<void>;
2972
+ }
2973
+
2974
+ interface InternalObjectRecord extends ObjectRecord {
2975
+ tenantId: TenantId;
2976
+ }
2977
+ interface MockStores {
2978
+ objects: Map<Uuid, DBObject>;
2979
+ attributes: Map<Uuid, DBAttribute>;
2980
+ userProfiles: Map<Uuid, UserProfile>;
2981
+ files: Map<Uuid, File>;
2982
+ objectRecords: Map<Uuid, InternalObjectRecord>;
2983
+ views: Map<Uuid, DBView>;
2984
+ }
2985
+ /**
2986
+ * Create an in-memory mock adapter for testing and development
2987
+ *
2988
+ * This adapter stores all data in memory and is perfect for:
2989
+ * - Unit tests
2990
+ * - Integration tests
2991
+ * - Local development without a database
2992
+ * - Understanding the adapter interface
2993
+ *
2994
+ * @returns A DatabaseAdapter implementation using in-memory storage
2995
+ *
2996
+ * @example
2997
+ * ```typescript
2998
+ * import { createMockAdapter, RecordService } from "@stndrds/schema";
2999
+ *
3000
+ * // Create adapter
3001
+ * const adapter = createMockAdapter();
3002
+ *
3003
+ * // Use with services
3004
+ * const recordService = new RecordService(adapter, "tenant-123");
3005
+ *
3006
+ * // Create a record
3007
+ * const product = await recordService.createRecord("obj-product", {
3008
+ * name: "Nike Air Max",
3009
+ * price: 129.99
3010
+ * });
3011
+ *
3012
+ * // List records
3013
+ * const { records, total } = await recordService.listRecords("obj-product");
3014
+ * ```
3015
+ */
3016
+ declare function createMockAdapter(): DatabaseAdapter & {
3017
+ _stores: MockStores;
3018
+ reset(): void;
3019
+ };
3020
+
3021
+ /**
3022
+ * Service for managing files
3023
+ * Handles file metadata CRUD, permissions, and soft delete
3024
+ */
3025
+ declare class FileService {
3026
+ private adapter;
3027
+ private tenantId;
3028
+ constructor(adapter: DatabaseAdapter, tenantId: string);
3029
+ /**
3030
+ * Create a new file record (after upload to storage)
3031
+ *
3032
+ * @param data - File metadata
3033
+ * @returns Created file record
3034
+ *
3035
+ * @example
3036
+ * ```typescript
3037
+ * const service = new FileService(adapter, "tenant-123");
3038
+ *
3039
+ * // After uploading to S3
3040
+ * const file = await service.createFile({
3041
+ * tenantId: "tenant-123",
3042
+ * name: "contract-2025.pdf",
3043
+ * originalName: "Contract Acme Corp 2025.pdf",
3044
+ * mimeType: "application/pdf",
3045
+ * size: 2458624,
3046
+ * storageProvider: "s3",
3047
+ * storagePath: "tenants/123/files/2025/contract.pdf",
3048
+ * storageBucket: "my-app-files",
3049
+ * url: "https://cdn.example.com/files/file-123",
3050
+ * uploadedBy: "profile-456",
3051
+ * visibility: "private"
3052
+ * });
3053
+ * ```
3054
+ */
3055
+ createFile(data: CreateFile): Promise<File>;
3056
+ /**
3057
+ * Get file by ID
3058
+ */
3059
+ getFile(fileId: string): Promise<File | null>;
3060
+ /**
3061
+ * Get file by ID or throw
3062
+ */
3063
+ getFileOrThrow(fileId: string): Promise<File>;
3064
+ /**
3065
+ * Update file metadata
3066
+ *
3067
+ * @param fileId - File UUID
3068
+ * @param data - Data to update
3069
+ * @returns Updated file
3070
+ */
3071
+ updateFile(fileId: string, data: UpdateFile): Promise<File>;
3072
+ /**
3073
+ * Delete file (soft delete)
3074
+ *
3075
+ * @param fileId - File UUID
3076
+ * @param options - Delete options
3077
+ */
3078
+ deleteFile(fileId: string, options?: {
3079
+ hard?: boolean;
3080
+ checkOwnership?: boolean;
3081
+ userId?: string;
3082
+ }): Promise<void>;
3083
+ /**
3084
+ * List files for the tenant
3085
+ */
3086
+ listFiles(options?: FileListOptions): Promise<File[]>;
3087
+ /**
3088
+ * List files by folder
3089
+ */
3090
+ listFilesByFolder(folderPath: string): Promise<File[]>;
3091
+ /**
3092
+ * List files uploaded by a specific user
3093
+ */
3094
+ listFilesByUploader(uploadedBy: string): Promise<File[]>;
3095
+ /**
3096
+ * Change file visibility
3097
+ *
3098
+ * @param fileId - File UUID
3099
+ * @param visibility - New visibility level
3100
+ * @param allowedUsers - Users allowed to access (if restricted)
3101
+ */
3102
+ changeVisibility(fileId: string, visibility: "public" | "private" | "restricted", allowedUsers?: string[]): Promise<File>;
3103
+ /**
3104
+ * Grant access to a file for specific users
3105
+ *
3106
+ * @param fileId - File UUID
3107
+ * @param userIds - User IDs to grant access
3108
+ */
3109
+ grantAccess(fileId: string, userIds: string[]): Promise<File>;
3110
+ /**
3111
+ * Revoke access to a file for specific users
3112
+ *
3113
+ * @param fileId - File UUID
3114
+ * @param userIds - User IDs to revoke access
3115
+ */
3116
+ revokeAccess(fileId: string, userIds: string[]): Promise<File>;
3117
+ /**
3118
+ * Check if user has access to a file
3119
+ *
3120
+ * @param fileId - File UUID
3121
+ * @param userId - User ID to check
3122
+ * @returns true if user can access the file
3123
+ */
3124
+ canAccess(fileId: string, userId: string): Promise<boolean>;
3125
+ /**
3126
+ * Move file to different folder
3127
+ */
3128
+ moveToFolder(fileId: string, newFolderPath: string): Promise<File>;
3129
+ /**
3130
+ * Add tags to file
3131
+ */
3132
+ addTags(fileId: string, tags: string[]): Promise<File>;
3133
+ /**
3134
+ * Remove tags from file
3135
+ */
3136
+ removeTags(fileId: string, tags: string[]): Promise<File>;
3137
+ }
3138
+
3139
+ /**
3140
+ * Geocoding service for address autocomplete and geocoding operations
3141
+ *
3142
+ * @example
3143
+ * ```typescript
3144
+ * import { GeocodingService } from "@stndrds/schema";
3145
+ * import { GoogleMapsAdapter } from "./adapters/google-maps";
3146
+ *
3147
+ * const geocoding = new GeocodingService(new GoogleMapsAdapter({ apiKey: "..." }));
3148
+ *
3149
+ * const suggestions = await geocoding.autocomplete({
3150
+ * query: "40 Quai des Belges",
3151
+ * countries: ["FRA"],
3152
+ * limit: 5,
3153
+ * });
3154
+ * ```
3155
+ */
3156
+ declare class GeocodingService {
3157
+ private readonly adapter;
3158
+ constructor(adapter: GeocodingAdapter);
3159
+ /**
3160
+ * Search for address suggestions as the user types
3161
+ */
3162
+ autocomplete(params: GeocodingAutocompleteParams): Promise<GeocodingSuggestion[]>;
3163
+ /**
3164
+ * Reverse geocode coordinates to an address
3165
+ */
3166
+ reverse(params: ReverseGeocodingParams): Promise<GeocodingSuggestion | null>;
3167
+ /**
3168
+ * Geocode a structured address to coordinates
3169
+ */
3170
+ geocode(params: GeocodingParams): Promise<GeocodingSuggestion | null>;
3171
+ }
3172
+
3173
+ /**
3174
+ * Service for global search across all object records
3175
+ * Allows searching across all objects or a subset of objects for a tenant
3176
+ *
3177
+ * @example
3178
+ * ```typescript
3179
+ * const service = new GlobalSearchService(adapter, "tenant-123");
3180
+ *
3181
+ * // Search across all objects
3182
+ * const { results, total } = await service.search("nike");
3183
+ *
3184
+ * // Search only in specific objects
3185
+ * const { results, total } = await service.search("nike", {
3186
+ * objectNames: ["products", "orders"],
3187
+ * limit: 20
3188
+ * });
3189
+ * ```
3190
+ */
3191
+ declare class GlobalSearchService {
3192
+ private adapter;
3193
+ private tenantId;
3194
+ constructor(adapter: DatabaseAdapter, tenantId: string);
3195
+ /**
3196
+ * Search across all object records for the tenant
3197
+ *
3198
+ * @param query - Search query string
3199
+ * @param options - Search options (pagination, object filters)
3200
+ * @returns Matching records with object metadata and total count
3201
+ *
3202
+ * @example
3203
+ * ```typescript
3204
+ * // Basic search
3205
+ * const { results, total } = await service.search("nike air");
3206
+ *
3207
+ * // With pagination
3208
+ * const { results, total } = await service.search("nike", {
3209
+ * limit: 10,
3210
+ * offset: 20
3211
+ * });
3212
+ *
3213
+ * // Filter by object types
3214
+ * const { results, total } = await service.search("nike", {
3215
+ * objectNames: ["products", "orders"]
3216
+ * });
3217
+ * ```
3218
+ */
3219
+ search(query: string, options?: GlobalSearchOptions): Promise<{
3220
+ results: GlobalSearchResultItem[];
3221
+ total: number;
3222
+ }>;
3223
+ /**
3224
+ * Search and group results by object type
3225
+ *
3226
+ * @param query - Search query string
3227
+ * @param options - Search options
3228
+ * @returns Results grouped by object name
3229
+ */
3230
+ searchGrouped(query: string, options?: Omit<GlobalSearchOptions, "limit" | "offset">): Promise<{
3231
+ groups: Array<{
3232
+ objectName: string;
3233
+ objectLabel: string;
3234
+ results: GlobalSearchResultItem[];
3235
+ count: number;
3236
+ }>;
3237
+ total: number;
3238
+ }>;
3239
+ }
3240
+
3241
+ /**
3242
+ * Input for creating a custom object
3243
+ */
3244
+ interface CreateCustomObjectInput {
3245
+ name: string;
3246
+ label: string;
3247
+ /**
3248
+ * Template expression for computing record display labels.
3249
+ * Example: "{{ name }}" or "{{ firstName }} {{ lastName }}"
3250
+ */
3251
+ labelExpression: string;
3252
+ description?: string;
3253
+ icon?: IconName;
3254
+ attributes?: (Attribute | {
3255
+ build: () => Attribute;
3256
+ })[];
3257
+ metadata?: Record<string, unknown>;
3258
+ }
3259
+ /**
3260
+ * Input for adding an attribute to an object
3261
+ */
3262
+ interface AddAttributeInput {
3263
+ name: string;
3264
+ label: string;
3265
+ type: AttributeType;
3266
+ required?: boolean;
3267
+ unique?: boolean;
3268
+ description?: string;
3269
+ placeholder?: string;
3270
+ icon?: IconName;
3271
+ defaultValue?: unknown;
3272
+ metadata?: Record<string, unknown>;
3273
+ [key: string]: unknown;
3274
+ }
3275
+ /**
3276
+ * Service for managing object schemas
3277
+ * Handles fusion of native objects (from registry) and custom objects (from database)
3278
+ */
3279
+ declare class ObjectSchemaService {
3280
+ private adapter;
3281
+ private nativeRegistry;
3282
+ constructor(adapter: DatabaseAdapter, nativeRegistry: typeof registry);
3283
+ /**
3284
+ * Create a new custom object
3285
+ * Validates name format and ensures system=false
3286
+ *
3287
+ * @param definition - Object definition (attributes can be raw definitions or builders)
3288
+ * @param tenantId - Tenant ID owning the object
3289
+ * @returns Created ObjectDefinition
3290
+ */
3291
+ createCustomObject(definition: CreateCustomObjectInput, tenantId: string): Promise<ObjectDefinition>;
3292
+ /**
3293
+ * Add a custom attribute to an existing object
3294
+ * Can be used on both custom and native objects
3295
+ * Attributes added via API are always custom (system=false)
3296
+ *
3297
+ * @param objectId - Object UUID from database
3298
+ * @param attribute - Attribute definition
3299
+ * @param tenantId - Tenant ID (required for relation validation)
3300
+ * @returns Created Attribute
3301
+ */
3302
+ addAttributeToObject(objectId: string, attribute: AddAttributeInput, tenantId?: string): Promise<Attribute>;
3303
+ /**
3304
+ * Update an attribute
3305
+ * Can only update custom attributes (system=false)
3306
+ *
3307
+ * @param attributeId - Attribute UUID
3308
+ * @param updates - Partial attribute updates
3309
+ * @param tenantId - Tenant ID (required for relation validation)
3310
+ * @returns Updated Attribute
3311
+ */
3312
+ updateAttribute(attributeId: string, updates: Partial<AddAttributeInput>, tenantId?: string): Promise<Attribute>;
3313
+ /**
3314
+ * Delete an attribute
3315
+ * Can only delete custom attributes (system=false)
3316
+ *
3317
+ * @param attributeId - Attribute UUID
3318
+ */
3319
+ deleteAttribute(attributeId: string): Promise<void>;
3320
+ /**
3321
+ * List attributes for an object
3322
+ *
3323
+ * @param objectId - Object UUID
3324
+ * @param options - Filter options
3325
+ * @returns List of attributes
3326
+ */
3327
+ listAttributes(objectId: string, options?: {
3328
+ systemOnly?: boolean;
3329
+ customOnly?: boolean;
3330
+ }): Promise<Attribute[]>;
3331
+ /**
3332
+ * Validate attribute name format (variable identifier)
3333
+ * @internal
3334
+ */
3335
+ private validateAttributeName;
3336
+ /**
3337
+ * Get complete object schema (system + custom attributes)
3338
+ * If object is native, merges registry definition with DB custom attributes
3339
+ * If object is custom, returns DB definition only
3340
+ *
3341
+ * @param objectId - Object UUID from database
3342
+ * @returns Complete ObjectDefinition with all attributes
3343
+ *
3344
+ * @example
3345
+ * ```typescript
3346
+ * const service = new ObjectSchemaService(adapter, registry);
3347
+ * const productSchema = await service.getObjectSchema("obj-123");
3348
+ *
3349
+ * console.log(productSchema.attributes); // System + custom attributes
3350
+ * ```
3351
+ */
3352
+ getObjectSchema(objectId: string): Promise<ObjectDefinition>;
3353
+ /**
3354
+ * Get object schema by name (for system/native objects)
3355
+ * @deprecated Use getObjectSchemaByNameForTenant for custom objects support
3356
+ */
3357
+ getObjectSchemaByName(name: string): Promise<ObjectDefinition>;
3358
+ /**
3359
+ * Get object schema by name for a tenant (supports both native and custom objects)
3360
+ */
3361
+ getObjectSchemaByNameForTenant(name: string, tenantId: string): Promise<ObjectDefinition>;
3362
+ /**
3363
+ * List all object schemas for a tenant
3364
+ */
3365
+ listObjectSchemas(tenantId: string): Promise<ObjectDefinition[]>;
3366
+ /**
3367
+ * Merge native object from registry with custom attributes from DB
3368
+ * @internal
3369
+ */
3370
+ private mergeNativeObject;
3371
+ /**
3372
+ * Convert DB object + attributes to ObjectDefinition
3373
+ * @internal
3374
+ */
3375
+ private convertDBObjectToDefinition;
3376
+ /**
3377
+ * Validate attribute input and return parsed config
3378
+ * Validates: name format, config schema, relation targets
3379
+ * @internal
3380
+ */
3381
+ private validateAttributeInput;
3382
+ /**
3383
+ * Build and validate attribute config from input
3384
+ * Uses Zod schema to validate and strip unknown properties
3385
+ * @internal
3386
+ */
3387
+ private buildAttributeConfig;
3388
+ /**
3389
+ * Validate that relation target objects exist
3390
+ * @internal
3391
+ */
3392
+ private validateRelationTargets;
3393
+ /**
3394
+ * Convert DB attribute to Attribute type
3395
+ * @internal
3396
+ */
3397
+ private convertDBAttributeToAttribute;
3398
+ }
3399
+
3400
+ /**
3401
+ * Options for RecordService constructor
3402
+ */
3403
+ interface RecordServiceOptions {
3404
+ /**
3405
+ * Hook registry for executing triggers before/after operations.
3406
+ * If not provided, a no-op registry is used (no hooks executed).
3407
+ */
3408
+ hookRegistry?: HookRegistry;
3409
+ }
3410
+ /**
3411
+ * Service for managing object records (CRUD operations)
3412
+ * Handles validation, dispatch to correct table, and data consistency
3413
+ *
3414
+ * Supports optional hook system for triggers on attribute changes.
3415
+ */
3416
+ declare class RecordService {
3417
+ private adapter;
3418
+ private tenantId;
3419
+ private schemaService;
3420
+ private relationService;
3421
+ private hookRegistry;
3422
+ constructor(adapter: DatabaseAdapter, tenantId: string, options?: RecordServiceOptions);
3423
+ /**
3424
+ * Compute display label from schema expression
3425
+ * @internal
3426
+ */
3427
+ private computeLabel;
3428
+ /**
3429
+ * Create a new record with validation
3430
+ *
3431
+ * Triggers beforeCreate and afterCreate hooks if a HookRegistry is configured.
3432
+ *
3433
+ * @param objectId - Object UUID
3434
+ * @param data - Record data (attribute values)
3435
+ * @param options - Creation options
3436
+ * @returns Created record with computed completionStatus
3437
+ *
3438
+ * @example
3439
+ * ```typescript
3440
+ * const service = new RecordService(adapter, "tenant-123");
3441
+ *
3442
+ * // Create a complete record (strict validation)
3443
+ * const product = await service.createRecord("obj-product", {
3444
+ * name: "Nike Air Max",
3445
+ * price: 129.99,
3446
+ * status: "active"
3447
+ * });
3448
+ * // → product.completionStatus = "complete"
3449
+ *
3450
+ * // Create a draft record (allows missing required fields)
3451
+ * const draft = await service.createRecord("obj-product", {
3452
+ * name: "Draft Product"
3453
+ * }, { allowDraft: true });
3454
+ * // → draft.completionStatus = "draft"
3455
+ * ```
3456
+ */
3457
+ createRecord(objectId: string, data: Record<string, unknown>, options?: {
3458
+ /**
3459
+ * Allow creating records with missing required fields.
3460
+ * Format validation still applies to provided values.
3461
+ * @default false
3462
+ */
3463
+ allowDraft?: boolean;
3464
+ /**
3465
+ * Skip all validation (format + relations).
3466
+ * @default true
3467
+ */
3468
+ validate?: boolean;
3469
+ /**
3470
+ * Skip relation validation only.
3471
+ * Useful for bulk imports where relations are validated separately.
3472
+ * @default false
3473
+ */
3474
+ skipRelationValidation?: boolean;
3475
+ skipSystemCheck?: boolean;
3476
+ /**
3477
+ * Skip hook execution.
3478
+ * @default false
3479
+ */
3480
+ skipHooks?: boolean;
3481
+ /**
3482
+ * Additional metadata to pass to hooks (e.g., userId, requestId).
3483
+ */
3484
+ hookMetadata?: Record<string, unknown>;
3485
+ }): Promise<ObjectRecord>;
3486
+ /**
3487
+ * Get a record by ID
3488
+ *
3489
+ * @param recordId - Record UUID
3490
+ * @param options - Query options
3491
+ * @returns Record or null if not found
3492
+ */
3493
+ getRecord(recordId: string, options?: {
3494
+ includeSchema?: boolean;
3495
+ }): Promise<ObjectRecord | null>;
3496
+ /**
3497
+ * Get a record by ID or throw if not found
3498
+ */
3499
+ getRecordOrThrow(recordId: string): Promise<ObjectRecord>;
3500
+ /**
3501
+ * Update a record with validation
3502
+ *
3503
+ * The completion status is automatically recalculated after each update.
3504
+ * A draft record becomes complete when all required fields are filled.
3505
+ *
3506
+ * Triggers beforeUpdate and afterUpdate hooks if a HookRegistry is configured.
3507
+ *
3508
+ * @param recordId - Record UUID
3509
+ * @param data - Partial data to update
3510
+ * @param options - Update options
3511
+ * @returns Updated record with recalculated completionStatus
3512
+ *
3513
+ * @example
3514
+ * ```typescript
3515
+ * // Update a draft record to make it complete
3516
+ * const updated = await service.updateRecord(draftId, {
3517
+ * price: 99.99,
3518
+ * status: "active"
3519
+ * });
3520
+ * // → updated.completionStatus = "complete" if all required fields now present
3521
+ * ```
3522
+ */
3523
+ updateRecord(recordId: string, data: Partial<Record<string, unknown>>, options?: {
3524
+ /**
3525
+ * Skip validation entirely (format + relations).
3526
+ * @default true
3527
+ */
3528
+ validate?: boolean;
3529
+ /**
3530
+ * Allow partial updates without strict validation.
3531
+ * Format validation still applies to provided values.
3532
+ * @default false
3533
+ */
3534
+ partial?: boolean;
3535
+ /**
3536
+ * Skip relation validation only.
3537
+ * @default false
3538
+ */
3539
+ skipRelationValidation?: boolean;
3540
+ /**
3541
+ * Skip hook execution.
3542
+ * @default false
3543
+ */
3544
+ skipHooks?: boolean;
3545
+ /**
3546
+ * Additional metadata to pass to hooks (e.g., userId, requestId).
3547
+ */
3548
+ hookMetadata?: Record<string, unknown>;
3549
+ }): Promise<ObjectRecord>;
3550
+ /**
3551
+ * Build hook context for update operations
3552
+ * @internal
3553
+ */
3554
+ private buildHookContext;
3555
+ /**
3556
+ * Build hook context for create operations (no existing record)
3557
+ * @internal
3558
+ */
3559
+ private buildCreateHookContext;
3560
+ /**
3561
+ * Build hook context for delete operations
3562
+ * @internal
3563
+ */
3564
+ private buildDeleteHookContext;
3565
+ /**
3566
+ * Delete a record
3567
+ *
3568
+ * Triggers beforeDelete and afterDelete hooks if a HookRegistry is configured.
3569
+ *
3570
+ * @param recordId - Record UUID
3571
+ * @param options - Delete options
3572
+ */
3573
+ deleteRecord(recordId: string, options?: {
3574
+ checkSystem?: boolean;
3575
+ /**
3576
+ * Skip hook execution.
3577
+ * @default false
3578
+ */
3579
+ skipHooks?: boolean;
3580
+ /**
3581
+ * Additional metadata to pass to hooks (e.g., userId, requestId).
3582
+ */
3583
+ hookMetadata?: Record<string, unknown>;
3584
+ }): Promise<void>;
3585
+ /**
3586
+ * List records for an object with pagination
3587
+ *
3588
+ * @param objectId - Object UUID
3589
+ * @param options - List options
3590
+ * @returns Records and total count
3591
+ */
3592
+ listRecords(objectId: string, options?: {
3593
+ limit?: number;
3594
+ offset?: number;
3595
+ orderBy?: string;
3596
+ orderDirection?: "asc" | "desc";
3597
+ }): Promise<{
3598
+ records: ObjectRecord[];
3599
+ total: number;
3600
+ }>;
3601
+ /**
3602
+ * Search records using full-text search
3603
+ *
3604
+ * @param objectId - Object UUID
3605
+ * @param query - Search query
3606
+ * @param options - Search options
3607
+ * @returns Matching records and total count
3608
+ */
3609
+ searchRecords(objectId: string, query: string, options?: {
3610
+ limit?: number;
3611
+ offset?: number;
3612
+ }): Promise<{
3613
+ records: ObjectRecord[];
3614
+ total: number;
3615
+ }>;
3616
+ /**
3617
+ * Validate data against object schema without saving
3618
+ *
3619
+ * @param objectId - Object UUID
3620
+ * @param data - Data to validate
3621
+ * @returns Validation result
3622
+ */
3623
+ validateData(objectId: string, data: Record<string, unknown>): Promise<ValidationResult>;
3624
+ /**
3625
+ * Compute the completion status for given data without saving.
3626
+ * Useful for UI to show draft/complete status before submitting.
3627
+ *
3628
+ * @param objectId - Object UUID
3629
+ * @param data - Data to check
3630
+ * @returns Computed completion status
3631
+ */
3632
+ computeStatus(objectId: string, data: Record<string, unknown>): Promise<CompletionStatus>;
3633
+ /**
3634
+ * Refresh the completion status of an existing record.
3635
+ * Useful when schema changes and you need to recompute statuses.
3636
+ *
3637
+ * @param recordId - Record UUID
3638
+ * @returns Updated completion status
3639
+ */
3640
+ refreshRecordStatus(recordId: string): Promise<CompletionStatus>;
3641
+ }
3642
+
3643
+ /**
3644
+ * Result of relation validation
3645
+ */
3646
+ interface RelationValidationResult {
3647
+ valid: boolean;
3648
+ errors: RelationValidationError[];
3649
+ }
3650
+ /**
3651
+ * Individual relation validation error
3652
+ */
3653
+ interface RelationValidationError {
3654
+ /** Attribute name */
3655
+ attribute: string;
3656
+ /** Error message */
3657
+ message: string;
3658
+ /** Invalid record IDs */
3659
+ invalidIds?: string[];
3660
+ }
3661
+ /**
3662
+ * Resolved relation option
3663
+ */
3664
+ interface RelationOption {
3665
+ /** Record ID */
3666
+ id: string;
3667
+ /** Object ID */
3668
+ objectId: string;
3669
+ /** Object name (technical name) */
3670
+ objectName: string;
3671
+ /** Object label (display name) */
3672
+ objectLabel: string;
3673
+ /** Object icon */
3674
+ objectIcon?: string;
3675
+ /** Display label (computed from labelExpression) */
3676
+ label: string;
3677
+ /** Additional record data */
3678
+ data?: Record<string, unknown>;
3679
+ }
3680
+ /**
3681
+ * Response for relation options
3682
+ */
3683
+ interface RelationOptionsResponse {
3684
+ options: RelationOption[];
3685
+ hasMore: boolean;
3686
+ total: number;
3687
+ }
3688
+ /**
3689
+ * Parameters for fetching relation options
3690
+ */
3691
+ interface GetRelationOptionsParams {
3692
+ /** Search query */
3693
+ query?: string;
3694
+ /** Page number (1-based) */
3695
+ page?: number;
3696
+ /** Page size */
3697
+ pageSize?: number;
3698
+ /** Filter by specific target object */
3699
+ targetObject?: string;
3700
+ }
3701
+ /**
3702
+ * Service for validating relation attributes
3703
+ * Ensures referenced records exist and belong to valid target objects
3704
+ */
3705
+ declare class RelationService {
3706
+ private adapter;
3707
+ private schemaService;
3708
+ constructor(adapter: DatabaseAdapter, nativeRegistry: typeof registry);
3709
+ /**
3710
+ * Validate all relation attributes in the data
3711
+ *
3712
+ * @param schema - Object schema containing attribute definitions
3713
+ * @param data - Record data to validate
3714
+ * @returns Validation result with errors if any
3715
+ *
3716
+ * @example
3717
+ * ```typescript
3718
+ * const result = await relationService.validateRelations(schema, {
3719
+ * company: "rec-123",
3720
+ * contacts: ["rec-456", "rec-789"]
3721
+ * });
3722
+ *
3723
+ * if (!result.valid) {
3724
+ * console.log(result.errors);
3725
+ * // [{ attribute: "company", message: "Record not found", invalidIds: ["rec-123"] }]
3726
+ * }
3727
+ * ```
3728
+ */
3729
+ validateRelations(schema: ObjectDefinition, data: Record<string, unknown>): Promise<RelationValidationResult>;
3730
+ /**
3731
+ * Validate a single relation attribute value
3732
+ */
3733
+ private validateRelationAttribute;
3734
+ /**
3735
+ * Extract IDs from relation value based on cardinality
3736
+ */
3737
+ private extractIds;
3738
+ /**
3739
+ * Get valid object IDs from relation targets
3740
+ */
3741
+ private getValidObjectIds;
3742
+ /**
3743
+ * Validate relations and throw if invalid
3744
+ */
3745
+ validateRelationsOrThrow(schema: ObjectDefinition, data: Record<string, unknown>): Promise<void>;
3746
+ /**
3747
+ * Get available options for a relation attribute
3748
+ * Searches across all target objects defined in the relation
3749
+ *
3750
+ * @param attribute - Relation attribute definition
3751
+ * @param tenantId - Tenant ID for multi-tenant isolation
3752
+ * @param params - Query parameters
3753
+ *
3754
+ * @example
3755
+ * ```typescript
3756
+ * const options = await relationService.getOptions(attribute, "tenant-1", {
3757
+ * query: "nike",
3758
+ * page: 1,
3759
+ * pageSize: 20
3760
+ * });
3761
+ * ```
3762
+ */
3763
+ getOptions(attribute: RelationAttribute, tenantId: string, params?: GetRelationOptionsParams): Promise<RelationOptionsResponse>;
3764
+ /**
3765
+ * Resolve record IDs to their display labels
3766
+ * Useful for displaying current values in the UI
3767
+ *
3768
+ * @param ids - Record IDs to resolve
3769
+ * @param tenantId - Tenant ID for multi-tenant isolation
3770
+ *
3771
+ * @example
3772
+ * ```typescript
3773
+ * const resolved = await relationService.resolveIds(["rec-1", "rec-2"], "tenant-1");
3774
+ * // [{ id: "rec-1", label: "Nike Air Max", objectName: "products", ... }]
3775
+ * ```
3776
+ */
3777
+ resolveIds(ids: string[], tenantId: string): Promise<RelationOption[]>;
3778
+ /**
3779
+ * Find a relation attribute by ID
3780
+ */
3781
+ findAttributeById(attributeId: string): Promise<RelationAttribute | null>;
3782
+ }
3783
+
3784
+ /**
3785
+ * Service for managing user profiles
3786
+ * Handles user profile CRUD, auth provider sync, and role management
3787
+ */
3788
+ declare class UserProfileService {
3789
+ private adapter;
3790
+ private tenantId;
3791
+ constructor(adapter: DatabaseAdapter, tenantId: string);
3792
+ /**
3793
+ * Create a new user profile (typically after first auth)
3794
+ *
3795
+ * @param data - User profile creation data
3796
+ * @returns Created user profile
3797
+ *
3798
+ * @example
3799
+ * ```typescript
3800
+ * const service = new UserProfileService(adapter, "tenant-123");
3801
+ *
3802
+ * // After Supabase auth
3803
+ * const profile = await service.createProfile({
3804
+ * tenantId: "tenant-123",
3805
+ * authId: authUser.id,
3806
+ * email: authUser.email,
3807
+ * firstName: authUser.user_metadata.first_name,
3808
+ * lastName: authUser.user_metadata.last_name,
3809
+ * role: "member",
3810
+ * status: "active"
3811
+ * });
3812
+ * ```
3813
+ */
3814
+ createProfile(data: CreateUserProfile): Promise<UserProfile>;
3815
+ /**
3816
+ * Get user profile by ID
3817
+ */
3818
+ getProfile(profileId: string): Promise<UserProfile | null>;
3819
+ /**
3820
+ * Get user profile by ID or throw
3821
+ */
3822
+ getProfileOrThrow(profileId: string): Promise<UserProfile>;
3823
+ /**
3824
+ * Get user profile by auth provider ID
3825
+ *
3826
+ * @param authId - Auth provider user ID (Supabase, Clerk, etc.)
3827
+ * @returns User profile or null
3828
+ */
3829
+ getProfileByAuthId(authId: string): Promise<UserProfile | null>;
3830
+ /**
3831
+ * Get or create user profile (idempotent operation)
3832
+ * Useful for auth callbacks - ensures profile exists
3833
+ *
3834
+ * @param authId - Auth provider user ID
3835
+ * @param data - Profile data to create if doesn't exist
3836
+ * @returns Existing or newly created profile
3837
+ *
3838
+ * @example
3839
+ * ```typescript
3840
+ * // In Supabase auth callback
3841
+ * const profile = await service.getOrCreateProfile(
3842
+ * authUser.id,
3843
+ * {
3844
+ * tenantId: "tenant-123",
3845
+ * authId: authUser.id,
3846
+ * email: authUser.email,
3847
+ * role: "member",
3848
+ * status: "active"
3849
+ * }
3850
+ * );
3851
+ * ```
3852
+ */
3853
+ getOrCreateProfile(authId: string, data: CreateUserProfile): Promise<UserProfile>;
3854
+ /**
3855
+ * Update user profile
3856
+ */
3857
+ updateProfile(profileId: string, data: UpdateUserProfile): Promise<UserProfile>;
3858
+ /**
3859
+ * Delete user profile
3860
+ *
3861
+ * @param profileId - Profile UUID
3862
+ * @param options - Delete options
3863
+ */
3864
+ deleteProfile(profileId: string, options?: {
3865
+ checkAdmin?: boolean;
3866
+ }): Promise<void>;
3867
+ /**
3868
+ * List all user profiles for the tenant
3869
+ */
3870
+ listProfiles(options?: ListOptions): Promise<UserProfile[]>;
3871
+ /**
3872
+ * Update last login timestamp
3873
+ *
3874
+ * @param profileId - Profile UUID
3875
+ *
3876
+ * @example
3877
+ * ```typescript
3878
+ * // After successful auth
3879
+ * await service.updateLastLogin(profile.id);
3880
+ * ```
3881
+ */
3882
+ updateLastLogin(profileId: string): Promise<void>;
3883
+ /**
3884
+ * Change user role
3885
+ *
3886
+ * @param profileId - Profile UUID
3887
+ * @param newRole - New role
3888
+ */
3889
+ changeRole(profileId: string, newRole: string): Promise<UserProfile>;
3890
+ /**
3891
+ * Change user status
3892
+ *
3893
+ * @param profileId - Profile UUID
3894
+ * @param newStatus - New status
3895
+ */
3896
+ changeStatus(profileId: string, newStatus: "active" | "pending" | "inactive" | "suspended"): Promise<UserProfile>;
3897
+ /**
3898
+ * Get user by email
3899
+ */
3900
+ getProfileByEmail(email: string): Promise<UserProfile | null>;
3901
+ /**
3902
+ * Check if user has role
3903
+ */
3904
+ hasRole(profileId: string, role: string): Promise<boolean>;
3905
+ /**
3906
+ * Check if user is admin
3907
+ */
3908
+ isAdmin(profileId: string): Promise<boolean>;
3909
+ }
3910
+
3911
+ /**
3912
+ * Input for creating a custom view
3913
+ */
3914
+ interface CreateViewInput {
3915
+ name: string;
3916
+ label: string;
3917
+ objectName: string;
3918
+ description?: string;
3919
+ icon?: IconName;
3920
+ tabs: Tab[];
3921
+ default?: boolean;
3922
+ metadata?: Record<string, unknown>;
3923
+ }
3924
+ /**
3925
+ * Input for updating a view
3926
+ */
3927
+ interface UpdateViewInput {
3928
+ label?: string;
3929
+ description?: string;
3930
+ icon?: IconName;
3931
+ tabs?: Tab[];
3932
+ default?: boolean;
3933
+ metadata?: Record<string, unknown>;
3934
+ }
3935
+ /**
3936
+ * Service for managing views
3937
+ * Handles fusion of native views (from registry) and custom views (from database)
3938
+ */
3939
+ declare class ViewService {
3940
+ private adapter;
3941
+ private nativeViews;
3942
+ constructor(adapter: DatabaseAdapter, nativeViews: typeof viewRegistry);
3943
+ /**
3944
+ * Get all views for an object (native + custom)
3945
+ *
3946
+ * @param objectName - Object name
3947
+ * @param tenantId - Tenant ID
3948
+ * @returns All views for the object
3949
+ */
3950
+ getViewsForObject(objectName: string, tenantId: string): Promise<ViewDefinition[]>;
3951
+ /**
3952
+ * Get a specific view by name
3953
+ *
3954
+ * @param objectName - Object name
3955
+ * @param viewName - View name
3956
+ * @param tenantId - Tenant ID
3957
+ * @returns View definition or null
3958
+ */
3959
+ getView(objectName: string, viewName: string, tenantId: string): Promise<ViewDefinition | null>;
3960
+ /**
3961
+ * Get the default view for an object
3962
+ *
3963
+ * Priority:
3964
+ * 1. Custom view marked as default
3965
+ * 2. Native view marked as default
3966
+ * 3. First available view
3967
+ *
3968
+ * @param objectName - Object name
3969
+ * @param tenantId - Tenant ID
3970
+ * @returns Default view or null
3971
+ */
3972
+ getDefaultView(objectName: string, tenantId: string): Promise<ViewDefinition | null>;
3973
+ /**
3974
+ * Create a custom view
3975
+ *
3976
+ * @param input - View definition
3977
+ * @param tenantId - Tenant ID
3978
+ * @returns Created view
3979
+ */
3980
+ createView(input: CreateViewInput, tenantId: string): Promise<ViewDefinition>;
3981
+ /**
3982
+ * Update a custom view
3983
+ *
3984
+ * @param viewId - View ID
3985
+ * @param input - Update data
3986
+ * @returns Updated view
3987
+ */
3988
+ updateView(viewId: string, input: UpdateViewInput): Promise<ViewDefinition>;
3989
+ /**
3990
+ * Delete a custom view
3991
+ *
3992
+ * @param viewId - View ID
3993
+ */
3994
+ deleteView(viewId: string): Promise<void>;
3995
+ /**
3996
+ * Set a view as default for its object
3997
+ *
3998
+ * @param viewId - View ID
3999
+ * @param tenantId - Tenant ID
4000
+ * @returns Updated view
4001
+ */
4002
+ setDefaultView(viewId: string, tenantId: string): Promise<ViewDefinition>;
4003
+ /**
4004
+ * Validate view name format (kebab-case)
4005
+ */
4006
+ private validateViewName;
4007
+ /**
4008
+ * Convert database view to ViewDefinition
4009
+ */
4010
+ private convertDBViewToDefinition;
4011
+ }
4012
+
4013
+ /**
4014
+ * Result of view sync operation
4015
+ */
4016
+ interface ViewSyncResult {
4017
+ success: boolean;
4018
+ viewsSynced: number;
4019
+ viewsCreated: number;
4020
+ viewsUpdated: number;
4021
+ viewsDeleted: number;
4022
+ errors: Array<{
4023
+ viewName: string;
4024
+ objectName: string;
4025
+ error: string;
4026
+ }>;
4027
+ }
4028
+ /**
4029
+ * Options for view sync
4030
+ */
4031
+ interface ViewSyncOptions {
4032
+ dryRun?: boolean;
4033
+ verbose?: boolean;
4034
+ tenantId?: string;
4035
+ }
4036
+ /**
4037
+ * Sync native views from registry to database
4038
+ *
4039
+ * This function:
4040
+ * 1. Reads all registered native views from the registry
4041
+ * 2. Upserts them into the database (views table)
4042
+ * 3. Marks them as system=true for protection
4043
+ * 4. Removes views that were deleted from code
4044
+ *
4045
+ * @param adapter - Database adapter implementing DatabaseAdapter interface
4046
+ * @param nativeViewRegistry - Registry containing native views
4047
+ * @param options - Sync options (dryRun, verbose, tenantId)
4048
+ * @returns Sync result with statistics
4049
+ *
4050
+ * @example
4051
+ * ```typescript
4052
+ * import { syncNativeViews, viewRegistry } from "@stndrds/schema";
4053
+ * import { drizzleAdapter } from "./db/adapter";
4054
+ *
4055
+ * const result = await syncNativeViews(drizzleAdapter, viewRegistry, {
4056
+ * verbose: true,
4057
+ * tenantId: "default"
4058
+ * });
4059
+ *
4060
+ * if (result.success) {
4061
+ * console.log(`✓ Synced ${result.viewsSynced} views`);
4062
+ * }
4063
+ * ```
4064
+ */
4065
+ declare function syncNativeViews(adapter: DatabaseAdapter, nativeViewRegistry: typeof viewRegistry, options?: ViewSyncOptions): Promise<ViewSyncResult>;
4066
+ /**
4067
+ * Verify that all native views are synced to database
4068
+ *
4069
+ * @param adapter - Database adapter
4070
+ * @param nativeViewRegistry - Registry containing native views
4071
+ * @returns true if all views are synced, false otherwise
4072
+ *
4073
+ * @example
4074
+ * ```typescript
4075
+ * const isSynced = await verifyNativeViewsSync(adapter, viewRegistry);
4076
+ * if (!isSynced) {
4077
+ * console.warn("Native views not synced, running sync...");
4078
+ * await syncNativeViews(adapter, viewRegistry);
4079
+ * }
4080
+ * ```
4081
+ */
4082
+ declare function verifyNativeViewsSync(adapter: DatabaseAdapter, nativeViewRegistry: typeof viewRegistry): Promise<boolean>;
4083
+ /**
4084
+ * Get sync preview without modifying database
4085
+ *
4086
+ * @param adapter - Database adapter
4087
+ * @param nativeViewRegistry - Registry containing native views
4088
+ * @returns Sync result (dry run)
4089
+ */
4090
+ declare function getViewSyncPreview(adapter: DatabaseAdapter, nativeViewRegistry: typeof viewRegistry): Promise<ViewSyncResult>;
4091
+
4092
+ /**
4093
+ * Result of sync operation
4094
+ */
4095
+ interface SyncResult {
4096
+ success: boolean;
4097
+ objectsSynced: number;
4098
+ attributesSynced: number;
4099
+ objectsCreated: number;
4100
+ objectsUpdated: number;
4101
+ attributesCreated: number;
4102
+ attributesUpdated: number;
4103
+ attributesDeleted: number;
4104
+ errors: Array<{
4105
+ objectName: string;
4106
+ error: string;
4107
+ }>;
4108
+ }
4109
+ /**
4110
+ * Sync options
4111
+ */
4112
+ interface SyncOptions {
4113
+ dryRun?: boolean;
4114
+ verbose?: boolean;
4115
+ tenantId?: string;
4116
+ }
4117
+ /**
4118
+ * Sync native objects from registry to database
4119
+ *
4120
+ * This function:
4121
+ * 1. Reads all registered native objects from the registry
4122
+ * 2. Upserts them into the database (objects + attributes tables)
4123
+ * 3. Marks them as system=true for protection
4124
+ * 4. Removes attributes that were deleted from code
4125
+ *
4126
+ * @param adapter - Database adapter implementing DatabaseAdapter interface
4127
+ * @param nativeRegistry - Registry containing native objects
4128
+ * @param options - Sync options (dryRun, verbose, tenantId)
4129
+ * @returns Sync result with statistics
4130
+ *
4131
+ * @example
4132
+ * ```typescript
4133
+ * import { syncNativeObjects } from "@stndrds/schema/runtime";
4134
+ * import { registry } from "./objects/native";
4135
+ * import { drizzleAdapter } from "./db/adapter";
4136
+ *
4137
+ * const result = await syncNativeObjects(drizzleAdapter, registry, {
4138
+ * verbose: true,
4139
+ * tenantId: "default"
4140
+ * });
4141
+ *
4142
+ * if (result.success) {
4143
+ * console.log(`✓ Synced ${result.objectsSynced} objects`);
4144
+ * } else {
4145
+ * console.error("Sync errors:", result.errors);
4146
+ * }
4147
+ * ```
4148
+ */
4149
+ declare function syncNativeObjects(adapter: DatabaseAdapter, nativeRegistry: typeof registry, options?: SyncOptions): Promise<SyncResult>;
4150
+ /**
4151
+ * Verify that all native objects are synced to database
4152
+ *
4153
+ * @param adapter - Database adapter
4154
+ * @param nativeRegistry - Registry containing native objects
4155
+ * @returns true if all objects are synced, false otherwise
4156
+ *
4157
+ * @example
4158
+ * ```typescript
4159
+ * const isSynced = await verifyNativeObjectsSync(adapter, registry);
4160
+ * if (!isSynced) {
4161
+ * console.warn("Native objects not synced, running sync...");
4162
+ * await syncNativeObjects(adapter, registry);
4163
+ * }
4164
+ * ```
4165
+ */
4166
+ declare function verifyNativeObjectsSync(adapter: DatabaseAdapter, nativeRegistry: typeof registry): Promise<boolean>;
4167
+ /**
4168
+ * Get sync statistics without modifying database
4169
+ *
4170
+ * @param adapter - Database adapter
4171
+ * @param nativeRegistry - Registry containing native objects
4172
+ * @returns Sync result (dry run)
4173
+ */
4174
+ declare function getSyncPreview(adapter: DatabaseAdapter, nativeRegistry: typeof registry): Promise<SyncResult>;
4175
+ /**
4176
+ * Result of full sync operation (objects + views)
4177
+ */
4178
+ interface FullSyncResult {
4179
+ success: boolean;
4180
+ objects: SyncResult;
4181
+ views: ViewSyncResult;
4182
+ }
4183
+ /**
4184
+ * Options for full sync
4185
+ */
4186
+ interface FullSyncOptions extends SyncOptions, ViewSyncOptions {
4187
+ }
4188
+ /**
4189
+ * Sync all native objects and views from registries to database
4190
+ *
4191
+ * This is a convenience function that:
4192
+ * 1. Syncs native objects first (views may depend on objects)
4193
+ * 2. Syncs native views
4194
+ *
4195
+ * @param adapter - Database adapter
4196
+ * @param objectRegistry - Registry containing native objects
4197
+ * @param nativeViewRegistry - Registry containing native views
4198
+ * @param options - Sync options
4199
+ * @returns Combined sync result
4200
+ *
4201
+ * @example
4202
+ * ```typescript
4203
+ * import { syncAll, registry, viewRegistry } from "@stndrds/schema";
4204
+ * import { adapter } from "./db";
4205
+ *
4206
+ * const result = await syncAll(adapter, registry, viewRegistry, {
4207
+ * verbose: true,
4208
+ * tenantId: "default"
4209
+ * });
4210
+ *
4211
+ * if (result.success) {
4212
+ * console.log(`✓ Synced ${result.objects.objectsSynced} objects, ${result.views.viewsSynced} views`);
4213
+ * }
4214
+ * ```
4215
+ */
4216
+ declare function syncAll(adapter: DatabaseAdapter, objectRegistry: typeof registry, nativeViewRegistry: typeof viewRegistry, options?: FullSyncOptions): Promise<FullSyncResult>;
4217
+
4218
+ /**
4219
+ * Default fallback value when expression resolves to empty string
4220
+ */
4221
+ declare const DEFAULT_LABEL_FALLBACK = "(Untitled)";
4222
+ /**
4223
+ * Render a label expression template with values
4224
+ *
4225
+ * Supports:
4226
+ * - Variable interpolation: `{{ fieldName }}`
4227
+ * - Dot notation: `{{ user.firstName }}`
4228
+ * - Pipes: `{{ name | UPPER }}`, `{{ name | capitalize | trim }}`
4229
+ *
4230
+ * @param template - The label expression template (e.g., "{{ firstName }} {{ lastName }}")
4231
+ * @param values - Record values to interpolate
4232
+ * @param fallback - Fallback value if result is empty (default: "(Untitled)")
4233
+ * @returns The rendered label string
4234
+ *
4235
+ * @example
4236
+ * ```typescript
4237
+ * const label = renderLabelExpression(
4238
+ * "{{ firstName }} {{ lastName | UPPER }}",
4239
+ * { firstName: "John", lastName: "Doe" }
4240
+ * );
4241
+ * // → "John DOE"
4242
+ *
4243
+ * // With missing values
4244
+ * const label = renderLabelExpression(
4245
+ * "{{ name }}",
4246
+ * { }
4247
+ * );
4248
+ * // → "(Untitled)"
4249
+ * ```
4250
+ */
4251
+ declare function renderLabelExpression(template: string, values: Record<string, unknown>, fallback?: string): string;
4252
+ /**
4253
+ * Check if a string is a valid label expression template
4254
+ * A valid template contains at least one {{ variable }} block with a non-empty variable
4255
+ */
4256
+ declare function isLabelExpression(value: string): boolean;
4257
+ /**
4258
+ * Extract attribute names referenced in a label expression
4259
+ * Useful for validation or dependency tracking
4260
+ *
4261
+ * @example
4262
+ * extractAttributeNames("{{ firstName }} {{ lastName | UPPER }}")
4263
+ * // → ["firstName", "lastName"]
4264
+ */
4265
+ declare function extractAttributeNames(template: string): string[];
4266
+
4267
+ export { type MultiselectFilterOperator as $, type Attribute as A, type BaseAttribute as B, type Currency as C, type DateAttribute as D, type RelationAttribute as E, type FileAttribute as F, type Group as G, type StorageProvider as H, type FileVisibility as I, type File as J, type CreateFile as K, type Location as L, type MultiselectAttribute as M, type NumberAttribute as N, type Option as O, type Phone as P, type UpdateFile as Q, type RelationOnDelete as R, type StatusAttribute as S, type TextAttribute as T, type UserAttribute as U, type ViewDefinition as V, type TextFilterOperator as W, type NumberFilterOperator as X, type CheckboxFilterOperator as Y, type DateFilterOperator as Z, type SelectFilterOperator as _, type SelectAttribute as a, attributeConfigSchemas as a$, type RelationFilterOperator as a0, type FilterOperator as a1, type RelativeDateValue as a2, type FilterValue as a3, type FilterRule as a4, type FilterCombinator as a5, type FilterState as a6, type FilterGroup as a7, type AdvancedFilterState as a8, isAdvancedFilterState as a9, type TableTab as aA, type CustomTab as aB, isFormTab as aC, isTableTab as aD, isCustomTab as aE, type Uuid as aF, type TenantId as aG, generateId as aH, generatePrefixedId as aI, registry as aJ, viewRegistry as aK, textConfigSchema as aL, textareaConfigSchema as aM, numberConfigSchema as aN, checkboxConfigSchema as aO, dateConfigSchema as aP, phoneConfigSchema as aQ, currencyConfigSchema as aR, statusConfigSchema as aS, locationConfigSchema as aT, timestampConfigSchema as aU, selectConfigSchema as aV, multiselectConfigSchema as aW, fileConfigSchema as aX, userConfigSchema as aY, relationConfigSchema as aZ, ratingConfigSchema as a_, toAdvancedFilterState as aa, toSimpleFilterState as ab, type SortDirection as ac, type SortRule as ad, type QueryState as ae, OPERATORS_BY_TYPE as af, type NoValueOperator as ag, NO_VALUE_OPERATORS as ah, isNoValueOperator as ai, type GeocodingSuggestion as aj, type GeocodingAutocompleteParams as ak, type ReverseGeocodingParams as al, type GeocodingParams as am, type GeocodingAdapter as an, NoopGeocodingAdapter as ao, type Timestamps as ap, type ObjectAttribute as aq, type CompletionStatus as ar, type ObjectRecord as as, type UserRole as at, type UserStatus as au, type UserProfile as av, type CreateUserProfile as aw, type UpdateUserProfile as ax, type TabType as ay, type FormTab as az, type TextAreaAttribute as b, type CreateViewInput as b$, getAttributeConfigSchema as b0, validateAttributeConfig as b1, parseAttributeConfig as b2, safeParseAttributeConfig as b3, createTextValidator as b4, createNumberValidator as b5, createCheckboxValidator as b6, createDateValidator as b7, createPhoneValidator as b8, createCurrencyValidator as b9, type HookDefinition as bA, type HookHandler as bB, type HookType as bC, NoopHookRegistry as bD, type HookRegistry as bE, createMockAdapter as bF, type ObjectsRepository as bG, type AttributesRepository as bH, type UserProfilesRepository as bI, type FilesRepository as bJ, type ObjectRecordsRepository as bK, type ViewsRepository as bL, FileService as bM, GeocodingService as bN, GlobalSearchService as bO, type CreateCustomObjectInput as bP, type AddAttributeInput as bQ, ObjectSchemaService as bR, type RecordServiceOptions as bS, RecordService as bT, type RelationValidationResult as bU, type RelationValidationError as bV, type RelationOption as bW, type RelationOptionsResponse as bX, type GetRelationOptionsParams as bY, RelationService as bZ, UserProfileService as b_, createStatusValidator as ba, createSelectValidator as bb, createMultiselectValidator as bc, createLocationValidator as bd, createTimestampValidator as be, createFileValidator as bf, createUserValidator as bg, createSingleRelationValidator as bh, createMultiRelationValidator as bi, createRelationValidator as bj, createRatingValidator as bk, createAttributeValidator as bl, createObjectValidator as bm, type ValidationResult as bn, validateAttribute as bo, validateObject as bp, validateObjectOrThrow as bq, createDraftValidator as br, validateDraft as bs, validateDraftOrThrow as bt, getMissingRequiredAttributes as bu, isRecordComplete as bv, computeRecordStatus as bw, type DatabaseAdapter as bx, type AttributeChange as by, type HookContext as bz, type CheckboxAttribute as c, type UpdateViewInput as c0, ViewService as c1, type SyncResult as c2, type SyncOptions as c3, syncNativeObjects as c4, verifyNativeObjectsSync as c5, getSyncPreview as c6, type FullSyncResult as c7, type FullSyncOptions as c8, syncAll as c9, verifyNativeViewsSync as cA, getViewSyncPreview as cB, DEFAULT_LABEL_FALLBACK as ca, renderLabelExpression as cb, isLabelExpression as cc, extractAttributeNames as cd, type DBObject as ce, type CreateDBObject as cf, type UpdateDBObject as cg, type UpsertDBObject as ch, type DBAttribute as ci, type CreateDBAttribute as cj, type UpdateDBAttribute as ck, type UpsertDBAttribute as cl, type CreateObjectRecord as cm, type ListOptions as cn, type SearchOptions as co, type GlobalSearchOptions as cp, type GlobalSearchResultItem as cq, type FileListOptions as cr, type DBView as cs, type CreateDBView as ct, type UpdateDBView as cu, type UpsertDBView as cv, type OperationResult as cw, type ViewSyncResult as cx, type ViewSyncOptions as cy, syncNativeViews as cz, type PhoneAttribute as d, type CurrencyAttribute as e, type LocationAttribute as f, type TimestampAttribute as g, type SingleRelationAttribute as h, type MultiRelationAttribute as i, type RelationTarget as j, type RatingAttribute as k, type ObjectDefinition as l, type Field as m, type AttributeGroupField as n, type Tab as o, type AttributeType as p, type StatusGroup as q, type AttributeGroup as r, type NumberUnit as s, type DateFormat as t, type DateValue as u, type LocationGranularity as v, type DocumentType as w, type DocumentFace as x, type DocumentTypeConfig as y, type FileVerificationConfig as z };