@stndrds/schema 0.1.0-alpha.67 → 1.0.0-alpha.102

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 (155) hide show
  1. package/dist/attributes-D7yQuTJK.d.mts +665 -0
  2. package/dist/attributes-DcbQC-4b.d.ts +665 -0
  3. package/dist/chunk-3JINFUN3.js +81 -0
  4. package/dist/chunk-4KRLCWJM.mjs +8 -0
  5. package/dist/chunk-4TC27SMF.mjs +18 -0
  6. package/dist/chunk-56QI6UTK.js +32 -0
  7. package/dist/chunk-5JVVPJJW.mjs +208 -0
  8. package/dist/chunk-5XL3JP73.mjs +83 -0
  9. package/dist/chunk-7HFZ7MVR.mjs +28 -0
  10. package/dist/chunk-ACQ3TUFK.js +10 -0
  11. package/dist/chunk-AYCSVKI2.mjs +14 -0
  12. package/dist/chunk-BLXQGQLK.mjs +10 -0
  13. package/dist/chunk-D7WFIGXW.js +14 -0
  14. package/dist/chunk-FRCDMQER.js +47 -0
  15. package/dist/chunk-GCRHSPZN.js +16 -0
  16. package/dist/chunk-IRTRJH37.mjs +8 -0
  17. package/dist/chunk-ITTQ4FGR.mjs +14 -0
  18. package/dist/chunk-J5HRK3WD.js +10 -0
  19. package/dist/chunk-KNYZH2WD.mjs +18 -0
  20. package/dist/chunk-KWVCGQ7N.mjs +78 -0
  21. package/dist/chunk-MAKSIK3P.js +10 -0
  22. package/dist/chunk-N7T66JVY.js +86 -0
  23. package/dist/chunk-OAQWRMTP.js +10 -0
  24. package/dist/chunk-OLJLCVNY.mjs +8 -0
  25. package/dist/chunk-P2BE2A2G.js +64 -0
  26. package/dist/chunk-PGERPYDR.js +2 -0
  27. package/dist/chunk-QWZHR2OO.js +12 -0
  28. package/dist/chunk-QY6QFRRV.mjs +41 -0
  29. package/dist/chunk-QYNPB37W.js +221 -0
  30. package/dist/chunk-R4CJHCC4.mjs +60 -0
  31. package/dist/chunk-RJ4LOX7P.js +22 -0
  32. package/dist/chunk-ROAZLZA2.js +20 -0
  33. package/dist/chunk-RUYUFXNW.mjs +12 -0
  34. package/dist/chunk-SP3PNHYF.mjs +1 -0
  35. package/dist/chunk-SS2NR6DH.mjs +176 -0
  36. package/dist/chunk-T225DB55.js +33 -0
  37. package/dist/chunk-TKN73433.js +20 -0
  38. package/dist/chunk-TMYBEXBT.mjs +8 -0
  39. package/dist/chunk-UQVW4KPP.mjs +30 -0
  40. package/dist/chunk-V6DE3MXC.js +180 -0
  41. package/dist/chunk-VXOTYFEW.js +16 -0
  42. package/dist/chunk-WV4V64D5.mjs +20 -0
  43. package/dist/helpers-DD6JzYfI.d.mts +860 -0
  44. package/dist/helpers-kMS5R7KX.d.ts +860 -0
  45. package/dist/index.d.mts +3597 -1768
  46. package/dist/index.d.ts +3597 -1768
  47. package/dist/index.js +4957 -1955
  48. package/dist/index.mjs +3920 -1116
  49. package/dist/types-BAPgWlpX.d.mts +39 -0
  50. package/dist/types-mZPUEZl0.d.ts +39 -0
  51. package/dist/utils.d.mts +20 -55
  52. package/dist/utils.d.ts +20 -55
  53. package/dist/utils.js +26 -19
  54. package/dist/utils.mjs +1 -19
  55. package/dist/validation/all.d.mts +8 -0
  56. package/dist/validation/all.d.ts +8 -0
  57. package/dist/validation/all.js +56 -0
  58. package/dist/validation/all.mjs +19 -0
  59. package/dist/validation/complex/currency.d.mts +15 -0
  60. package/dist/validation/complex/currency.d.ts +15 -0
  61. package/dist/validation/complex/currency.js +11 -0
  62. package/dist/validation/complex/currency.mjs +2 -0
  63. package/dist/validation/complex/file.d.mts +13 -0
  64. package/dist/validation/complex/file.d.ts +13 -0
  65. package/dist/validation/complex/file.js +11 -0
  66. package/dist/validation/complex/file.mjs +2 -0
  67. package/dist/validation/complex/location.d.mts +22 -0
  68. package/dist/validation/complex/location.d.ts +22 -0
  69. package/dist/validation/complex/location.js +11 -0
  70. package/dist/validation/complex/location.mjs +2 -0
  71. package/dist/validation/complex/phone.d.mts +22 -0
  72. package/dist/validation/complex/phone.d.ts +22 -0
  73. package/dist/validation/complex/phone.js +11 -0
  74. package/dist/validation/complex/phone.mjs +2 -0
  75. package/dist/validation/complex/relation.d.mts +25 -0
  76. package/dist/validation/complex/relation.d.ts +25 -0
  77. package/dist/validation/complex/relation.js +19 -0
  78. package/dist/validation/complex/relation.mjs +2 -0
  79. package/dist/validation/complex/richtext.d.mts +13 -0
  80. package/dist/validation/complex/richtext.d.ts +13 -0
  81. package/dist/validation/complex/richtext.js +11 -0
  82. package/dist/validation/complex/richtext.mjs +2 -0
  83. package/dist/validation/complex/select.d.mts +20 -0
  84. package/dist/validation/complex/select.d.ts +20 -0
  85. package/dist/validation/complex/select.js +19 -0
  86. package/dist/validation/complex/select.mjs +2 -0
  87. package/dist/validation/complex/user.d.mts +13 -0
  88. package/dist/validation/complex/user.d.ts +13 -0
  89. package/dist/validation/complex/user.js +11 -0
  90. package/dist/validation/complex/user.mjs +2 -0
  91. package/dist/validation/computed/formula.d.mts +14 -0
  92. package/dist/validation/computed/formula.d.ts +14 -0
  93. package/dist/validation/computed/formula.js +11 -0
  94. package/dist/validation/computed/formula.mjs +2 -0
  95. package/dist/validation/computed/rollup.d.mts +14 -0
  96. package/dist/validation/computed/rollup.d.ts +14 -0
  97. package/dist/validation/computed/rollup.js +11 -0
  98. package/dist/validation/computed/rollup.mjs +2 -0
  99. package/dist/validation/config/index.d.mts +20 -0
  100. package/dist/validation/config/index.d.ts +20 -0
  101. package/dist/validation/config/index.js +18 -0
  102. package/dist/validation/config/index.mjs +1 -0
  103. package/dist/validation/core/index.d.mts +19 -0
  104. package/dist/validation/core/index.d.ts +19 -0
  105. package/dist/validation/core/index.js +14 -0
  106. package/dist/validation/core/index.mjs +1 -0
  107. package/dist/validation/object/index.d.mts +31 -0
  108. package/dist/validation/object/index.d.ts +31 -0
  109. package/dist/validation/object/index.js +70 -0
  110. package/dist/validation/object/index.mjs +17 -0
  111. package/dist/validation/primitives/checkbox.d.mts +12 -0
  112. package/dist/validation/primitives/checkbox.d.ts +12 -0
  113. package/dist/validation/primitives/checkbox.js +11 -0
  114. package/dist/validation/primitives/checkbox.mjs +2 -0
  115. package/dist/validation/primitives/date.d.mts +12 -0
  116. package/dist/validation/primitives/date.d.ts +12 -0
  117. package/dist/validation/primitives/date.js +11 -0
  118. package/dist/validation/primitives/date.mjs +2 -0
  119. package/dist/validation/primitives/number.d.mts +12 -0
  120. package/dist/validation/primitives/number.d.ts +12 -0
  121. package/dist/validation/primitives/number.js +11 -0
  122. package/dist/validation/primitives/number.mjs +2 -0
  123. package/dist/validation/primitives/rating.d.mts +12 -0
  124. package/dist/validation/primitives/rating.d.ts +12 -0
  125. package/dist/validation/primitives/rating.js +11 -0
  126. package/dist/validation/primitives/rating.mjs +2 -0
  127. package/dist/validation/primitives/text.d.mts +17 -0
  128. package/dist/validation/primitives/text.d.ts +17 -0
  129. package/dist/validation/primitives/text.js +15 -0
  130. package/dist/validation/primitives/text.mjs +2 -0
  131. package/package.json +108 -13
  132. package/dist/chunk-36UBIXJN.js +0 -82
  133. package/dist/chunk-3RG5ZIWI.js +0 -10
  134. package/dist/chunk-A6T4UUZ2.mjs +0 -18669
  135. package/dist/chunk-NEVERCM3.js +0 -41
  136. package/dist/chunk-SV4BCGQU.mjs +0 -617
  137. package/dist/chunk-TOTUS3YS.js +0 -18669
  138. package/dist/chunk-U4AB53AM.js +0 -617
  139. package/dist/chunk-V2RPPE2Y.mjs +0 -41
  140. package/dist/chunk-V5QXU2OK.mjs +0 -82
  141. package/dist/chunk-Y6FXYEAI.mjs +0 -10
  142. package/dist/default-roles-42X3TJI5.mjs +0 -21
  143. package/dist/default-roles-C3FYDYMN.js +0 -21
  144. package/dist/runtime-BgtwoMx5.d.ts +0 -12759
  145. package/dist/runtime-DQlTgVZJ.d.mts +0 -12759
  146. package/dist/runtime.d.mts +0 -6
  147. package/dist/runtime.d.ts +0 -6
  148. package/dist/runtime.js +0 -323
  149. package/dist/runtime.mjs +0 -323
  150. package/dist/validation/validators.d.mts +0 -4
  151. package/dist/validation/validators.d.ts +0 -4
  152. package/dist/validation/validators.js +0 -121
  153. package/dist/validation/validators.mjs +0 -121
  154. package/dist/validators-BROsLGn4.d.mts +0 -1556
  155. package/dist/validators-CEzdvxEq.d.ts +0 -1556
@@ -0,0 +1,860 @@
1
+ import { z } from 'zod';
2
+ import { A as Attribute, j as AttributeType, f as RollupAttribute } from './attributes-DcbQC-4b.js';
3
+ import { V as ValidationMessages, a as ValidationResult } from './types-mZPUEZl0.js';
4
+ import { IconName } from '@stndrds/constants';
5
+ import { Uuid } from './utils.js';
6
+
7
+ /** Operators for text-based attributes */
8
+ type TextFilterOperator = "is" | "is_not" | "contains" | "not_contains" | "starts_with" | "ends_with" | "is_empty" | "is_not_empty";
9
+ /** Operators for number-based attributes */
10
+ type NumberFilterOperator = "eq" | "neq" | "lt" | "gt" | "lte" | "gte" | "is_empty" | "is_not_empty";
11
+ /** Operators for checkbox */
12
+ type CheckboxFilterOperator = "is_checked" | "is_not_checked";
13
+ /** Operators for date-based attributes */
14
+ type DateFilterOperator = "is" | "is_not" | "before" | "after" | "on_or_before" | "on_or_after" | "is_within" | "is_empty" | "is_not_empty";
15
+ /** Operators for select-based attributes (supports single or multi-value filtering) */
16
+ type SelectFilterOperator = "is" | "is_not" | "any_of" | "none_of" | "is_empty" | "is_not_empty";
17
+ /** Operators for multiselect-based attributes */
18
+ type MultiselectFilterOperator = "contains" | "not_contains" | "is_empty" | "is_not_empty";
19
+ /** Operators for relation-based attributes (supports single or multi-value filtering) */
20
+ type RelationFilterOperator = "any_of" | "none_of" | "contains" | "not_contains" | "is_empty" | "is_not_empty";
21
+ /** All possible filter operators */
22
+ type FilterOperator = TextFilterOperator | NumberFilterOperator | CheckboxFilterOperator | DateFilterOperator | SelectFilterOperator | MultiselectFilterOperator | RelationFilterOperator;
23
+ /** Relative date value for "is_within" operator */
24
+ interface RelativeDateValue {
25
+ amount: number;
26
+ unit: "days" | "weeks" | "months" | "years";
27
+ direction: "past" | "future";
28
+ }
29
+ /** Currency filter value with amount and optional currency codes
30
+ * - code: undefined or [] = any currency
31
+ * - code: string[] = filter by specific currencies
32
+ */
33
+ interface CurrencyFilterValue {
34
+ value: number | null;
35
+ code?: string[];
36
+ }
37
+ /** Phone filter value with number and optional country code */
38
+ interface PhoneFilterValue {
39
+ phoneNumber: string | null;
40
+ countryCode?: string;
41
+ }
42
+ /** Filter value can be various types depending on the attribute */
43
+ type FilterValue = string | number | boolean | string[] | RelativeDateValue | CurrencyFilterValue | PhoneFilterValue | null;
44
+ /** A single filter rule */
45
+ interface FilterRule {
46
+ /** Attribute name to filter on */
47
+ attribute: string;
48
+ /** Filter operator */
49
+ operator: FilterOperator;
50
+ /** Filter value (null for operators like is_empty) */
51
+ value: FilterValue;
52
+ }
53
+ /**
54
+ * Extended filter rule with optional attribute definition.
55
+ * When provided, enables smarter type-aware filtering (e.g., array operators for multiselect).
56
+ */
57
+ interface ExtendedFilterRule extends FilterRule {
58
+ /** Full attribute definition for type-aware filtering */
59
+ attributeDef?: Attribute;
60
+ }
61
+ /** Combinator for filter rules */
62
+ type FilterCombinator = "and" | "or";
63
+ /** Complete filter state (simple mode) */
64
+ interface FilterState {
65
+ /** How to combine rules */
66
+ combinator: FilterCombinator;
67
+ /** List of filter rules */
68
+ rules: FilterRule[];
69
+ }
70
+ /**
71
+ * A filter group containing rules (used in advanced mode)
72
+ * Groups can be nested up to 2 levels deep
73
+ */
74
+ interface FilterGroup {
75
+ /** Unique identifier for this group */
76
+ id: string;
77
+ /** How to combine rules within this group */
78
+ combinator: FilterCombinator;
79
+ /** List of filter rules in this group */
80
+ rules: FilterRule[];
81
+ }
82
+ /**
83
+ * Advanced filter state with nested groups
84
+ * Structure: AdvancedFilterState -> FilterGroup[] -> FilterRule[]
85
+ * Maximum 2 levels of nesting
86
+ */
87
+ interface AdvancedFilterState {
88
+ /** How to combine groups at the top level */
89
+ combinator: FilterCombinator;
90
+ /** List of filter groups */
91
+ groups: FilterGroup[];
92
+ }
93
+ /** Sort direction */
94
+ type SortDirection = "asc" | "desc";
95
+ /** A single sort rule */
96
+ interface SortRule {
97
+ /** Attribute name to sort by */
98
+ attribute: string;
99
+ /** Sort direction */
100
+ direction: SortDirection;
101
+ }
102
+ /** Complete query state with search, filters, sorts, and pagination */
103
+ interface QueryState {
104
+ /** Full-text search query */
105
+ search?: string;
106
+ /** Filter configuration (simple mode) */
107
+ filters?: FilterState;
108
+ /** Advanced filter configuration (grouped mode) */
109
+ advancedFilters?: AdvancedFilterState;
110
+ /** Sort configuration (multiple sorts supported) */
111
+ sorts?: SortRule[];
112
+ /** Pagination */
113
+ limit?: number;
114
+ offset?: number;
115
+ }
116
+ /** Mapping of attribute types to their valid operators (rollup excluded — use getRollupFilterOperators()) */
117
+ declare const OPERATORS_BY_TYPE: Record<Exclude<AttributeType, "rollup">, readonly FilterOperator[]>;
118
+ /** Check if an operator requires a value */
119
+ type NoValueOperator = "is_empty" | "is_not_empty" | "is_checked" | "is_not_checked";
120
+ /** Operators that don't require a value */
121
+ declare const NO_VALUE_OPERATORS: readonly NoValueOperator[];
122
+ /**
123
+ * Check if an operator requires a value
124
+ */
125
+ declare function isNoValueOperator(operator: FilterOperator): operator is NoValueOperator;
126
+ /**
127
+ * Get the filter operators for a rollup attribute based on its aggregation function and target type.
128
+ *
129
+ * - earliest / latest → date operators
130
+ * - original → operators matching targetAttributeType (falls back to numeric if unknown)
131
+ * - all other functions → numeric operators (sum, avg, count, percent, etc.)
132
+ */
133
+ declare function getRollupFilterOperators(attr: RollupAttribute): readonly FilterOperator[];
134
+
135
+ /**
136
+ * Type of view - determines the config structure
137
+ */
138
+ type ViewType = "detail" | "list";
139
+ /**
140
+ * Creation behavior when clicking the "+" button
141
+ * - `redirect`: Create the record then navigate to its detail page
142
+ * - `inline`: Insert an empty row in the table (no navigation)
143
+ * - `modal`: Open a stacked modal for creation
144
+ */
145
+ type CreateMode = "redirect" | "inline" | "modal";
146
+ /**
147
+ * Inline attribute group configuration
148
+ * Groups multiple attributes into a single composite field with dropdown editing
149
+ */
150
+ interface AttributeGroupField {
151
+ /** Unique identifier for the group */
152
+ id: string;
153
+ /** Display label for the composite field */
154
+ label: string;
155
+ /** Description shown in the dropdown */
156
+ description?: string;
157
+ /** Attribute names to include in this group */
158
+ attributes: string[];
159
+ /**
160
+ * Template for the display value
161
+ * Uses {attributeName} syntax for interpolation
162
+ * @example "{billing_street}, {billing_city} {billing_postal_code}"
163
+ */
164
+ displayTemplate?: string;
165
+ }
166
+ /**
167
+ * Field definition within a form group
168
+ * Can be either a single attribute or an inline attribute group
169
+ */
170
+ interface Field {
171
+ /** Attribute name to display (for single attribute fields) */
172
+ attribute?: string;
173
+ /** Inline attribute group (groups multiple attributes into one composite field) */
174
+ attributeGroup?: AttributeGroupField;
175
+ /** Grid span (1-12 columns) */
176
+ span?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
177
+ /** Override label for this view (only for single attribute fields) */
178
+ label?: string;
179
+ /** Force read-only display */
180
+ readOnly?: boolean;
181
+ }
182
+ /**
183
+ * Base properties shared by all group types
184
+ */
185
+ interface BaseGroup {
186
+ id: string;
187
+ label: string;
188
+ description?: string;
189
+ collapsible?: boolean;
190
+ collapsed?: boolean;
191
+ order?: number;
192
+ }
193
+ /**
194
+ * Group of fields for organizing forms (default group type)
195
+ */
196
+ interface FieldGroup extends BaseGroup {
197
+ /** Discriminant — optional for backward compatibility with existing data */
198
+ type?: "fields";
199
+ fields: Field[];
200
+ }
201
+ /**
202
+ * Group that displays related records for a relation attribute
203
+ */
204
+ interface RelationGroup extends BaseGroup {
205
+ type: "relation";
206
+ /** Relation attribute name on the source object */
207
+ attribute: string;
208
+ /** Columns to display (auto-detected from target object if empty) */
209
+ columns?: string[];
210
+ /** Read-only mode */
211
+ readOnly?: boolean;
212
+ /** Allow creating new related records */
213
+ allowCreate?: boolean;
214
+ /**
215
+ * Two-level traversal — display records from the target's relation.
216
+ * When set, parent rows become grouping headers and the sub-rows
217
+ * (from `through.attribute`) are the primary display.
218
+ *
219
+ * @example attribute = "members", through.attribute = "companies"
220
+ * → displays companies of each member
221
+ */
222
+ through?: {
223
+ /** Relation attribute on the first-level target object */
224
+ attribute: string;
225
+ };
226
+ }
227
+ /**
228
+ * Discriminated union of all group types
229
+ */
230
+ type Group = FieldGroup | RelationGroup;
231
+ type TabType = "form" | "table" | "custom" | "activity" | "richtext" | "documents" | "forms";
232
+ /**
233
+ * Base properties shared by all tab types
234
+ */
235
+ interface BaseTab {
236
+ id: string;
237
+ name: string;
238
+ label: string;
239
+ icon?: IconName;
240
+ order?: number;
241
+ }
242
+ /**
243
+ * Form layout density
244
+ */
245
+ type FormDensity = "compact" | "comfortable" | "spacious";
246
+ /**
247
+ * Form tab - displays attributes organized in groups
248
+ */
249
+ interface FormTab extends BaseTab {
250
+ type: "form";
251
+ groups: Group[];
252
+ /** Number of grid columns (1, 2, or 3). Default: 2 */
253
+ formColumns?: 1 | 2 | 3;
254
+ /** Layout density. Default: "comfortable" */
255
+ density?: FormDensity;
256
+ }
257
+ /**
258
+ * Direct relation on the current object
259
+ *
260
+ * @example Contact.companies → shows Companies linked via the "companies" relation
261
+ */
262
+ interface RelationSource {
263
+ type: "relation";
264
+ /** Relation attribute name on the current object */
265
+ attribute: string;
266
+ }
267
+ /**
268
+ * Inverse lookup — records from another object that point to us
269
+ *
270
+ * @example On Company, show Contacts where Contact.company = this Company
271
+ */
272
+ interface InverseSource {
273
+ type: "inverse";
274
+ /** Object name that has the relation to us */
275
+ object: string;
276
+ /** Relation attribute name on the source object that points to us */
277
+ attribute: string;
278
+ }
279
+ /**
280
+ * Where table data comes from — either a direct relation or an inverse lookup
281
+ */
282
+ type TableSource = RelationSource | InverseSource;
283
+ /**
284
+ * Table tab - displays related records in a table
285
+ *
286
+ * The `source` field determines where data comes from.
287
+ *
288
+ * @example Direct: source = { type: "relation", attribute: "members" }
289
+ * @example Inverse: source = { type: "inverse", object: "contacts", attribute: "company" }
290
+ */
291
+ interface TableTab extends BaseTab {
292
+ type: "table";
293
+ /** Where the data comes from */
294
+ source: TableSource;
295
+ /** Columns to display (attribute names from the resolved target object) */
296
+ columns: string[];
297
+ /**
298
+ * Traverse a 2nd-level relation to display nested data.
299
+ * When active, `columns` stores the 2nd-level object's attribute names.
300
+ *
301
+ * @example source.attribute = "members", through.attribute = "companies"
302
+ * → displays companies of each member
303
+ */
304
+ through?: {
305
+ /** Relation attribute on the first-level target object */
306
+ attribute: string;
307
+ /** Show _source and _target columns */
308
+ showSourceTarget?: boolean;
309
+ };
310
+ /** Allow creating new records */
311
+ allowCreate?: boolean;
312
+ /** Creation behavior when allowCreate is true. Default: "redirect" */
313
+ createMode?: CreateMode;
314
+ /** Allow inline editing */
315
+ allowEdit?: boolean;
316
+ /** Allow deleting records */
317
+ allowDelete?: boolean;
318
+ /** Default filters applied to the table */
319
+ filters?: FilterState;
320
+ /** Default sort rules */
321
+ sorts?: SortRule[];
322
+ }
323
+ /**
324
+ * Custom tab - renders a developer-defined component
325
+ */
326
+ interface CustomTab extends BaseTab {
327
+ type: "custom";
328
+ /** Component identifier to render */
329
+ component: string;
330
+ /** Props to pass to the component */
331
+ props?: Record<string, unknown>;
332
+ }
333
+ /**
334
+ * Activity tab - displays activity feed for the current record
335
+ */
336
+ interface ActivityTab extends BaseTab {
337
+ type: "activity";
338
+ limit?: number;
339
+ }
340
+ /**
341
+ * Richtext tab - displays a block editor for a richtext attribute
342
+ */
343
+ interface RichtextTab extends BaseTab {
344
+ type: "richtext";
345
+ /** Richtext attribute to display in the BlockEditor */
346
+ attribute: string;
347
+ /** Optional text attribute for an editable title input above the editor */
348
+ titleAttribute?: string;
349
+ }
350
+ /**
351
+ * Documents tab - displays all documents attached to the record
352
+ */
353
+ interface DocumentsTab extends BaseTab {
354
+ type: "documents";
355
+ allowUpload?: boolean;
356
+ allowRemove?: boolean;
357
+ hideAttachments?: boolean;
358
+ }
359
+ /**
360
+ * Forms tab - displays available forms for creating related records
361
+ */
362
+ interface FormsTab extends BaseTab {
363
+ type: "forms";
364
+ /** Object name to filter forms by slot (derived from record context, but can be overridden) */
365
+ objectName?: string;
366
+ }
367
+ /**
368
+ * Union of all tab types (for detail views)
369
+ */
370
+ type Tab = FormTab | TableTab | CustomTab | ActivityTab | RichtextTab | DocumentsTab | FormsTab;
371
+ /**
372
+ * Detail view layout mode
373
+ * - `page`: Full view with multiple tabs
374
+ * - `modal`: Simplified view for modals (single FormTab, no tabs UI)
375
+ */
376
+ type DetailViewLayout = "page" | "modal";
377
+ /**
378
+ * List view layout mode
379
+ * - `table`: Table/grid layout
380
+ * - `kanban`: Kanban board layout (grouped by attribute)
381
+ */
382
+ type ListViewLayout = "table" | "kanban";
383
+ /**
384
+ * Tab within a list view — each tab carries its own full display configuration.
385
+ *
386
+ * @example
387
+ * ```typescript
388
+ * const tabs: ListViewTab[] = [
389
+ * { id: "all", label: "All Contacts", default: true, layout: "table", columns: ["name", "email", "status"] },
390
+ * { id: "active", label: "Active", layout: "table", columns: ["name", "email"], filters: activeFilter },
391
+ * { id: "pipeline", label: "Pipeline", layout: "kanban", columns: ["name", "amount"], groupByAttribute: "stage" },
392
+ * ];
393
+ * ```
394
+ */
395
+ interface ListViewTab {
396
+ /** Unique identifier */
397
+ id: string;
398
+ /** Display label */
399
+ label: string;
400
+ /** Icon */
401
+ icon?: IconName;
402
+ /** Default tab (shown on load) */
403
+ default?: boolean;
404
+ /** Layout mode */
405
+ layout: ListViewLayout;
406
+ /** Attribute names to display as columns */
407
+ columns: string[];
408
+ /** Column widths in pixels */
409
+ columnSizing?: Record<string, number>;
410
+ /** Filters applied to this tab */
411
+ filters?: FilterGroup;
412
+ /** Sort rules for this tab */
413
+ sorts?: SortRule[];
414
+ /** Attribute to group by (required when layout is "kanban") */
415
+ groupByAttribute?: string;
416
+ /** When true, the tab is read-only: no cell editing, no create, no delete */
417
+ readOnly?: boolean;
418
+ /** Creation behavior when clicking "+". Default: "redirect" */
419
+ createMode?: CreateMode;
420
+ /** User attribute to display on kanban cards (bottom-left) */
421
+ cardUserAttribute?: string;
422
+ /** Date attribute to display on kanban cards (bottom-right) */
423
+ cardDateAttribute?: string;
424
+ /** Order of kanban columns (by option value) - for kanban layout only */
425
+ kanbanColumnOrder?: string[];
426
+ /** Visibility of kanban columns (by option value) - for kanban layout only */
427
+ kanbanColumnVisibility?: Record<string, boolean>;
428
+ /** Pinned kanban columns (by option value) - for kanban layout only */
429
+ kanbanPinnedColumns?: string[];
430
+ }
431
+ /**
432
+ * Configuration for the side panel displayed alongside tab content.
433
+ * When present, a right-side panel shows the configured attributes as flat fields.
434
+ */
435
+ interface SidePanelConfig {
436
+ /** Attribute names to display as flat fields in the panel */
437
+ attributes: string[];
438
+ /** Width in pixels. @default 320 */
439
+ width?: number;
440
+ }
441
+ /**
442
+ * Configuration for detail views (RecordEditView)
443
+ */
444
+ interface DetailViewConfig {
445
+ /** Layout mode */
446
+ layout: DetailViewLayout;
447
+ /** Tabs in this view */
448
+ tabs: Tab[];
449
+ /** Optional side panel with flat attribute fields (not available for modal layout) */
450
+ sidePanel?: SidePanelConfig;
451
+ }
452
+ /**
453
+ * Configuration for list views (RecordsView)
454
+ *
455
+ * Each tab carries its own full config (layout, columns, filters, sorts, groupBy).
456
+ * The view only holds shared base filters applied to ALL tabs.
457
+ */
458
+ interface ListViewConfig {
459
+ /** Base filters applied to ALL tabs (scoping, tenant, etc.) */
460
+ defaultFilters?: FilterGroup;
461
+ /** Tabs — at least one required. Each carries its own full config. */
462
+ tabs: ListViewTab[];
463
+ }
464
+ /**
465
+ * Union of all view configs
466
+ */
467
+ type ViewConfig = DetailViewConfig | ListViewConfig;
468
+ /**
469
+ * Base view properties shared by all view types
470
+ */
471
+ interface BaseViewDefinition {
472
+ /** Unique identifier (UUID, assigned by database) */
473
+ id?: string;
474
+ /** Technical name (kebab-case) */
475
+ name: string;
476
+ /** Display label */
477
+ label: string;
478
+ /** Description */
479
+ description?: string;
480
+ /** Icon */
481
+ icon?: IconName;
482
+ /** Object this view belongs to (object name) */
483
+ object: string;
484
+ /** Default view for this object+type combination */
485
+ default?: boolean;
486
+ /** Extensible metadata */
487
+ metadata?: Record<string, unknown>;
488
+ /** Current schema version of this view definition */
489
+ schema_version: number;
490
+ }
491
+ /**
492
+ * Detail view definition
493
+ */
494
+ interface DetailViewDefinition extends BaseViewDefinition {
495
+ type: "detail";
496
+ config: DetailViewConfig;
497
+ }
498
+ /**
499
+ * List view definition
500
+ */
501
+ interface ListViewDefinition extends BaseViewDefinition {
502
+ type: "list";
503
+ config: ListViewConfig;
504
+ }
505
+ /**
506
+ * Unified view definition - discriminated union by type
507
+ */
508
+ type ViewDefinition = DetailViewDefinition | ListViewDefinition;
509
+ /**
510
+ * Configuration overrides for user customizations
511
+ * Only stores the delta from the source view
512
+ */
513
+ interface ConfigOverrides {
514
+ tabs?: ListViewTab[];
515
+ hiddenTabIds?: string[];
516
+ detailTabs?: Tab[];
517
+ hiddenDetailTabIds?: string[];
518
+ }
519
+ /**
520
+ * User customization overlay for a view
521
+ * Stored per user, merged at runtime with the source view
522
+ */
523
+ interface ViewOverlay {
524
+ /** Unique identifier */
525
+ id: string;
526
+ /** View ID this overlay applies to (UUID or virtual ID) */
527
+ viewId: string;
528
+ /** User ID who owns this overlay */
529
+ userId: string;
530
+ /** Configuration overrides (delta only) */
531
+ configOverrides: ConfigOverrides;
532
+ /** User's default view for this object (stored in overlay) */
533
+ isUserDefault?: boolean;
534
+ /** Created timestamp */
535
+ createdAt: Date;
536
+ /** Updated timestamp */
537
+ updatedAt: Date;
538
+ }
539
+ /**
540
+ * Check if a view is a detail view
541
+ */
542
+ declare function isDetailView(view: ViewDefinition): view is DetailViewDefinition;
543
+ /**
544
+ * Check if a view is a list view
545
+ */
546
+ declare function isListView(view: ViewDefinition): view is ListViewDefinition;
547
+ /**
548
+ * Check if a group is a field group (default type)
549
+ */
550
+ declare function isFieldGroup(group: Group): group is FieldGroup;
551
+ /**
552
+ * Check if a group is a relation group
553
+ */
554
+ declare function isRelationGroup(group: Group): group is RelationGroup;
555
+
556
+ type TransformSource = "system" | "runtime" | "rollback" | "seed";
557
+ type BuiltInTransform = "toString" | "toNumber" | "toDate" | "toBoolean" | "toISOString";
558
+ type SchemaOperation = {
559
+ type: "add_attribute";
560
+ attribute: Attribute;
561
+ } | {
562
+ type: "remove_attribute";
563
+ name: string;
564
+ backup_config: Attribute;
565
+ } | {
566
+ type: "rename_attribute";
567
+ from: string;
568
+ to: string;
569
+ } | {
570
+ type: "change_type";
571
+ name: string;
572
+ from: AttributeType;
573
+ to: AttributeType;
574
+ transform?: BuiltInTransform;
575
+ } | {
576
+ type: "update_config";
577
+ name: string;
578
+ from: Partial<Record<string, unknown>>;
579
+ to: Partial<Record<string, unknown>>;
580
+ } | {
581
+ type: "remove_object";
582
+ backup: Record<string, unknown>;
583
+ } | {
584
+ type: "rename_object";
585
+ from: string;
586
+ to: string;
587
+ };
588
+ type ViewOperation = {
589
+ type: "update_config";
590
+ from: ViewConfig;
591
+ to: ViewConfig;
592
+ } | {
593
+ type: "update_tabs";
594
+ from: (ListViewTab | Tab)[];
595
+ to: (ListViewTab | Tab)[];
596
+ } | {
597
+ type: "force_reset";
598
+ config: ViewConfig;
599
+ } | {
600
+ type: "remove_view";
601
+ backup: Record<string, unknown>;
602
+ };
603
+ interface MigrationDefinition {
604
+ version: number;
605
+ operations: SchemaOperation[];
606
+ reverse_operations: SchemaOperation[];
607
+ }
608
+ interface SchemaTransform {
609
+ id: string;
610
+ tenantId: string;
611
+ objectId: string;
612
+ fromVersion: number;
613
+ toVersion: number;
614
+ operations: SchemaOperation[];
615
+ reverseOperations: SchemaOperation[];
616
+ source: TransformSource;
617
+ appliedAt: Date;
618
+ fullyMigrated: boolean;
619
+ }
620
+ interface ViewTransform {
621
+ id: string;
622
+ tenantId: string;
623
+ viewId: string;
624
+ fromVersion: number;
625
+ toVersion: number;
626
+ operations: ViewOperation[];
627
+ reverseOperations: ViewOperation[];
628
+ source: TransformSource;
629
+ appliedAt: Date;
630
+ }
631
+ interface MigrationError {
632
+ id: string;
633
+ tenantId: string;
634
+ transformId: string;
635
+ recordId: string;
636
+ attributeName: string;
637
+ originalValue: unknown;
638
+ error: string;
639
+ resolvedAt: Date | null;
640
+ resolvedValue: unknown | null;
641
+ }
642
+
643
+ /**
644
+ * Timestamps for tracking creation and updates
645
+ */
646
+ interface Timestamps {
647
+ createdAt: Date;
648
+ updatedAt: Date;
649
+ }
650
+ /**
651
+ * Object definition - Represents a database table/entity
652
+ */
653
+ interface ObjectDefinition {
654
+ id?: Uuid;
655
+ name: string;
656
+ label: string;
657
+ pluralLabel?: string;
658
+ description?: string;
659
+ icon?: IconName;
660
+ /**
661
+ * Template expression used to compute the object's display label.
662
+ * Supports variable interpolation and pipes for formatting.
663
+ *
664
+ * @example
665
+ * ```typescript
666
+ * // Simple attribute reference
667
+ * labelExpression: "{{ name }}"
668
+ *
669
+ * // Multiple attributes
670
+ * labelExpression: "{{ firstName }} {{ lastName }}"
671
+ *
672
+ * // With pipes for formatting
673
+ * labelExpression: "{{ code | UPPER }} - {{ name | capitalize }}"
674
+ * ```
675
+ *
676
+ * Available pipes: UPPER, LOWER, capitalize, trim
677
+ */
678
+ labelExpression: string;
679
+ attributes: Attribute[];
680
+ system?: boolean;
681
+ metadata?: Record<string, unknown>;
682
+ /** Current schema version (incremented with each migration) */
683
+ schema_version: number;
684
+ /** Ordered list of migrations applied to this object's schema */
685
+ migrations: MigrationDefinition[];
686
+ }
687
+ /**
688
+ * Links an attribute to an object
689
+ */
690
+ interface ObjectAttribute {
691
+ objectId: Uuid;
692
+ attributeId: Uuid;
693
+ order?: number;
694
+ required?: boolean;
695
+ }
696
+ /**
697
+ * Completion status of a record based on data completeness.
698
+ *
699
+ * - `draft`: Record is missing one or more required attribute values.
700
+ * Can be saved but is considered incomplete.
701
+ * - `complete`: All required attribute values are present and valid.
702
+ * Record is ready for use.
703
+ *
704
+ * This is different from workflow status (e.g., "pending", "approved").
705
+ * Completion status is computed dynamically based on the object schema.
706
+ */
707
+ type CompletionStatus = "draft" | "complete";
708
+ /**
709
+ * Record - Instance of an Object (a row in the database)
710
+ */
711
+ interface ObjectRecord extends Timestamps {
712
+ id: Uuid;
713
+ objectId: Uuid;
714
+ /**
715
+ * Display label computed from the object's labelExpression.
716
+ * Computed dynamically based on record values.
717
+ *
718
+ * @example "John Doe" (from "{{ firstName }} {{ lastName }}")
719
+ */
720
+ label: string;
721
+ /**
722
+ * Completion status of the record.
723
+ * - `draft`: Missing required values, record is incomplete
724
+ * - `complete`: All required values present and valid
725
+ *
726
+ * Computed dynamically based on the object's schema.
727
+ */
728
+ completionStatus: CompletionStatus;
729
+ values: Record<string, unknown>;
730
+ /**
731
+ * Custom metadata for the record.
732
+ * Use this for UI/UX state, feature flags, or any application-specific data.
733
+ * Unlike system fields (id, createdAt, updatedAt), metadata can be updated.
734
+ */
735
+ metadata?: Record<string, unknown>;
736
+ /**
737
+ * Soft delete timestamp.
738
+ * If set, the record is considered deleted but can be restored.
739
+ * Queries exclude soft-deleted records by default.
740
+ */
741
+ deletedAt?: Date | null;
742
+ /**
743
+ * User ID who created this record.
744
+ * Automatically set by RecordService when userId is configured.
745
+ * Optional for backward compatibility with existing records.
746
+ */
747
+ createdBy?: string;
748
+ /**
749
+ * User ID who last updated this record.
750
+ * Automatically set by RecordService when userId is configured.
751
+ * Optional for backward compatibility with existing records.
752
+ */
753
+ lastUpdatedBy?: string;
754
+ /** Schema version at the time this record was last migrated */
755
+ schemaVersion: number;
756
+ /**
757
+ * Values archived during attribute removal or type changes.
758
+ * Retained according to the retention policy before permanent deletion.
759
+ */
760
+ archivedValues?: Record<string, unknown>;
761
+ }
762
+ /**
763
+ * System-managed field names on ObjectRecord.
764
+ * These are stored as SQL columns (not in JSONB `values`).
765
+ *
766
+ * Use this in adapters to determine if a filter/sort attribute is a table column
767
+ * vs. a JSONB value field.
768
+ *
769
+ * @example
770
+ * ```typescript
771
+ * if (SYSTEM_FIELD_NAMES.includes(filter.attribute)) {
772
+ * // Filter on SQL column (e.g., WHERE created_at > ...)
773
+ * } else {
774
+ * // Filter on JSONB field (e.g., WHERE values->>'name' = ...)
775
+ * }
776
+ * ```
777
+ */
778
+ declare const SYSTEM_FIELD_NAMES: readonly ["id", "createdAt", "updatedAt", "createdBy", "lastUpdatedBy"];
779
+ /**
780
+ * Type for system field names
781
+ */
782
+ type SystemFieldName = (typeof SYSTEM_FIELD_NAMES)[number];
783
+ /**
784
+ * Reserved attribute names that cannot be used for custom attributes.
785
+ * These names conflict with ObjectRecord properties.
786
+ *
787
+ * Includes:
788
+ * - System fields (id, createdAt, updatedAt, createdBy, lastUpdatedBy)
789
+ * - Other ObjectRecord properties (objectId, label, completionStatus, values, metadata, deletedAt)
790
+ *
791
+ * @example
792
+ * ```typescript
793
+ * if (RESERVED_ATTRIBUTE_NAMES.includes(attributeName)) {
794
+ * throw new Error(`"${attributeName}" is a reserved name`);
795
+ * }
796
+ * ```
797
+ */
798
+ declare const RESERVED_ATTRIBUTE_NAMES: readonly ["id", "createdAt", "updatedAt", "createdBy", "lastUpdatedBy", "objectId", "label", "completionStatus", "values", "metadata", "deletedAt", "schemaVersion", "archivedValues"];
799
+ /**
800
+ * Type for reserved attribute names
801
+ */
802
+ type ReservedAttributeName = (typeof RESERVED_ATTRIBUTE_NAMES)[number];
803
+
804
+ /**
805
+ * Create a Zod schema for any attribute type.
806
+ * Returns a strict validator that does NOT handle optional fields.
807
+ * Use createFormAttributeValidator for form validation with optional support.
808
+ *
809
+ * @param attr - The attribute to create a validator for
810
+ * @param messages - Custom validation messages for i18n support
811
+ */
812
+ declare function createAttributeValidator(attr: Attribute, messages?: ValidationMessages): z.ZodTypeAny;
813
+ /**
814
+ * Create a Zod schema for form validation.
815
+ * - Normalizes empty values (empty strings, empty objects) to null for optional fields
816
+ * - Accepts custom messages for i18n support
817
+ *
818
+ * Use this in UI forms where optional fields may have null/undefined values.
819
+ *
820
+ * @param attr - The attribute to create a validator for
821
+ * @param messages - Custom validation messages for i18n support
822
+ */
823
+ declare function createFormAttributeValidator(attr: Attribute, messages?: ValidationMessages): z.ZodTypeAny;
824
+
825
+ /**
826
+ * Validate data against an attribute schema
827
+ */
828
+ declare function validateAttribute(attr: Attribute, value: unknown): ValidationResult;
829
+ /**
830
+ * Validate data against an object schema
831
+ */
832
+ declare function validateObject(objectDef: ObjectDefinition, data: Record<string, unknown>): ValidationResult;
833
+ /**
834
+ * Validate and throw if invalid
835
+ */
836
+ declare function validateObjectOrThrow(objectDef: ObjectDefinition, data: Record<string, unknown>): Record<string, unknown>;
837
+ /**
838
+ * Validate data in draft mode.
839
+ * - All attributes are treated as optional (no required validation)
840
+ * - Provided values are still validated for format/type correctness
841
+ */
842
+ declare function validateDraft(objectDef: ObjectDefinition, data: Record<string, unknown>): ValidationResult;
843
+ /**
844
+ * Validate draft data and throw if format validation fails.
845
+ */
846
+ declare function validateDraftOrThrow(objectDef: ObjectDefinition, data: Record<string, unknown>): Record<string, unknown>;
847
+ /**
848
+ * Get the list of required attributes that are missing values.
849
+ */
850
+ declare function getMissingRequiredAttributes(objectDef: ObjectDefinition, data: Record<string, unknown>): Attribute[];
851
+ /**
852
+ * Check if a record is complete (all required attributes have valid values).
853
+ */
854
+ declare function isRecordComplete(objectDef: ObjectDefinition, data: Record<string, unknown>): boolean;
855
+ /**
856
+ * Compute the completion status of a record based on its data.
857
+ */
858
+ declare function computeRecordStatus(objectDef: ObjectDefinition, data: Record<string, unknown>): CompletionStatus;
859
+
860
+ export { type MigrationError as $, type AttributeGroupField as A, type BuiltInTransform as B, type ConfigOverrides as C, type DetailViewConfig as D, type CurrencyFilterValue as E, type FilterState as F, type Group as G, type CustomTab as H, type DocumentsTab as I, type ExtendedFilterRule as J, type FilterCombinator as K, type ListViewConfig as L, type MigrationDefinition as M, type FilterGroup as N, type ObjectDefinition as O, type FilterOperator as P, type FilterRule as Q, type RelationGroup as R, type SortRule as S, type Timestamps as T, type FilterValue as U, type ViewType as V, type FormDensity as W, type FormTab as X, type FormsTab as Y, type InverseSource as Z, type ListViewLayout as _, createFormAttributeValidator as a, NO_VALUE_OPERATORS as a0, type NoValueOperator as a1, OPERATORS_BY_TYPE as a2, type ObjectAttribute as a3, type PhoneFilterValue as a4, type QueryState as a5, RESERVED_ATTRIBUTE_NAMES as a6, type RelationSource as a7, type RelativeDateValue as a8, type ReservedAttributeName as a9, type RichtextTab as aa, SYSTEM_FIELD_NAMES as ab, type SchemaOperation as ac, type SchemaTransform as ad, type SortDirection as ae, type SystemFieldName as af, type TabType as ag, type TableSource as ah, type TransformSource as ai, type ViewOperation as aj, type ViewOverlay as ak, type ViewTransform as al, getRollupFilterOperators as am, isDetailView as an, isFieldGroup as ao, isListView as ap, isNoValueOperator as aq, isRelationGroup as ar, validateObject as b, computeRecordStatus as c, validateObjectOrThrow as d, createAttributeValidator as e, validateAttribute as f, getMissingRequiredAttributes as g, validateDraft as h, isRecordComplete as i, type ViewConfig as j, type CompletionStatus as k, type ObjectRecord as l, type DetailViewDefinition as m, type DetailViewLayout as n, type SidePanelConfig as o, type Field as p, type FieldGroup as q, type TableTab as r, type CreateMode as s, type Tab as t, type ListViewDefinition as u, validateDraftOrThrow as v, type ViewDefinition as w, type ListViewTab as x, type ActivityTab as y, type AdvancedFilterState as z };