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