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