@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,1840 @@
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
+ * RelationAttribute links to other objects/records
212
+ * relation: array of object IDs that can be linked
213
+ * limit: maximum number of relations that can be selected
214
+ */
215
+ interface RelationAttribute extends BaseAttribute<string> {
216
+ type: "relation";
217
+ relation: string[];
218
+ limit?: number;
219
+ cascadeDelete?: boolean;
220
+ }
221
+ interface TextAreaAttribute extends BaseAttribute<string> {
222
+ type: "textarea";
223
+ }
224
+ interface RatingAttribute extends BaseAttribute<number> {
225
+ type: "rating";
226
+ max?: number;
227
+ iconType?: "star" | "heart" | "thumbs" | "number";
228
+ }
229
+ type Attribute = TextAttribute | TextAreaAttribute | NumberAttribute | CheckboxAttribute | DateAttribute | PhoneAttribute | CurrencyAttribute | StatusAttribute | LocationAttribute | TimestampAttribute | SelectAttribute | MultiselectAttribute | FileAttribute | UserAttribute | RelationAttribute | RatingAttribute;
230
+
231
+ /**
232
+ * Timestamps for tracking creation and updates
233
+ */
234
+ interface Timestamps {
235
+ createdAt: Date;
236
+ updatedAt: Date;
237
+ }
238
+ /**
239
+ * Object definition - Represents a database table/entity
240
+ */
241
+ interface ObjectDefinition {
242
+ id?: Uuid;
243
+ name: string;
244
+ label: string;
245
+ description?: string;
246
+ icon?: IconName;
247
+ /**
248
+ * Name of the text attribute used as the object's title/display name.
249
+ * This attribute is used to represent the record in lists, relations, etc.
250
+ * Must reference an existing text attribute.
251
+ */
252
+ titleAttribute: string;
253
+ attributes: Attribute[];
254
+ system?: boolean;
255
+ metadata?: Record<string, unknown>;
256
+ }
257
+ /**
258
+ * Links an attribute to an object
259
+ */
260
+ interface ObjectAttribute {
261
+ objectId: Uuid;
262
+ attributeId: Uuid;
263
+ order?: number;
264
+ required?: boolean;
265
+ }
266
+ /**
267
+ * Completion status of a record based on data completeness.
268
+ *
269
+ * - `draft`: Record is missing one or more required attribute values.
270
+ * Can be saved but is considered incomplete.
271
+ * - `complete`: All required attribute values are present and valid.
272
+ * Record is ready for use.
273
+ *
274
+ * This is different from workflow status (e.g., "pending", "approved").
275
+ * Completion status is computed dynamically based on the object schema.
276
+ */
277
+ type CompletionStatus = "draft" | "complete";
278
+ /**
279
+ * Record - Instance of an Object (a row in the database)
280
+ */
281
+ interface ObjectRecord extends Timestamps {
282
+ id: Uuid;
283
+ objectId: Uuid;
284
+ /**
285
+ * Completion status of the record.
286
+ * - `draft`: Missing required values, record is incomplete
287
+ * - `complete`: All required values present and valid
288
+ *
289
+ * Computed dynamically based on the object's schema.
290
+ */
291
+ completionStatus: CompletionStatus;
292
+ values: Record<string, unknown>;
293
+ }
294
+
295
+ /**
296
+ * Storage provider type
297
+ */
298
+ type StorageProvider = "s3" | "gcs" | "azure" | "local" | "cloudflare-r2" | string;
299
+ /**
300
+ * File visibility level
301
+ */
302
+ type FileVisibility = "public" | "private" | "restricted";
303
+ /**
304
+ * File - Represents uploaded file metadata and storage info
305
+ *
306
+ * ARCHITECTURE:
307
+ * - Fixed table (no custom attributes)
308
+ * - Manages file storage, permissions, and metadata
309
+ * - uploadedBy links to user_profiles table
310
+ * - Supports soft delete via deletedAt
311
+ *
312
+ * @example
313
+ * ```typescript
314
+ * const file: File = {
315
+ * id: "file-123",
316
+ * tenantId: "tenant-456",
317
+ * name: "contract-2025.pdf",
318
+ * originalName: "Contract Acme Corp 2025.pdf",
319
+ * mimeType: "application/pdf",
320
+ * size: 2458624,
321
+ * storageProvider: "s3",
322
+ * storagePath: "tenants/456/files/2025/11/contract-2025.pdf",
323
+ * storageBucket: "my-app-files",
324
+ * url: "https://cdn.example.com/files/file-123",
325
+ * uploadedBy: "profile-789",
326
+ * folderPath: "/contracts/2025",
327
+ * tags: ["contract", "legal"],
328
+ * visibility: "restricted",
329
+ * allowedUsers: ["profile-789", "profile-456"],
330
+ * createdAt: new Date(),
331
+ * updatedAt: new Date(),
332
+ * };
333
+ * ```
334
+ */
335
+ interface File extends Timestamps {
336
+ id: Uuid;
337
+ tenantId: Uuid;
338
+ /**
339
+ * File name (sanitized for storage)
340
+ */
341
+ name: string;
342
+ /**
343
+ * Original file name (as uploaded by user)
344
+ */
345
+ originalName: string;
346
+ /**
347
+ * MIME type (e.g., "application/pdf", "image/jpeg")
348
+ */
349
+ mimeType: MimeType | string;
350
+ /**
351
+ * File size in bytes
352
+ */
353
+ size: number;
354
+ /**
355
+ * Storage provider (s3, gcs, azure, local, etc.)
356
+ */
357
+ storageProvider: StorageProvider;
358
+ /**
359
+ * Path in the storage bucket
360
+ */
361
+ storagePath: string;
362
+ /**
363
+ * Storage bucket name (if applicable)
364
+ */
365
+ storageBucket?: string;
366
+ /**
367
+ * Public or signed URL to access the file
368
+ */
369
+ url: string;
370
+ /**
371
+ * User who uploaded the file (FK to user_profiles)
372
+ */
373
+ uploadedBy: Uuid;
374
+ /**
375
+ * Folder path for organization (e.g., "/contracts/2025")
376
+ */
377
+ folderPath?: string;
378
+ /**
379
+ * Tags for search and categorization
380
+ */
381
+ tags?: string[];
382
+ /**
383
+ * File visibility level
384
+ * - public: Anyone with the URL can access
385
+ * - private: Only uploadedBy can access
386
+ * - restricted: Only specific users (allowedUsers) can access
387
+ */
388
+ visibility: FileVisibility;
389
+ /**
390
+ * List of user IDs authorized to access this file (if visibility = "restricted")
391
+ */
392
+ allowedUsers?: Uuid[];
393
+ /**
394
+ * Soft delete timestamp (null = not deleted)
395
+ */
396
+ deletedAt?: Date;
397
+ }
398
+ /**
399
+ * Data required to create a new file record
400
+ */
401
+ interface CreateFile {
402
+ tenantId: Uuid;
403
+ name: string;
404
+ originalName: string;
405
+ mimeType: MimeType | string;
406
+ size: number;
407
+ storageProvider: StorageProvider;
408
+ storagePath: string;
409
+ storageBucket?: string;
410
+ url: string;
411
+ uploadedBy: Uuid;
412
+ folderPath?: string;
413
+ tags?: string[];
414
+ visibility?: FileVisibility;
415
+ allowedUsers?: Uuid[];
416
+ }
417
+ /**
418
+ * Data for updating an existing file record
419
+ */
420
+ interface UpdateFile {
421
+ name?: string;
422
+ folderPath?: string;
423
+ tags?: string[];
424
+ visibility?: FileVisibility;
425
+ allowedUsers?: Uuid[];
426
+ }
427
+
428
+ /**
429
+ * User role in the application
430
+ * Can be extended with custom roles as needed
431
+ */
432
+ type UserRole = "admin" | "member" | "guest" | string;
433
+ /**
434
+ * User status for account management
435
+ */
436
+ type UserStatus = "active" | "pending" | "inactive" | "suspended";
437
+ /**
438
+ * User Profile - Represents application user data (authorization)
439
+ *
440
+ * ARCHITECTURE:
441
+ * - authId links to external auth provider (Supabase, Clerk, Auth0, etc.)
442
+ * - email is denormalized from auth provider for performance
443
+ * - Auth provider handles authentication (passwords, sessions, OAuth)
444
+ * - This type handles authorization (roles, permissions, tenant membership)
445
+ *
446
+ * @example
447
+ * ```typescript
448
+ * const profile: UserProfile = {
449
+ * id: "profile-123",
450
+ * tenantId: "tenant-456",
451
+ * authId: "supabase-auth-uuid-789",
452
+ * email: "john@example.com",
453
+ * firstName: "John",
454
+ * lastName: "Doe",
455
+ * role: "admin",
456
+ * status: "active",
457
+ * createdAt: new Date(),
458
+ * updatedAt: new Date(),
459
+ * };
460
+ * ```
461
+ */
462
+ interface UserProfile extends Timestamps {
463
+ id: Uuid;
464
+ tenantId: Uuid;
465
+ /**
466
+ * Link to external auth provider (Supabase auth.users.id, Clerk user ID, etc.)
467
+ * This is the bridge between authentication (provider) and authorization (your app)
468
+ */
469
+ authId: string;
470
+ /**
471
+ * Email address (denormalized from auth provider)
472
+ * Allows efficient querying and filtering without hitting auth provider API
473
+ */
474
+ email: string;
475
+ /**
476
+ * User's first name
477
+ */
478
+ firstName?: string;
479
+ /**
480
+ * User's last name
481
+ */
482
+ lastName?: string;
483
+ /**
484
+ * Avatar/profile picture URL
485
+ */
486
+ avatarUrl?: string;
487
+ /**
488
+ * User role for authorization
489
+ * Common values: "admin", "member", "guest"
490
+ * Can be extended with custom roles
491
+ */
492
+ role: UserRole;
493
+ /**
494
+ * Account status
495
+ * - active: Normal user, full access
496
+ * - pending: Awaiting activation/approval
497
+ * - inactive: Deactivated account
498
+ * - suspended: Temporarily blocked
499
+ */
500
+ status: UserStatus;
501
+ /**
502
+ * Last login timestamp (updated on each successful auth)
503
+ */
504
+ lastLoginAt?: Date;
505
+ }
506
+ /**
507
+ * Data required to create a new user profile
508
+ */
509
+ interface CreateUserProfile {
510
+ tenantId: Uuid;
511
+ authId: string;
512
+ email: string;
513
+ firstName?: string;
514
+ lastName?: string;
515
+ avatarUrl?: string;
516
+ role?: UserRole;
517
+ status?: UserStatus;
518
+ }
519
+ /**
520
+ * Data for updating an existing user profile
521
+ */
522
+ interface UpdateUserProfile {
523
+ firstName?: string;
524
+ lastName?: string;
525
+ avatarUrl?: string;
526
+ role?: UserRole;
527
+ status?: UserStatus;
528
+ lastLoginAt?: Date;
529
+ }
530
+
531
+ /**
532
+ * Registry for native objects defined in code
533
+ * Native objects are system objects that cannot be deleted/modified by clients
534
+ * They are defined by developers and synced to the database at startup
535
+ */
536
+ declare class NativeObjectRegistryClass {
537
+ private objects;
538
+ /**
539
+ * Register one or more native objects
540
+ * Auto-builds if ObjectBuilder is passed instead of ObjectDefinition
541
+ * @param objects - Single object/builder or array of objects/builders to register
542
+ * @returns this (for chaining)
543
+ * @throws Error if object is invalid or already registered
544
+ *
545
+ * @example
546
+ * ```typescript
547
+ * // No .build() needed - registry auto-builds!
548
+ * const PRODUCT = object({ id: "obj-product", name: "products", label: "Product" })
549
+ * .system()
550
+ * .attribute(text({ id: "attr-name", name: "name", label: "Name" }));
551
+ *
552
+ * registry.register(PRODUCT); // ← Auto-builds here
553
+ *
554
+ * // Can still explicitly .build() if you want
555
+ * registry.register(PRODUCT.build());
556
+ *
557
+ * // Register multiple
558
+ * registry.register([PRODUCT, ORDER, CUSTOMER]);
559
+ * ```
560
+ */
561
+ register(objects: ObjectDefinition | ObjectDefinition[] | {
562
+ build: () => ObjectDefinition;
563
+ } | Array<{
564
+ build: () => ObjectDefinition;
565
+ }>): this;
566
+ /**
567
+ * Validate and register a single object
568
+ * @internal
569
+ */
570
+ private validateAndRegister;
571
+ /**
572
+ * Get a native object by its name
573
+ * @param name - The object name
574
+ * @returns The object definition or undefined if not found
575
+ *
576
+ * @example
577
+ * ```typescript
578
+ * const product = registry.getByName("products");
579
+ * if (product) {
580
+ * console.log(product.label); // "Product"
581
+ * }
582
+ * ```
583
+ */
584
+ getByName(name: string): ObjectDefinition | undefined;
585
+ /**
586
+ * Get a native object or throw if not found
587
+ * @param name - The object name
588
+ * @returns The object definition
589
+ * @throws Error if not found
590
+ */
591
+ getByNameOrThrow(name: string): ObjectDefinition;
592
+ /**
593
+ * Get all registered native objects
594
+ * @returns Array of all registered object definitions
595
+ */
596
+ getAll(): ObjectDefinition[];
597
+ /**
598
+ * Get all registered native object names
599
+ * @returns Array of object names
600
+ */
601
+ listNames(): string[];
602
+ /**
603
+ * Check if a native object is registered
604
+ * @param name - The object name
605
+ * @returns true if registered, false otherwise
606
+ */
607
+ has(name: string): boolean;
608
+ /**
609
+ * Get the number of registered objects
610
+ */
611
+ get size(): number;
612
+ /**
613
+ * Clear all registered objects (useful for testing)
614
+ * @internal
615
+ */
616
+ clear(): void;
617
+ /**
618
+ * Get registry summary for debugging
619
+ */
620
+ summary(): string;
621
+ /**
622
+ * Log registry summary to console
623
+ */
624
+ debug(): void;
625
+ }
626
+ /**
627
+ * Singleton instance of the registry
628
+ * Use this to register and retrieve native objects
629
+ *
630
+ * @example
631
+ * ```typescript
632
+ * import { registry } from "@andyoucreate/schema";
633
+ *
634
+ * // Register objects
635
+ * registry.register([PRODUCT, ORDER, CUSTOMER]);
636
+ *
637
+ * // Get object by name
638
+ * const product = registry.getByName("products");
639
+ *
640
+ * // List all
641
+ * console.log(registry.listNames()); // ["products", "orders", ...]
642
+ *
643
+ * // Debug
644
+ * registry.debug();
645
+ * ```
646
+ */
647
+ declare const registry: NativeObjectRegistryClass;
648
+
649
+ /**
650
+ * Create a Zod schema for a text attribute
651
+ */
652
+ declare function createTextValidator(attr: TextAttribute): z.ZodString;
653
+ /**
654
+ * Create a Zod schema for a number attribute
655
+ */
656
+ declare function createNumberValidator(attr: NumberAttribute): z.ZodNumber;
657
+ /**
658
+ * Create a Zod schema for a checkbox attribute
659
+ */
660
+ declare function createCheckboxValidator(_attr: CheckboxAttribute): z.ZodBoolean;
661
+ /**
662
+ * Create a Zod schema for a date attribute
663
+ */
664
+ declare function createDateValidator(attr: DateAttribute): z.ZodString;
665
+ /**
666
+ * Create a Zod schema for a phone attribute
667
+ */
668
+ declare function createPhoneValidator(_attr: PhoneAttribute): z.ZodType<{
669
+ countryCode: string;
670
+ phoneNumber: string;
671
+ }>;
672
+ /**
673
+ * Create a Zod schema for a currency attribute
674
+ */
675
+ declare function createCurrencyValidator(_attr: CurrencyAttribute): z.ZodType<{
676
+ code: string;
677
+ value: number;
678
+ }>;
679
+ /**
680
+ * Create a Zod schema for a status attribute
681
+ */
682
+ declare function createStatusValidator(attr: StatusAttribute): z.ZodEnum<[string, ...string[]]>;
683
+ /**
684
+ * Create a Zod schema for a select attribute
685
+ */
686
+ declare function createSelectValidator(attr: SelectAttribute): z.ZodEnum<[string, ...string[]]>;
687
+ /**
688
+ * Create a Zod schema for a multiselect attribute
689
+ */
690
+ declare function createMultiselectValidator(attr: MultiselectAttribute): z.ZodArray<z.ZodEnum<[string, ...string[]]>>;
691
+ /**
692
+ * Create a Zod schema for a location attribute
693
+ */
694
+ type LocationShape = {
695
+ address?: string;
696
+ address2?: string;
697
+ city?: string;
698
+ state?: string;
699
+ postalCode?: string;
700
+ country?: string;
701
+ latitude?: number;
702
+ longitude?: number;
703
+ };
704
+ declare function createLocationValidator(_attr: LocationAttribute): z.ZodType<LocationShape>;
705
+ /**
706
+ * Create a Zod schema for a timestamp attribute
707
+ */
708
+ declare function createTimestampValidator(_attr: TimestampAttribute): z.ZodNumber;
709
+ /**
710
+ * Create a Zod schema for a file attribute
711
+ */
712
+ declare function createFileValidator(_attr: FileAttribute): z.ZodString;
713
+ /**
714
+ * Create a Zod schema for a user attribute
715
+ */
716
+ declare function createUserValidator(_attr: UserAttribute): z.ZodString;
717
+ /**
718
+ * Create a Zod schema for a relation attribute
719
+ */
720
+ declare function createRelationValidator(_attr: RelationAttribute): z.ZodString;
721
+ /**
722
+ * Create a Zod schema for a rating attribute
723
+ */
724
+ declare function createRatingValidator(attr: RatingAttribute): z.ZodNumber;
725
+ /**
726
+ * Create a Zod schema for any attribute type
727
+ */
728
+ declare function createAttributeValidator(attr: Attribute): z.ZodTypeAny;
729
+ /**
730
+ * Create a Zod schema for an entire object
731
+ */
732
+ declare function createObjectValidator(objectDef: ObjectDefinition): z.ZodType<Record<string, unknown>>;
733
+ /**
734
+ * Validation result
735
+ */
736
+ interface ValidationResult {
737
+ success: boolean;
738
+ data?: Record<string, unknown>;
739
+ errors?: Array<{
740
+ path: string[];
741
+ message: string;
742
+ }>;
743
+ }
744
+ /**
745
+ * Validate data against an attribute schema
746
+ */
747
+ declare function validateAttribute(attr: Attribute, value: unknown): ValidationResult;
748
+ /**
749
+ * Validate data against an object schema
750
+ */
751
+ declare function validateObject(objectDef: ObjectDefinition, data: Record<string, unknown>): ValidationResult;
752
+ /**
753
+ * Validate and throw if invalid
754
+ */
755
+ declare function validateObjectOrThrow(objectDef: ObjectDefinition, data: Record<string, unknown>): Record<string, unknown>;
756
+ /**
757
+ * Create a Zod schema for draft validation.
758
+ * All attributes become optional, but provided values are still validated.
759
+ */
760
+ declare function createDraftValidator(objectDef: ObjectDefinition): z.ZodType<Record<string, unknown>>;
761
+ /**
762
+ * Validate data in draft mode.
763
+ * - All attributes are treated as optional (no required validation)
764
+ * - Provided values are still validated for format/type correctness
765
+ *
766
+ * Use this when creating records that may be incomplete (drafts).
767
+ *
768
+ * @example
769
+ * ```typescript
770
+ * const result = validateDraft(PRODUCT, { name: "Draft" });
771
+ * // → success even if "price" is required but missing
772
+ *
773
+ * const result2 = validateDraft(PRODUCT, { price: -10 });
774
+ * // → fails because price must be >= 0 (format validation still applies)
775
+ * ```
776
+ */
777
+ declare function validateDraft(objectDef: ObjectDefinition, data: Record<string, unknown>): ValidationResult;
778
+ /**
779
+ * Validate draft data and throw if format validation fails.
780
+ */
781
+ declare function validateDraftOrThrow(objectDef: ObjectDefinition, data: Record<string, unknown>): Record<string, unknown>;
782
+ /**
783
+ * Get the list of required attributes that are missing values.
784
+ *
785
+ * @example
786
+ * ```typescript
787
+ * const missing = getMissingRequiredAttributes(PRODUCT, { name: "Test" });
788
+ * // → [priceAttribute, statusAttribute] if price and status are required but missing
789
+ * ```
790
+ */
791
+ declare function getMissingRequiredAttributes(objectDef: ObjectDefinition, data: Record<string, unknown>): Attribute[];
792
+ /**
793
+ * Check if a record is complete (all required attributes have valid values).
794
+ *
795
+ * @returns `true` if all required values are present and valid, `false` otherwise
796
+ */
797
+ declare function isRecordComplete(objectDef: ObjectDefinition, data: Record<string, unknown>): boolean;
798
+ /**
799
+ * Compute the completion status of a record based on its data.
800
+ *
801
+ * - `"complete"`: All required values are present and valid
802
+ * - `"draft"`: One or more required values are missing or invalid
803
+ *
804
+ * This function is used to dynamically determine the status when
805
+ * creating or updating records.
806
+ *
807
+ * @example
808
+ * ```typescript
809
+ * const status = computeRecordStatus(PRODUCT, {
810
+ * name: "Nike Air Max",
811
+ * price: 129.99,
812
+ * status: "active"
813
+ * });
814
+ * // → "complete"
815
+ *
816
+ * const status2 = computeRecordStatus(PRODUCT, { name: "Draft Product" });
817
+ * // → "draft" (missing required fields)
818
+ * ```
819
+ */
820
+ declare function computeRecordStatus(objectDef: ObjectDefinition, data: Record<string, unknown>): CompletionStatus;
821
+
822
+ /**
823
+ * Object as stored in database (metadata)
824
+ */
825
+ interface DBObject extends Timestamps {
826
+ id: Uuid;
827
+ tenantId: TenantId;
828
+ name: string;
829
+ label: string;
830
+ description?: string;
831
+ icon?: IconName;
832
+ system: boolean;
833
+ metadata?: Record<string, unknown>;
834
+ }
835
+ interface CreateDBObject {
836
+ tenantId: TenantId;
837
+ name: string;
838
+ label: string;
839
+ description?: string;
840
+ icon?: IconName;
841
+ system?: boolean;
842
+ metadata?: Record<string, unknown>;
843
+ }
844
+ interface UpdateDBObject {
845
+ label?: string;
846
+ description?: string;
847
+ icon?: IconName;
848
+ metadata?: Record<string, unknown>;
849
+ }
850
+ interface UpsertDBObject extends CreateDBObject {
851
+ system: boolean;
852
+ }
853
+ /**
854
+ * Attribute as stored in database (metadata)
855
+ */
856
+ interface DBAttribute extends Timestamps {
857
+ id: Uuid;
858
+ objectId: Uuid;
859
+ name: string;
860
+ label: string;
861
+ type: AttributeType;
862
+ description?: string;
863
+ icon?: IconName;
864
+ system: boolean;
865
+ required: boolean;
866
+ unique: boolean;
867
+ order: number;
868
+ hidden?: boolean;
869
+ archived?: boolean;
870
+ deprecated?: boolean;
871
+ defaultValue?: unknown;
872
+ config: Record<string, unknown>;
873
+ }
874
+ interface CreateDBAttribute {
875
+ objectId: Uuid;
876
+ name: string;
877
+ label: string;
878
+ type: AttributeType;
879
+ description?: string;
880
+ icon?: IconName;
881
+ system?: boolean;
882
+ required?: boolean;
883
+ unique?: boolean;
884
+ order?: number;
885
+ hidden?: boolean;
886
+ archived?: boolean;
887
+ deprecated?: boolean;
888
+ defaultValue?: unknown;
889
+ config?: Record<string, unknown>;
890
+ }
891
+ interface UpdateDBAttribute {
892
+ label?: string;
893
+ description?: string;
894
+ icon?: IconName;
895
+ required?: boolean;
896
+ order?: number;
897
+ hidden?: boolean;
898
+ archived?: boolean;
899
+ deprecated?: boolean;
900
+ defaultValue?: unknown;
901
+ config?: Record<string, unknown>;
902
+ }
903
+ interface UpsertDBAttribute extends CreateDBAttribute {
904
+ objectId: Uuid;
905
+ name: string;
906
+ }
907
+
908
+ /**
909
+ * Object record creation data
910
+ */
911
+ interface CreateObjectRecord {
912
+ tenantId: TenantId;
913
+ objectId: Uuid;
914
+ data: Record<string, unknown>;
915
+ /**
916
+ * Completion status of the record.
917
+ * - `draft`: Record is incomplete (missing required values)
918
+ * - `complete`: All required values are present and valid
919
+ */
920
+ completionStatus: "draft" | "complete";
921
+ }
922
+ /**
923
+ * Generic list options for pagination and sorting
924
+ */
925
+ interface ListOptions {
926
+ limit?: number;
927
+ offset?: number;
928
+ orderBy?: string;
929
+ orderDirection?: "asc" | "desc";
930
+ }
931
+ /**
932
+ * Search options for full-text search
933
+ */
934
+ interface SearchOptions extends ListOptions {
935
+ filters?: Record<string, unknown>;
936
+ highlight?: boolean;
937
+ }
938
+ /**
939
+ * File-specific list options
940
+ */
941
+ interface FileListOptions extends ListOptions {
942
+ folderPath?: string;
943
+ mimeType?: string;
944
+ uploadedBy?: Uuid;
945
+ includeDeleted?: boolean;
946
+ }
947
+ /**
948
+ * Result of an operation
949
+ */
950
+ interface OperationResult<T = unknown> {
951
+ success: boolean;
952
+ data?: T;
953
+ error?: {
954
+ code: string;
955
+ message: string;
956
+ details?: Record<string, unknown>;
957
+ };
958
+ }
959
+
960
+ /**
961
+ * Repository for objects table (metadata)
962
+ */
963
+ interface ObjectsRepository {
964
+ /**
965
+ * Find object by ID
966
+ */
967
+ findById(id: Uuid): Promise<DBObject | null>;
968
+ /**
969
+ * Find object by name and tenant
970
+ */
971
+ findByName(tenantId: TenantId, name: string): Promise<DBObject | null>;
972
+ /**
973
+ * Find system/native object by name (system=true, for sync)
974
+ */
975
+ findSystemByName(name: string): Promise<DBObject | null>;
976
+ /**
977
+ * Create object
978
+ */
979
+ create(data: CreateDBObject): Promise<DBObject>;
980
+ /**
981
+ * Update object
982
+ */
983
+ update(id: Uuid, data: Partial<UpdateDBObject>): Promise<DBObject>;
984
+ /**
985
+ * Delete object
986
+ */
987
+ delete(id: Uuid): Promise<void>;
988
+ /**
989
+ * List all objects for a tenant
990
+ */
991
+ list(tenantId: TenantId): Promise<DBObject[]>;
992
+ /**
993
+ * Upsert object (create or update based on nativeObjectId)
994
+ */
995
+ upsert(data: UpsertDBObject): Promise<DBObject>;
996
+ }
997
+ /**
998
+ * Repository for attributes table (metadata)
999
+ */
1000
+ interface AttributesRepository {
1001
+ /**
1002
+ * Find attribute by ID
1003
+ */
1004
+ findById(id: Uuid): Promise<DBAttribute | null>;
1005
+ /**
1006
+ * Find attributes by object ID
1007
+ */
1008
+ findByObjectId(objectId: Uuid): Promise<DBAttribute[]>;
1009
+ /**
1010
+ * Create attribute
1011
+ */
1012
+ create(data: CreateDBAttribute): Promise<DBAttribute>;
1013
+ /**
1014
+ * Update attribute
1015
+ */
1016
+ update(id: Uuid, data: Partial<UpdateDBAttribute>): Promise<DBAttribute>;
1017
+ /**
1018
+ * Delete attribute
1019
+ */
1020
+ delete(id: Uuid): Promise<void>;
1021
+ /**
1022
+ * Delete multiple attributes by names (for sync cleanup)
1023
+ */
1024
+ deleteByNames(objectId: Uuid, excludeNames: string[]): Promise<number>;
1025
+ /**
1026
+ * Upsert attribute (create or update based on objectId + name)
1027
+ */
1028
+ upsert(data: UpsertDBAttribute): Promise<DBAttribute>;
1029
+ }
1030
+ /**
1031
+ * Repository for user_profiles table
1032
+ */
1033
+ interface UserProfilesRepository {
1034
+ /**
1035
+ * Find user profile by ID
1036
+ */
1037
+ findById(id: Uuid): Promise<UserProfile | null>;
1038
+ /**
1039
+ * Find user profile by auth ID (external auth provider)
1040
+ */
1041
+ findByAuthId(authId: string): Promise<UserProfile | null>;
1042
+ /**
1043
+ * Find user profile by email
1044
+ */
1045
+ findByEmail(tenantId: TenantId, email: string): Promise<UserProfile | null>;
1046
+ /**
1047
+ * Create user profile
1048
+ */
1049
+ create(data: CreateUserProfile): Promise<UserProfile>;
1050
+ /**
1051
+ * Update user profile
1052
+ */
1053
+ update(id: Uuid, data: UpdateUserProfile): Promise<UserProfile>;
1054
+ /**
1055
+ * Delete user profile
1056
+ */
1057
+ delete(id: Uuid): Promise<void>;
1058
+ /**
1059
+ * List all user profiles for a tenant
1060
+ */
1061
+ list(tenantId: TenantId, options?: ListOptions): Promise<UserProfile[]>;
1062
+ /**
1063
+ * Update last login timestamp
1064
+ */
1065
+ updateLastLogin(id: Uuid): Promise<void>;
1066
+ }
1067
+ /**
1068
+ * Repository for files table
1069
+ */
1070
+ interface FilesRepository {
1071
+ /**
1072
+ * Find file by ID
1073
+ */
1074
+ findById(id: Uuid): Promise<File | null>;
1075
+ /**
1076
+ * Create file
1077
+ */
1078
+ create(data: CreateFile): Promise<File>;
1079
+ /**
1080
+ * Update file
1081
+ */
1082
+ update(id: Uuid, data: UpdateFile): Promise<File>;
1083
+ /**
1084
+ * Delete file (soft delete)
1085
+ */
1086
+ delete(id: Uuid): Promise<void>;
1087
+ /**
1088
+ * Hard delete file (permanent)
1089
+ */
1090
+ hardDelete(id: Uuid): Promise<void>;
1091
+ /**
1092
+ * List files for a tenant
1093
+ */
1094
+ list(tenantId: TenantId, options?: FileListOptions): Promise<File[]>;
1095
+ /**
1096
+ * Find files by folder path
1097
+ */
1098
+ findByFolder(tenantId: TenantId, folderPath: string): Promise<File[]>;
1099
+ /**
1100
+ * Find files by uploader
1101
+ */
1102
+ findByUploader(uploadedBy: Uuid): Promise<File[]>;
1103
+ }
1104
+ /**
1105
+ * Repository for object_records table (unified JSONB)
1106
+ */
1107
+ interface ObjectRecordsRepository {
1108
+ /**
1109
+ * Find record by ID
1110
+ */
1111
+ findById(id: Uuid): Promise<ObjectRecord | null>;
1112
+ /**
1113
+ * Create record
1114
+ */
1115
+ create(data: CreateObjectRecord): Promise<ObjectRecord>;
1116
+ /**
1117
+ * Update record
1118
+ */
1119
+ update(id: Uuid, data: Partial<Record<string, unknown>>): Promise<ObjectRecord>;
1120
+ /**
1121
+ * Delete record
1122
+ */
1123
+ delete(id: Uuid): Promise<void>;
1124
+ /**
1125
+ * List records for an object
1126
+ */
1127
+ list(tenantId: TenantId, objectId: Uuid, options?: ListOptions): Promise<{
1128
+ records: ObjectRecord[];
1129
+ total: number;
1130
+ }>;
1131
+ /**
1132
+ * Search records using PostgreSQL full-text search
1133
+ */
1134
+ search(tenantId: TenantId, objectId: Uuid, query: string, options?: SearchOptions): Promise<{
1135
+ records: ObjectRecord[];
1136
+ total: number;
1137
+ }>;
1138
+ }
1139
+
1140
+ /**
1141
+ * Generic database adapter interface
1142
+ * Any ORM (Drizzle, Prisma, Kysely, TypeORM) can implement this interface
1143
+ * to work with @andyoucreate/schema runtime services
1144
+ *
1145
+ * @example
1146
+ * ```typescript
1147
+ * // Drizzle implementation
1148
+ * import { createDrizzleAdapter } from "./adapters/drizzle";
1149
+ * import { db } from "./db";
1150
+ *
1151
+ * const adapter = createDrizzleAdapter(db);
1152
+ *
1153
+ * // Prisma implementation
1154
+ * import { createPrismaAdapter } from "./adapters/prisma";
1155
+ * import { prisma } from "./db";
1156
+ *
1157
+ * const adapter = createPrismaAdapter(prisma);
1158
+ * ```
1159
+ */
1160
+ interface DatabaseAdapter {
1161
+ objects: ObjectsRepository;
1162
+ attributes: AttributesRepository;
1163
+ userProfiles: UserProfilesRepository;
1164
+ files: FilesRepository;
1165
+ objectRecords: ObjectRecordsRepository;
1166
+ transaction<T>(callback: (adapter: DatabaseAdapter) => Promise<T>): Promise<T>;
1167
+ }
1168
+
1169
+ interface InternalObjectRecord extends ObjectRecord {
1170
+ tenantId: TenantId;
1171
+ }
1172
+ interface MockStores {
1173
+ objects: Map<Uuid, DBObject>;
1174
+ attributes: Map<Uuid, DBAttribute>;
1175
+ userProfiles: Map<Uuid, UserProfile>;
1176
+ files: Map<Uuid, File>;
1177
+ objectRecords: Map<Uuid, InternalObjectRecord>;
1178
+ }
1179
+ /**
1180
+ * Create an in-memory mock adapter for testing and development
1181
+ *
1182
+ * This adapter stores all data in memory and is perfect for:
1183
+ * - Unit tests
1184
+ * - Integration tests
1185
+ * - Local development without a database
1186
+ * - Understanding the adapter interface
1187
+ *
1188
+ * @returns A DatabaseAdapter implementation using in-memory storage
1189
+ *
1190
+ * @example
1191
+ * ```typescript
1192
+ * import { createMockAdapter, RecordService } from "@andyoucreate/schema";
1193
+ *
1194
+ * // Create adapter
1195
+ * const adapter = createMockAdapter();
1196
+ *
1197
+ * // Use with services
1198
+ * const recordService = new RecordService(adapter, "tenant-123");
1199
+ *
1200
+ * // Create a record
1201
+ * const product = await recordService.createRecord("obj-product", {
1202
+ * name: "Nike Air Max",
1203
+ * price: 129.99
1204
+ * });
1205
+ *
1206
+ * // List records
1207
+ * const { records, total } = await recordService.listRecords("obj-product");
1208
+ * ```
1209
+ */
1210
+ declare function createMockAdapter(): DatabaseAdapter & {
1211
+ _stores: MockStores;
1212
+ reset(): void;
1213
+ };
1214
+
1215
+ /**
1216
+ * Service for managing files
1217
+ * Handles file metadata CRUD, permissions, and soft delete
1218
+ */
1219
+ declare class FileService {
1220
+ private adapter;
1221
+ private tenantId;
1222
+ constructor(adapter: DatabaseAdapter, tenantId: string);
1223
+ /**
1224
+ * Create a new file record (after upload to storage)
1225
+ *
1226
+ * @param data - File metadata
1227
+ * @returns Created file record
1228
+ *
1229
+ * @example
1230
+ * ```typescript
1231
+ * const service = new FileService(adapter, "tenant-123");
1232
+ *
1233
+ * // After uploading to S3
1234
+ * const file = await service.createFile({
1235
+ * tenantId: "tenant-123",
1236
+ * name: "contract-2025.pdf",
1237
+ * originalName: "Contract Acme Corp 2025.pdf",
1238
+ * mimeType: "application/pdf",
1239
+ * size: 2458624,
1240
+ * storageProvider: "s3",
1241
+ * storagePath: "tenants/123/files/2025/contract.pdf",
1242
+ * storageBucket: "my-app-files",
1243
+ * url: "https://cdn.example.com/files/file-123",
1244
+ * uploadedBy: "profile-456",
1245
+ * visibility: "private"
1246
+ * });
1247
+ * ```
1248
+ */
1249
+ createFile(data: CreateFile): Promise<File>;
1250
+ /**
1251
+ * Get file by ID
1252
+ */
1253
+ getFile(fileId: string): Promise<File | null>;
1254
+ /**
1255
+ * Get file by ID or throw
1256
+ */
1257
+ getFileOrThrow(fileId: string): Promise<File>;
1258
+ /**
1259
+ * Update file metadata
1260
+ *
1261
+ * @param fileId - File UUID
1262
+ * @param data - Data to update
1263
+ * @returns Updated file
1264
+ */
1265
+ updateFile(fileId: string, data: UpdateFile): Promise<File>;
1266
+ /**
1267
+ * Delete file (soft delete)
1268
+ *
1269
+ * @param fileId - File UUID
1270
+ * @param options - Delete options
1271
+ */
1272
+ deleteFile(fileId: string, options?: {
1273
+ hard?: boolean;
1274
+ checkOwnership?: boolean;
1275
+ userId?: string;
1276
+ }): Promise<void>;
1277
+ /**
1278
+ * List files for the tenant
1279
+ */
1280
+ listFiles(options?: FileListOptions): Promise<File[]>;
1281
+ /**
1282
+ * List files by folder
1283
+ */
1284
+ listFilesByFolder(folderPath: string): Promise<File[]>;
1285
+ /**
1286
+ * List files uploaded by a specific user
1287
+ */
1288
+ listFilesByUploader(uploadedBy: string): Promise<File[]>;
1289
+ /**
1290
+ * Change file visibility
1291
+ *
1292
+ * @param fileId - File UUID
1293
+ * @param visibility - New visibility level
1294
+ * @param allowedUsers - Users allowed to access (if restricted)
1295
+ */
1296
+ changeVisibility(fileId: string, visibility: "public" | "private" | "restricted", allowedUsers?: string[]): Promise<File>;
1297
+ /**
1298
+ * Grant access to a file for specific users
1299
+ *
1300
+ * @param fileId - File UUID
1301
+ * @param userIds - User IDs to grant access
1302
+ */
1303
+ grantAccess(fileId: string, userIds: string[]): Promise<File>;
1304
+ /**
1305
+ * Revoke access to a file for specific users
1306
+ *
1307
+ * @param fileId - File UUID
1308
+ * @param userIds - User IDs to revoke access
1309
+ */
1310
+ revokeAccess(fileId: string, userIds: string[]): Promise<File>;
1311
+ /**
1312
+ * Check if user has access to a file
1313
+ *
1314
+ * @param fileId - File UUID
1315
+ * @param userId - User ID to check
1316
+ * @returns true if user can access the file
1317
+ */
1318
+ canAccess(fileId: string, userId: string): Promise<boolean>;
1319
+ /**
1320
+ * Move file to different folder
1321
+ */
1322
+ moveToFolder(fileId: string, newFolderPath: string): Promise<File>;
1323
+ /**
1324
+ * Add tags to file
1325
+ */
1326
+ addTags(fileId: string, tags: string[]): Promise<File>;
1327
+ /**
1328
+ * Remove tags from file
1329
+ */
1330
+ removeTags(fileId: string, tags: string[]): Promise<File>;
1331
+ }
1332
+
1333
+ /**
1334
+ * Input for creating a custom object
1335
+ */
1336
+ interface CreateCustomObjectInput {
1337
+ name: string;
1338
+ label: string;
1339
+ description?: string;
1340
+ icon?: IconName;
1341
+ attributes?: (Attribute | {
1342
+ build: () => Attribute;
1343
+ })[];
1344
+ metadata?: Record<string, unknown>;
1345
+ }
1346
+ /**
1347
+ * Input for adding an attribute to an object
1348
+ */
1349
+ interface AddAttributeInput {
1350
+ name: string;
1351
+ label: string;
1352
+ type: AttributeType;
1353
+ required?: boolean;
1354
+ unique?: boolean;
1355
+ description?: string;
1356
+ placeholder?: string;
1357
+ icon?: IconName;
1358
+ defaultValue?: unknown;
1359
+ metadata?: Record<string, unknown>;
1360
+ [key: string]: unknown;
1361
+ }
1362
+ /**
1363
+ * Service for managing object schemas
1364
+ * Handles fusion of native objects (from registry) and custom objects (from database)
1365
+ */
1366
+ declare class ObjectSchemaService {
1367
+ private adapter;
1368
+ private nativeRegistry;
1369
+ constructor(adapter: DatabaseAdapter, nativeRegistry: typeof registry);
1370
+ /**
1371
+ * Create a new custom object
1372
+ * Validates name format and ensures system=false
1373
+ *
1374
+ * @param definition - Object definition (attributes can be raw definitions or builders)
1375
+ * @param tenantId - Tenant ID owning the object
1376
+ * @returns Created ObjectDefinition
1377
+ */
1378
+ createCustomObject(definition: CreateCustomObjectInput, tenantId: string): Promise<ObjectDefinition>;
1379
+ /**
1380
+ * Add a custom attribute to an existing object
1381
+ * Can be used on both custom and native objects
1382
+ * Attributes added via API are always custom (system=false)
1383
+ *
1384
+ * @param objectId - Object UUID from database
1385
+ * @param attribute - Attribute definition
1386
+ * @returns Created Attribute
1387
+ */
1388
+ addAttributeToObject(objectId: string, attribute: AddAttributeInput): Promise<Attribute>;
1389
+ /**
1390
+ * Update an attribute
1391
+ * Can only update custom attributes (system=false)
1392
+ *
1393
+ * @param attributeId - Attribute UUID
1394
+ * @param updates - Partial attribute updates
1395
+ * @returns Updated Attribute
1396
+ */
1397
+ updateAttribute(attributeId: string, updates: Partial<AddAttributeInput>): Promise<Attribute>;
1398
+ /**
1399
+ * Delete an attribute
1400
+ * Can only delete custom attributes (system=false)
1401
+ *
1402
+ * @param attributeId - Attribute UUID
1403
+ */
1404
+ deleteAttribute(attributeId: string): Promise<void>;
1405
+ /**
1406
+ * List attributes for an object
1407
+ *
1408
+ * @param objectId - Object UUID
1409
+ * @param options - Filter options
1410
+ * @returns List of attributes
1411
+ */
1412
+ listAttributes(objectId: string, options?: {
1413
+ systemOnly?: boolean;
1414
+ customOnly?: boolean;
1415
+ }): Promise<Attribute[]>;
1416
+ /**
1417
+ * Validate attribute name format (variable identifier)
1418
+ * @internal
1419
+ */
1420
+ private validateAttributeName;
1421
+ /**
1422
+ * Get complete object schema (system + custom attributes)
1423
+ * If object is native, merges registry definition with DB custom attributes
1424
+ * If object is custom, returns DB definition only
1425
+ *
1426
+ * @param objectId - Object UUID from database
1427
+ * @returns Complete ObjectDefinition with all attributes
1428
+ *
1429
+ * @example
1430
+ * ```typescript
1431
+ * const service = new ObjectSchemaService(adapter, registry);
1432
+ * const productSchema = await service.getObjectSchema("obj-123");
1433
+ *
1434
+ * console.log(productSchema.attributes); // System + custom attributes
1435
+ * ```
1436
+ */
1437
+ getObjectSchema(objectId: string): Promise<ObjectDefinition>;
1438
+ /**
1439
+ * Get object schema by name (for system/native objects)
1440
+ */
1441
+ getObjectSchemaByName(name: string): Promise<ObjectDefinition>;
1442
+ /**
1443
+ * List all object schemas for a tenant
1444
+ */
1445
+ listObjectSchemas(tenantId: string): Promise<ObjectDefinition[]>;
1446
+ /**
1447
+ * Merge native object from registry with custom attributes from DB
1448
+ * @internal
1449
+ */
1450
+ private mergeNativeObject;
1451
+ /**
1452
+ * Convert DB object + attributes to ObjectDefinition
1453
+ * @internal
1454
+ */
1455
+ private convertDBObjectToDefinition;
1456
+ /**
1457
+ * Convert DB attribute to Attribute type
1458
+ * @internal
1459
+ */
1460
+ private convertDBAttributeToAttribute;
1461
+ }
1462
+
1463
+ /**
1464
+ * Service for managing object records (CRUD operations)
1465
+ * Handles validation, dispatch to correct table, and data consistency
1466
+ */
1467
+ declare class RecordService {
1468
+ private adapter;
1469
+ private tenantId;
1470
+ private schemaService;
1471
+ constructor(adapter: DatabaseAdapter, tenantId: string);
1472
+ /**
1473
+ * Create a new record with validation
1474
+ *
1475
+ * @param objectId - Object UUID
1476
+ * @param data - Record data (attribute values)
1477
+ * @param options - Creation options
1478
+ * @returns Created record with computed completionStatus
1479
+ *
1480
+ * @example
1481
+ * ```typescript
1482
+ * const service = new RecordService(adapter, "tenant-123");
1483
+ *
1484
+ * // Create a complete record (strict validation)
1485
+ * const product = await service.createRecord("obj-product", {
1486
+ * name: "Nike Air Max",
1487
+ * price: 129.99,
1488
+ * status: "active"
1489
+ * });
1490
+ * // → product.completionStatus = "complete"
1491
+ *
1492
+ * // Create a draft record (allows missing required fields)
1493
+ * const draft = await service.createRecord("obj-product", {
1494
+ * name: "Draft Product"
1495
+ * }, { allowDraft: true });
1496
+ * // → draft.completionStatus = "draft"
1497
+ * ```
1498
+ */
1499
+ createRecord(objectId: string, data: Record<string, unknown>, options?: {
1500
+ /**
1501
+ * Allow creating records with missing required fields.
1502
+ * Format validation still applies to provided values.
1503
+ * @default false
1504
+ */
1505
+ allowDraft?: boolean;
1506
+ /**
1507
+ * Skip all validation.
1508
+ * @default true
1509
+ */
1510
+ validate?: boolean;
1511
+ skipSystemCheck?: boolean;
1512
+ }): Promise<ObjectRecord>;
1513
+ /**
1514
+ * Get a record by ID
1515
+ *
1516
+ * @param recordId - Record UUID
1517
+ * @param options - Query options
1518
+ * @returns Record or null if not found
1519
+ */
1520
+ getRecord(recordId: string, options?: {
1521
+ includeSchema?: boolean;
1522
+ }): Promise<ObjectRecord | null>;
1523
+ /**
1524
+ * Get a record by ID or throw if not found
1525
+ */
1526
+ getRecordOrThrow(recordId: string): Promise<ObjectRecord>;
1527
+ /**
1528
+ * Update a record with validation
1529
+ *
1530
+ * The completion status is automatically recalculated after each update.
1531
+ * A draft record becomes complete when all required fields are filled.
1532
+ *
1533
+ * @param recordId - Record UUID
1534
+ * @param data - Partial data to update
1535
+ * @param options - Update options
1536
+ * @returns Updated record with recalculated completionStatus
1537
+ *
1538
+ * @example
1539
+ * ```typescript
1540
+ * // Update a draft record to make it complete
1541
+ * const updated = await service.updateRecord(draftId, {
1542
+ * price: 99.99,
1543
+ * status: "active"
1544
+ * });
1545
+ * // → updated.completionStatus = "complete" if all required fields now present
1546
+ * ```
1547
+ */
1548
+ updateRecord(recordId: string, data: Partial<Record<string, unknown>>, options?: {
1549
+ /**
1550
+ * Skip validation entirely.
1551
+ * @default true
1552
+ */
1553
+ validate?: boolean;
1554
+ /**
1555
+ * Allow partial updates without strict validation.
1556
+ * Format validation still applies to provided values.
1557
+ * @default false
1558
+ */
1559
+ partial?: boolean;
1560
+ }): Promise<ObjectRecord>;
1561
+ /**
1562
+ * Delete a record
1563
+ *
1564
+ * @param recordId - Record UUID
1565
+ * @param options - Delete options
1566
+ */
1567
+ deleteRecord(recordId: string, options?: {
1568
+ checkSystem?: boolean;
1569
+ }): Promise<void>;
1570
+ /**
1571
+ * List records for an object with pagination
1572
+ *
1573
+ * @param objectId - Object UUID
1574
+ * @param options - List options
1575
+ * @returns Records and total count
1576
+ */
1577
+ listRecords(objectId: string, options?: {
1578
+ limit?: number;
1579
+ offset?: number;
1580
+ orderBy?: string;
1581
+ orderDirection?: "asc" | "desc";
1582
+ }): Promise<{
1583
+ records: ObjectRecord[];
1584
+ total: number;
1585
+ }>;
1586
+ /**
1587
+ * Search records using full-text search
1588
+ *
1589
+ * @param objectId - Object UUID
1590
+ * @param query - Search query
1591
+ * @param options - Search options
1592
+ * @returns Matching records and total count
1593
+ */
1594
+ searchRecords(objectId: string, query: string, options?: {
1595
+ limit?: number;
1596
+ offset?: number;
1597
+ filters?: Record<string, unknown>;
1598
+ }): Promise<{
1599
+ records: ObjectRecord[];
1600
+ total: number;
1601
+ }>;
1602
+ /**
1603
+ * Validate data against object schema without saving
1604
+ *
1605
+ * @param objectId - Object UUID
1606
+ * @param data - Data to validate
1607
+ * @returns Validation result
1608
+ */
1609
+ validateData(objectId: string, data: Record<string, unknown>): Promise<ValidationResult>;
1610
+ /**
1611
+ * Compute the completion status for given data without saving.
1612
+ * Useful for UI to show draft/complete status before submitting.
1613
+ *
1614
+ * @param objectId - Object UUID
1615
+ * @param data - Data to check
1616
+ * @returns Computed completion status
1617
+ */
1618
+ computeStatus(objectId: string, data: Record<string, unknown>): Promise<CompletionStatus>;
1619
+ /**
1620
+ * Refresh the completion status of an existing record.
1621
+ * Useful when schema changes and you need to recompute statuses.
1622
+ *
1623
+ * @param recordId - Record UUID
1624
+ * @returns Updated completion status
1625
+ */
1626
+ refreshRecordStatus(recordId: string): Promise<CompletionStatus>;
1627
+ }
1628
+
1629
+ /**
1630
+ * Service for managing user profiles
1631
+ * Handles user profile CRUD, auth provider sync, and role management
1632
+ */
1633
+ declare class UserProfileService {
1634
+ private adapter;
1635
+ private tenantId;
1636
+ constructor(adapter: DatabaseAdapter, tenantId: string);
1637
+ /**
1638
+ * Create a new user profile (typically after first auth)
1639
+ *
1640
+ * @param data - User profile creation data
1641
+ * @returns Created user profile
1642
+ *
1643
+ * @example
1644
+ * ```typescript
1645
+ * const service = new UserProfileService(adapter, "tenant-123");
1646
+ *
1647
+ * // After Supabase auth
1648
+ * const profile = await service.createProfile({
1649
+ * tenantId: "tenant-123",
1650
+ * authId: authUser.id,
1651
+ * email: authUser.email,
1652
+ * firstName: authUser.user_metadata.first_name,
1653
+ * lastName: authUser.user_metadata.last_name,
1654
+ * role: "member",
1655
+ * status: "active"
1656
+ * });
1657
+ * ```
1658
+ */
1659
+ createProfile(data: CreateUserProfile): Promise<UserProfile>;
1660
+ /**
1661
+ * Get user profile by ID
1662
+ */
1663
+ getProfile(profileId: string): Promise<UserProfile | null>;
1664
+ /**
1665
+ * Get user profile by ID or throw
1666
+ */
1667
+ getProfileOrThrow(profileId: string): Promise<UserProfile>;
1668
+ /**
1669
+ * Get user profile by auth provider ID
1670
+ *
1671
+ * @param authId - Auth provider user ID (Supabase, Clerk, etc.)
1672
+ * @returns User profile or null
1673
+ */
1674
+ getProfileByAuthId(authId: string): Promise<UserProfile | null>;
1675
+ /**
1676
+ * Get or create user profile (idempotent operation)
1677
+ * Useful for auth callbacks - ensures profile exists
1678
+ *
1679
+ * @param authId - Auth provider user ID
1680
+ * @param data - Profile data to create if doesn't exist
1681
+ * @returns Existing or newly created profile
1682
+ *
1683
+ * @example
1684
+ * ```typescript
1685
+ * // In Supabase auth callback
1686
+ * const profile = await service.getOrCreateProfile(
1687
+ * authUser.id,
1688
+ * {
1689
+ * tenantId: "tenant-123",
1690
+ * authId: authUser.id,
1691
+ * email: authUser.email,
1692
+ * role: "member",
1693
+ * status: "active"
1694
+ * }
1695
+ * );
1696
+ * ```
1697
+ */
1698
+ getOrCreateProfile(authId: string, data: CreateUserProfile): Promise<UserProfile>;
1699
+ /**
1700
+ * Update user profile
1701
+ */
1702
+ updateProfile(profileId: string, data: UpdateUserProfile): Promise<UserProfile>;
1703
+ /**
1704
+ * Delete user profile
1705
+ *
1706
+ * @param profileId - Profile UUID
1707
+ * @param options - Delete options
1708
+ */
1709
+ deleteProfile(profileId: string, options?: {
1710
+ checkAdmin?: boolean;
1711
+ }): Promise<void>;
1712
+ /**
1713
+ * List all user profiles for the tenant
1714
+ */
1715
+ listProfiles(options?: ListOptions): Promise<UserProfile[]>;
1716
+ /**
1717
+ * Update last login timestamp
1718
+ *
1719
+ * @param profileId - Profile UUID
1720
+ *
1721
+ * @example
1722
+ * ```typescript
1723
+ * // After successful auth
1724
+ * await service.updateLastLogin(profile.id);
1725
+ * ```
1726
+ */
1727
+ updateLastLogin(profileId: string): Promise<void>;
1728
+ /**
1729
+ * Change user role
1730
+ *
1731
+ * @param profileId - Profile UUID
1732
+ * @param newRole - New role
1733
+ */
1734
+ changeRole(profileId: string, newRole: string): Promise<UserProfile>;
1735
+ /**
1736
+ * Change user status
1737
+ *
1738
+ * @param profileId - Profile UUID
1739
+ * @param newStatus - New status
1740
+ */
1741
+ changeStatus(profileId: string, newStatus: "active" | "pending" | "inactive" | "suspended"): Promise<UserProfile>;
1742
+ /**
1743
+ * Get user by email
1744
+ */
1745
+ getProfileByEmail(email: string): Promise<UserProfile | null>;
1746
+ /**
1747
+ * Check if user has role
1748
+ */
1749
+ hasRole(profileId: string, role: string): Promise<boolean>;
1750
+ /**
1751
+ * Check if user is admin
1752
+ */
1753
+ isAdmin(profileId: string): Promise<boolean>;
1754
+ }
1755
+
1756
+ /**
1757
+ * Result of sync operation
1758
+ */
1759
+ interface SyncResult {
1760
+ success: boolean;
1761
+ objectsSynced: number;
1762
+ attributesSynced: number;
1763
+ objectsCreated: number;
1764
+ objectsUpdated: number;
1765
+ attributesCreated: number;
1766
+ attributesUpdated: number;
1767
+ attributesDeleted: number;
1768
+ errors: Array<{
1769
+ objectName: string;
1770
+ error: string;
1771
+ }>;
1772
+ }
1773
+ /**
1774
+ * Sync options
1775
+ */
1776
+ interface SyncOptions {
1777
+ dryRun?: boolean;
1778
+ verbose?: boolean;
1779
+ tenantId?: string;
1780
+ }
1781
+ /**
1782
+ * Sync native objects from registry to database
1783
+ *
1784
+ * This function:
1785
+ * 1. Reads all registered native objects from the registry
1786
+ * 2. Upserts them into the database (objects + attributes tables)
1787
+ * 3. Marks them as system=true for protection
1788
+ * 4. Removes attributes that were deleted from code
1789
+ *
1790
+ * @param adapter - Database adapter implementing DatabaseAdapter interface
1791
+ * @param nativeRegistry - Registry containing native objects
1792
+ * @param options - Sync options (dryRun, verbose, tenantId)
1793
+ * @returns Sync result with statistics
1794
+ *
1795
+ * @example
1796
+ * ```typescript
1797
+ * import { syncNativeObjects } from "@andyoucreate/schema/runtime";
1798
+ * import { registry } from "./objects/native";
1799
+ * import { drizzleAdapter } from "./db/adapter";
1800
+ *
1801
+ * const result = await syncNativeObjects(drizzleAdapter, registry, {
1802
+ * verbose: true,
1803
+ * tenantId: "default"
1804
+ * });
1805
+ *
1806
+ * if (result.success) {
1807
+ * console.log(`✓ Synced ${result.objectsSynced} objects`);
1808
+ * } else {
1809
+ * console.error("Sync errors:", result.errors);
1810
+ * }
1811
+ * ```
1812
+ */
1813
+ declare function syncNativeObjects(adapter: DatabaseAdapter, nativeRegistry: typeof registry, options?: SyncOptions): Promise<SyncResult>;
1814
+ /**
1815
+ * Verify that all native objects are synced to database
1816
+ *
1817
+ * @param adapter - Database adapter
1818
+ * @param nativeRegistry - Registry containing native objects
1819
+ * @returns true if all objects are synced, false otherwise
1820
+ *
1821
+ * @example
1822
+ * ```typescript
1823
+ * const isSynced = await verifyNativeObjectsSync(adapter, registry);
1824
+ * if (!isSynced) {
1825
+ * console.warn("Native objects not synced, running sync...");
1826
+ * await syncNativeObjects(adapter, registry);
1827
+ * }
1828
+ * ```
1829
+ */
1830
+ declare function verifyNativeObjectsSync(adapter: DatabaseAdapter, nativeRegistry: typeof registry): Promise<boolean>;
1831
+ /**
1832
+ * Get sync statistics without modifying database
1833
+ *
1834
+ * @param adapter - Database adapter
1835
+ * @param nativeRegistry - Registry containing native objects
1836
+ * @returns Sync result (dry run)
1837
+ */
1838
+ declare function getSyncPreview(adapter: DatabaseAdapter, nativeRegistry: typeof registry): Promise<SyncResult>;
1839
+
1840
+ export { createTextValidator as $, type Attribute as A, type BaseAttribute as B, type Currency as C, type DateAttribute as D, type ObjectAttribute as E, type FileAttribute as F, type CompletionStatus as G, type ObjectRecord as H, type UserRole as I, type UserStatus as J, type UserProfile as K, type Location as L, type MultiselectAttribute as M, type NumberAttribute as N, type Option as O, type Phone as P, type CreateUserProfile as Q, type RelationAttribute as R, type StatusAttribute as S, type TextAttribute as T, type UserAttribute as U, type UpdateUserProfile as V, type Uuid as W, type TenantId as X, generateId as Y, generatePrefixedId as Z, registry as _, type SelectAttribute as a, createNumberValidator as a0, createCheckboxValidator as a1, createDateValidator as a2, createPhoneValidator as a3, createCurrencyValidator as a4, createStatusValidator as a5, createSelectValidator as a6, createMultiselectValidator as a7, createLocationValidator as a8, createTimestampValidator as a9, ObjectSchemaService as aA, RecordService as aB, UserProfileService as aC, type SyncResult as aD, type SyncOptions as aE, syncNativeObjects as aF, verifyNativeObjectsSync as aG, getSyncPreview as aH, type DBObject as aI, type CreateDBObject as aJ, type UpdateDBObject as aK, type UpsertDBObject as aL, type DBAttribute as aM, type CreateDBAttribute as aN, type UpdateDBAttribute as aO, type UpsertDBAttribute as aP, type CreateObjectRecord as aQ, type ListOptions as aR, type SearchOptions as aS, type FileListOptions as aT, type OperationResult as aU, createFileValidator as aa, createUserValidator as ab, createRelationValidator as ac, createRatingValidator as ad, createAttributeValidator as ae, createObjectValidator as af, type ValidationResult as ag, validateAttribute as ah, validateObject as ai, validateObjectOrThrow as aj, createDraftValidator as ak, validateDraft as al, validateDraftOrThrow as am, getMissingRequiredAttributes as an, isRecordComplete as ao, computeRecordStatus as ap, type DatabaseAdapter as aq, createMockAdapter as ar, type ObjectsRepository as as, type AttributesRepository as at, type UserProfilesRepository as au, type FilesRepository as av, type ObjectRecordsRepository as aw, FileService as ax, type CreateCustomObjectInput as ay, type AddAttributeInput as az, type TextAreaAttribute as b, type CheckboxAttribute as c, type PhoneAttribute as d, type CurrencyAttribute as e, type LocationAttribute as f, type TimestampAttribute as g, type RatingAttribute as h, type ObjectDefinition as i, type AttributeType as j, type StatusGroup as k, type AttributeGroup as l, type NumberUnit as m, type DateFormat as n, type DateValue as o, type LocationGranularity as p, type DocumentType as q, type DocumentFace as r, type DocumentTypeConfig as s, type FileVerificationConfig as t, type StorageProvider as u, type FileVisibility as v, type File as w, type CreateFile as x, type UpdateFile as y, type Timestamps as z };