@stndrds/schema 1.0.0-alpha.264 → 1.0.0-alpha.266
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.
- package/dist/all--B2_3ksI.d.ts +465 -0
- package/dist/all-D5zeUllO.d.mts +465 -0
- package/dist/{attributes-DUuaECJI.d.ts → attributes-_b3Db8vT.d.ts} +1 -1
- package/dist/{attributes-DCgZhISp.d.mts → attributes-lBLiOIY3.d.mts} +1 -1
- package/dist/chunk-6ZDH3EJA.js +1261 -0
- package/dist/chunk-F6ATLCIR.mjs +1214 -0
- package/dist/{chunk-TS3PJOMZ.js → chunk-FDIAOFHS.js} +22 -235
- package/dist/{chunk-UXCJ3NI4.mjs → chunk-KDHDC7E6.mjs} +150 -9
- package/dist/{chunk-U36ZIBEM.mjs → chunk-O73ROMWQ.mjs} +15 -6
- package/dist/{chunk-54WDPQ6R.mjs → chunk-POULKEJM.mjs} +22 -224
- package/dist/{chunk-EBGRZUIH.js → chunk-Q4SZAMJT.js} +5 -0
- package/dist/chunk-QMLO7V5E.mjs +216 -0
- package/dist/{chunk-L4U5QEQL.js → chunk-QN2N3IJZ.js} +158 -8
- package/dist/{chunk-JUKLL5RJ.mjs → chunk-R5LAJCBU.mjs} +5 -2
- package/dist/chunk-V6Q7HCA7.js +229 -0
- package/dist/{chunk-QAF3HNKQ.js → chunk-ZPFOKBIN.js} +16 -5
- package/dist/exceptions.d.mts +471 -0
- package/dist/exceptions.d.ts +471 -0
- package/dist/exceptions.js +158 -0
- package/dist/exceptions.mjs +1 -0
- package/dist/helpers-C1VVEAOO.d.mts +76 -0
- package/dist/helpers-vQ6kp8ET.d.ts +76 -0
- package/dist/index-Bq1KrQkR.d.ts +2413 -0
- package/dist/index-DtxtOBYT.d.mts +2413 -0
- package/dist/index.d.mts +1580 -2652
- package/dist/index.d.ts +1580 -2652
- package/dist/index.js +1297 -1045
- package/dist/index.mjs +913 -907
- package/dist/migrations-BXd2ZGfM.d.mts +39 -0
- package/dist/migrations-DcuJZ8qO.d.ts +39 -0
- package/dist/{helpers-B4qBjTd0.d.ts → objects-A1ED9af-.d.ts} +33 -113
- package/dist/{helpers-B_NlMAm2.d.mts → objects-BCaBw2ef.d.mts} +33 -113
- package/dist/{types-15lGDPlN.d.mts → types-DNz3ITS-.d.mts} +1 -1
- package/dist/{types-CqZZxm_V.d.ts → types-DqLi1tx1.d.ts} +1 -1
- package/dist/validation/all.d.mts +7 -4
- package/dist/validation/all.d.ts +7 -4
- package/dist/validation/all.js +88 -15
- package/dist/validation/all.mjs +9 -8
- package/dist/validation/complex/currency.d.mts +2 -2
- package/dist/validation/complex/currency.d.ts +2 -2
- package/dist/validation/complex/location.d.mts +2 -2
- package/dist/validation/complex/location.d.ts +2 -2
- package/dist/validation/complex/phone.d.mts +2 -2
- package/dist/validation/complex/phone.d.ts +2 -2
- package/dist/validation/complex/phone.js +2 -2
- package/dist/validation/complex/phone.mjs +1 -1
- package/dist/validation/complex/relation.d.mts +2 -2
- package/dist/validation/complex/relation.d.ts +2 -2
- package/dist/validation/complex/richtext.d.mts +2 -2
- package/dist/validation/complex/richtext.d.ts +2 -2
- package/dist/validation/complex/select.d.mts +2 -2
- package/dist/validation/complex/select.d.ts +2 -2
- package/dist/validation/complex/user.d.mts +2 -2
- package/dist/validation/complex/user.d.ts +2 -2
- package/dist/validation/computed/formula.d.mts +2 -2
- package/dist/validation/computed/formula.d.ts +2 -2
- package/dist/validation/computed/rollup.d.mts +2 -2
- package/dist/validation/computed/rollup.d.ts +2 -2
- package/dist/validation/config/index.d.mts +5 -18
- package/dist/validation/config/index.d.ts +5 -18
- package/dist/validation/config/index.js +34 -4
- package/dist/validation/config/index.mjs +7 -1
- package/dist/validation/core/index.d.mts +3 -3
- package/dist/validation/core/index.d.ts +3 -3
- package/dist/validation/object/index.d.mts +5 -4
- package/dist/validation/object/index.d.ts +5 -4
- package/dist/validation/object/index.js +19 -18
- package/dist/validation/object/index.mjs +7 -6
- package/dist/validation/primitives/checkbox.d.mts +2 -2
- package/dist/validation/primitives/checkbox.d.ts +2 -2
- package/dist/validation/primitives/date.d.mts +2 -2
- package/dist/validation/primitives/date.d.ts +2 -2
- package/dist/validation/primitives/number.d.mts +2 -2
- package/dist/validation/primitives/number.d.ts +2 -2
- package/dist/validation/primitives/text.d.mts +2 -2
- package/dist/validation/primitives/text.d.ts +2 -2
- package/dist/validation/primitives/text.js +2 -2
- package/dist/validation/primitives/text.mjs +1 -1
- package/package.json +7 -2
- package/dist/chunk-PGERPYDR.js +0 -2
- package/dist/chunk-SP3PNHYF.mjs +0 -1
|
@@ -0,0 +1,1214 @@
|
|
|
1
|
+
import { SCHEMA_LIMITS, iconNameSchema } from './chunk-KDHDC7E6.mjs';
|
|
2
|
+
import { ValidationError } from './chunk-POULKEJM.mjs';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
|
|
5
|
+
// src/types/system-attributes.ts
|
|
6
|
+
var SYSTEM_ATTRIBUTE_I18N_KEYS = {
|
|
7
|
+
createdAt: "createdAt",
|
|
8
|
+
updatedAt: "updatedAt",
|
|
9
|
+
createdBy: "createdBy",
|
|
10
|
+
lastUpdatedBy: "lastUpdatedBy",
|
|
11
|
+
attachments: "attachments"
|
|
12
|
+
};
|
|
13
|
+
function getSystemAttributeI18nKey(name) {
|
|
14
|
+
return SYSTEM_ATTRIBUTE_I18N_KEYS[name];
|
|
15
|
+
}
|
|
16
|
+
var SYSTEM_ATTRIBUTES = {
|
|
17
|
+
createdAt: {
|
|
18
|
+
id: "system:createdAt",
|
|
19
|
+
name: "createdAt",
|
|
20
|
+
label: "Created time",
|
|
21
|
+
type: "date",
|
|
22
|
+
required: false,
|
|
23
|
+
system: true,
|
|
24
|
+
icon: "clock-circle",
|
|
25
|
+
description: "When this record was created"
|
|
26
|
+
},
|
|
27
|
+
updatedAt: {
|
|
28
|
+
id: "system:updatedAt",
|
|
29
|
+
name: "updatedAt",
|
|
30
|
+
label: "Last edited time",
|
|
31
|
+
type: "date",
|
|
32
|
+
required: false,
|
|
33
|
+
system: true,
|
|
34
|
+
icon: "clock-circle",
|
|
35
|
+
description: "When this record was last modified"
|
|
36
|
+
},
|
|
37
|
+
createdBy: {
|
|
38
|
+
id: "system:createdBy",
|
|
39
|
+
name: "createdBy",
|
|
40
|
+
label: "Created by",
|
|
41
|
+
type: "user",
|
|
42
|
+
required: false,
|
|
43
|
+
system: true,
|
|
44
|
+
multiple: false,
|
|
45
|
+
icon: "user",
|
|
46
|
+
description: "Actor who created this record"
|
|
47
|
+
},
|
|
48
|
+
lastUpdatedBy: {
|
|
49
|
+
id: "system:lastUpdatedBy",
|
|
50
|
+
name: "lastUpdatedBy",
|
|
51
|
+
label: "Last edited by",
|
|
52
|
+
type: "user",
|
|
53
|
+
required: false,
|
|
54
|
+
system: true,
|
|
55
|
+
multiple: false,
|
|
56
|
+
icon: "user",
|
|
57
|
+
description: "Actor who last modified this record"
|
|
58
|
+
},
|
|
59
|
+
/**
|
|
60
|
+
* System attribute for free-form document attachments.
|
|
61
|
+
* Hidden from forms, visible in Documents tab.
|
|
62
|
+
* Users can attach any document without template constraints.
|
|
63
|
+
*/
|
|
64
|
+
attachments: {
|
|
65
|
+
id: "system:attachments",
|
|
66
|
+
name: "attachments",
|
|
67
|
+
label: "Attachments",
|
|
68
|
+
type: "document",
|
|
69
|
+
required: false,
|
|
70
|
+
system: true,
|
|
71
|
+
hidden: true,
|
|
72
|
+
// Hidden from regular form views
|
|
73
|
+
icon: "paperclip",
|
|
74
|
+
description: "Free-form document attachments"
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
function getSystemAttributeList() {
|
|
78
|
+
return Object.values(SYSTEM_ATTRIBUTES);
|
|
79
|
+
}
|
|
80
|
+
function isManagedSystemAttribute(attribute) {
|
|
81
|
+
return attribute.id?.startsWith("system:") ?? false;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// src/types/attribute-capabilities.ts
|
|
85
|
+
var TEXT_OPERATORS = [
|
|
86
|
+
"is",
|
|
87
|
+
"is_not",
|
|
88
|
+
"contains",
|
|
89
|
+
"not_contains",
|
|
90
|
+
"starts_with",
|
|
91
|
+
"ends_with",
|
|
92
|
+
"is_empty",
|
|
93
|
+
"is_not_empty"
|
|
94
|
+
];
|
|
95
|
+
var NUMBER_OPERATORS = [
|
|
96
|
+
"is",
|
|
97
|
+
"is_not",
|
|
98
|
+
"less_than",
|
|
99
|
+
"greater_than",
|
|
100
|
+
"less_or_equal",
|
|
101
|
+
"greater_or_equal",
|
|
102
|
+
"is_empty",
|
|
103
|
+
"is_not_empty"
|
|
104
|
+
];
|
|
105
|
+
var CHECKBOX_OPERATORS = ["is"];
|
|
106
|
+
var DATE_OPERATORS = [
|
|
107
|
+
"is",
|
|
108
|
+
"is_not",
|
|
109
|
+
"less_than",
|
|
110
|
+
"greater_than",
|
|
111
|
+
"less_or_equal",
|
|
112
|
+
"greater_or_equal",
|
|
113
|
+
"is_within",
|
|
114
|
+
"on_day_month",
|
|
115
|
+
"is_empty",
|
|
116
|
+
"is_not_empty"
|
|
117
|
+
];
|
|
118
|
+
var SELECT_OPERATORS = [
|
|
119
|
+
"is",
|
|
120
|
+
"is_not",
|
|
121
|
+
"any_of",
|
|
122
|
+
"none_of",
|
|
123
|
+
"is_empty",
|
|
124
|
+
"is_not_empty"
|
|
125
|
+
];
|
|
126
|
+
var MULTISELECT_OPERATORS = [
|
|
127
|
+
"any_of",
|
|
128
|
+
"none_of",
|
|
129
|
+
"is_empty",
|
|
130
|
+
"is_not_empty"
|
|
131
|
+
];
|
|
132
|
+
var REFERENCE_OPERATORS = [
|
|
133
|
+
"is",
|
|
134
|
+
"is_not",
|
|
135
|
+
"any_of",
|
|
136
|
+
"none_of",
|
|
137
|
+
"is_empty",
|
|
138
|
+
"is_not_empty"
|
|
139
|
+
];
|
|
140
|
+
var PRESENCE_OPERATORS = [
|
|
141
|
+
"is_empty",
|
|
142
|
+
"is_not_empty"
|
|
143
|
+
];
|
|
144
|
+
var FORMULA_OPERATORS = [
|
|
145
|
+
"is",
|
|
146
|
+
"is_not",
|
|
147
|
+
"less_than",
|
|
148
|
+
"greater_than",
|
|
149
|
+
"less_or_equal",
|
|
150
|
+
"greater_or_equal",
|
|
151
|
+
"contains",
|
|
152
|
+
"not_contains",
|
|
153
|
+
"is_empty",
|
|
154
|
+
"is_not_empty"
|
|
155
|
+
];
|
|
156
|
+
var ATTRIBUTE_FILTER_OPERATORS = {
|
|
157
|
+
text: TEXT_OPERATORS,
|
|
158
|
+
richtext: [],
|
|
159
|
+
number: NUMBER_OPERATORS,
|
|
160
|
+
checkbox: CHECKBOX_OPERATORS,
|
|
161
|
+
date: DATE_OPERATORS,
|
|
162
|
+
phone: ["is", "is_not", "contains", "not_contains", "starts_with", "is_empty", "is_not_empty"],
|
|
163
|
+
currency: NUMBER_OPERATORS,
|
|
164
|
+
status: SELECT_OPERATORS,
|
|
165
|
+
select: SELECT_OPERATORS,
|
|
166
|
+
multiselect: MULTISELECT_OPERATORS,
|
|
167
|
+
location: [],
|
|
168
|
+
user: REFERENCE_OPERATORS,
|
|
169
|
+
relation: REFERENCE_OPERATORS,
|
|
170
|
+
formula: FORMULA_OPERATORS,
|
|
171
|
+
document: PRESENCE_OPERATORS
|
|
172
|
+
};
|
|
173
|
+
var COMPUTED_TYPES = /* @__PURE__ */ new Set(["formula", "rollup"]);
|
|
174
|
+
var EDGE_BACKED_TYPES = /* @__PURE__ */ new Set(["user", "relation", "document"]);
|
|
175
|
+
var STATIC_DEFAULT_TYPES = /* @__PURE__ */ new Set([
|
|
176
|
+
"text",
|
|
177
|
+
"richtext",
|
|
178
|
+
"number",
|
|
179
|
+
"select",
|
|
180
|
+
"multiselect",
|
|
181
|
+
"status",
|
|
182
|
+
"date",
|
|
183
|
+
"phone",
|
|
184
|
+
"currency",
|
|
185
|
+
"location",
|
|
186
|
+
"user",
|
|
187
|
+
"relation",
|
|
188
|
+
"document"
|
|
189
|
+
]);
|
|
190
|
+
var PLACEHOLDER_TYPES = /* @__PURE__ */ new Set([
|
|
191
|
+
"text",
|
|
192
|
+
"number",
|
|
193
|
+
"date",
|
|
194
|
+
"phone",
|
|
195
|
+
"currency",
|
|
196
|
+
"select",
|
|
197
|
+
"multiselect"
|
|
198
|
+
]);
|
|
199
|
+
var SEARCHABLE_TYPES = /* @__PURE__ */ new Set([
|
|
200
|
+
"text",
|
|
201
|
+
"phone",
|
|
202
|
+
"status",
|
|
203
|
+
"select",
|
|
204
|
+
"multiselect"
|
|
205
|
+
]);
|
|
206
|
+
var SORTABLE_TYPES = /* @__PURE__ */ new Set([
|
|
207
|
+
"text",
|
|
208
|
+
"number",
|
|
209
|
+
"checkbox",
|
|
210
|
+
"date",
|
|
211
|
+
"phone",
|
|
212
|
+
"currency",
|
|
213
|
+
"status",
|
|
214
|
+
"select"
|
|
215
|
+
]);
|
|
216
|
+
function getAttributeCapabilities(attribute) {
|
|
217
|
+
const suppressed = Boolean(attribute.hidden || attribute.archived);
|
|
218
|
+
const active = !attribute.archived;
|
|
219
|
+
const computed = COMPUTED_TYPES.has(attribute.type);
|
|
220
|
+
const document = attribute.type === "document";
|
|
221
|
+
const edgeBacked = EDGE_BACKED_TYPES.has(attribute.type);
|
|
222
|
+
const cardinality = getAttributeCardinality(attribute);
|
|
223
|
+
const operators = suppressed ? [] : getRawFilterOperators(attribute);
|
|
224
|
+
const filterable = operators.length > 0 && !suppressed;
|
|
225
|
+
const searchable = !suppressed && SEARCHABLE_TYPES.has(attribute.type);
|
|
226
|
+
const sortable = !suppressed && SORTABLE_TYPES.has(attribute.type);
|
|
227
|
+
const groupable = !suppressed && isGroupableType(attribute.type);
|
|
228
|
+
const kanbanGroupable = !suppressed && attribute.type === "status";
|
|
229
|
+
const managed = isManagedSystemAttribute(attribute);
|
|
230
|
+
const readOnly = computed || document || managed;
|
|
231
|
+
const editable = !(suppressed || readOnly);
|
|
232
|
+
const required = isRequiredForbidden(attribute.type) ? "forbidden" : "allowed";
|
|
233
|
+
const defaultValue = getDefaultValueCapability(attribute.type);
|
|
234
|
+
const maxItems = supportsMaxItems(attribute);
|
|
235
|
+
const placeholder = PLACEHOLDER_TYPES.has(attribute.type);
|
|
236
|
+
const warningWhenDeprecated = Boolean(attribute.deprecated && !suppressed);
|
|
237
|
+
const editMode = resolveEditMode(attribute);
|
|
238
|
+
return {
|
|
239
|
+
lifecycle: {
|
|
240
|
+
active,
|
|
241
|
+
deprecated: Boolean(attribute.deprecated),
|
|
242
|
+
visibleInArchitect: true,
|
|
243
|
+
visibleInRuntime: !suppressed,
|
|
244
|
+
warningWhenDeprecated
|
|
245
|
+
},
|
|
246
|
+
storage: {
|
|
247
|
+
mode: computed ? "computed" : edgeBacked ? "edge" : "value",
|
|
248
|
+
cardinality,
|
|
249
|
+
edgeBacked,
|
|
250
|
+
preservesExistingValues: Boolean(attribute.archived),
|
|
251
|
+
qualifiedProperties: supportsQualifiedProperties(attribute.type),
|
|
252
|
+
polymorphic: getPolymorphicCapability(attribute),
|
|
253
|
+
maxItems
|
|
254
|
+
},
|
|
255
|
+
authoring: {
|
|
256
|
+
editable,
|
|
257
|
+
readOnly,
|
|
258
|
+
directEdit: editable && editMode === "inline",
|
|
259
|
+
required,
|
|
260
|
+
defaultValue,
|
|
261
|
+
placeholder,
|
|
262
|
+
maxItems
|
|
263
|
+
},
|
|
264
|
+
presentation: {
|
|
265
|
+
formField: !suppressed && isFormFieldType(attribute.type),
|
|
266
|
+
tableCell: !suppressed && isTableCellType(attribute.type),
|
|
267
|
+
defaultColumn: !suppressed && isDefaultColumnType(attribute.type),
|
|
268
|
+
compactDisplay: !suppressed,
|
|
269
|
+
popoverEditor: !suppressed && editMode === "popover",
|
|
270
|
+
placeholder,
|
|
271
|
+
warningWhenDeprecated
|
|
272
|
+
},
|
|
273
|
+
query: {
|
|
274
|
+
filterable,
|
|
275
|
+
searchable,
|
|
276
|
+
sortable,
|
|
277
|
+
groupable,
|
|
278
|
+
kanbanGroupable,
|
|
279
|
+
operators
|
|
280
|
+
},
|
|
281
|
+
agent: {
|
|
282
|
+
readable: !suppressed,
|
|
283
|
+
writable: editable && !document,
|
|
284
|
+
compactReadable: !suppressed,
|
|
285
|
+
contentReadable: !suppressed && isContentReadableType(attribute.type),
|
|
286
|
+
requiresDedicatedTool: document
|
|
287
|
+
},
|
|
288
|
+
exchange: {
|
|
289
|
+
importable: !suppressed,
|
|
290
|
+
exportable: !suppressed,
|
|
291
|
+
schemaExportable: true,
|
|
292
|
+
metadataExportable: false
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
function getAttributeFilterOperators(attribute) {
|
|
297
|
+
return getAttributeCapabilities(attribute).query.operators;
|
|
298
|
+
}
|
|
299
|
+
function isAttributeFilterable(attribute) {
|
|
300
|
+
return getAttributeCapabilities(attribute).query.filterable;
|
|
301
|
+
}
|
|
302
|
+
function isAttributeSearchable(attribute) {
|
|
303
|
+
return getAttributeCapabilities(attribute).query.searchable;
|
|
304
|
+
}
|
|
305
|
+
function isAttributeSortable(attribute) {
|
|
306
|
+
return getAttributeCapabilities(attribute).query.sortable;
|
|
307
|
+
}
|
|
308
|
+
function isAttributeGroupable(attribute) {
|
|
309
|
+
return getAttributeCapabilities(attribute).query.groupable;
|
|
310
|
+
}
|
|
311
|
+
function isAttributeKanbanGroupable(attribute) {
|
|
312
|
+
return getAttributeCapabilities(attribute).query.kanbanGroupable;
|
|
313
|
+
}
|
|
314
|
+
function getRollupFilterOperators(attr) {
|
|
315
|
+
const fn = attr.function;
|
|
316
|
+
if (fn === "earliest" || fn === "latest") {
|
|
317
|
+
return ATTRIBUTE_FILTER_OPERATORS.date;
|
|
318
|
+
}
|
|
319
|
+
if (fn === "original") {
|
|
320
|
+
const targetType = attr.targetAttributeType;
|
|
321
|
+
if (targetType && hasFilterOperatorEntry(targetType)) {
|
|
322
|
+
return ATTRIBUTE_FILTER_OPERATORS[targetType];
|
|
323
|
+
}
|
|
324
|
+
return ATTRIBUTE_FILTER_OPERATORS.number;
|
|
325
|
+
}
|
|
326
|
+
return ATTRIBUTE_FILTER_OPERATORS.number;
|
|
327
|
+
}
|
|
328
|
+
function getRawFilterOperators(attribute) {
|
|
329
|
+
if (attribute.type === "rollup") {
|
|
330
|
+
return getRollupFilterOperators(attribute);
|
|
331
|
+
}
|
|
332
|
+
return ATTRIBUTE_FILTER_OPERATORS[attribute.type] ?? [];
|
|
333
|
+
}
|
|
334
|
+
function getAttributeCardinality(attribute) {
|
|
335
|
+
if (attribute.type === "multiselect" || attribute.type === "document") return "many";
|
|
336
|
+
if (attribute.type === "user" && attribute.multiple === true) return "many";
|
|
337
|
+
if (attribute.type === "relation") return attribute.cardinality === "many" ? "many" : "one";
|
|
338
|
+
return "one";
|
|
339
|
+
}
|
|
340
|
+
function getPolymorphicCapability(attribute) {
|
|
341
|
+
if (attribute.type !== "relation") return "none";
|
|
342
|
+
const relation = attribute;
|
|
343
|
+
const targets = relation.targets ?? [];
|
|
344
|
+
if (targets.length === 1 && targets[0]?.object === "*") return "internal";
|
|
345
|
+
return targets.length > 1 ? "code-only" : "none";
|
|
346
|
+
}
|
|
347
|
+
function supportsMaxItems(attribute) {
|
|
348
|
+
if (attribute.type === "multiselect") return true;
|
|
349
|
+
if (attribute.type === "relation") return attribute.cardinality === "many";
|
|
350
|
+
return false;
|
|
351
|
+
}
|
|
352
|
+
function supportsQualifiedProperties(type) {
|
|
353
|
+
return type === "relation" || type === "document";
|
|
354
|
+
}
|
|
355
|
+
function isRequiredForbidden(type) {
|
|
356
|
+
return type === "checkbox" || type === "formula" || type === "rollup";
|
|
357
|
+
}
|
|
358
|
+
function getDefaultValueCapability(type) {
|
|
359
|
+
if (type === "checkbox") return "automatic";
|
|
360
|
+
if (type === "formula" || type === "rollup") return "forbidden";
|
|
361
|
+
if (STATIC_DEFAULT_TYPES.has(type)) return "static";
|
|
362
|
+
return "forbidden";
|
|
363
|
+
}
|
|
364
|
+
function isDefaultColumnType(type) {
|
|
365
|
+
return isTableCellType(type);
|
|
366
|
+
}
|
|
367
|
+
function isTableCellType(type) {
|
|
368
|
+
return type !== "richtext" && type !== "document";
|
|
369
|
+
}
|
|
370
|
+
function isFormFieldType(type) {
|
|
371
|
+
return type !== "richtext";
|
|
372
|
+
}
|
|
373
|
+
function resolveEditMode(attribute) {
|
|
374
|
+
switch (attribute.type) {
|
|
375
|
+
case "checkbox":
|
|
376
|
+
return "inline";
|
|
377
|
+
case "number":
|
|
378
|
+
return attribute.renderAs === "rating" ? "inline" : "default";
|
|
379
|
+
case "select":
|
|
380
|
+
case "multiselect":
|
|
381
|
+
return attribute.renderAs === "badges" ? "inline" : "popover";
|
|
382
|
+
case "status":
|
|
383
|
+
case "relation":
|
|
384
|
+
case "user":
|
|
385
|
+
return "popover";
|
|
386
|
+
default:
|
|
387
|
+
return "default";
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
function isGroupableType(type) {
|
|
391
|
+
return type === "status" || type === "currency";
|
|
392
|
+
}
|
|
393
|
+
function isContentReadableType(type) {
|
|
394
|
+
return type === "richtext" || type === "document";
|
|
395
|
+
}
|
|
396
|
+
function hasFilterOperatorEntry(type) {
|
|
397
|
+
return Object.prototype.hasOwnProperty.call(ATTRIBUTE_FILTER_OPERATORS, type);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// src/types/filters.ts
|
|
401
|
+
var OPERATORS_BY_TYPE = ATTRIBUTE_FILTER_OPERATORS;
|
|
402
|
+
var NO_VALUE_OPERATORS = ["is_empty", "is_not_empty"];
|
|
403
|
+
function isNoValueOperator(operator) {
|
|
404
|
+
return NO_VALUE_OPERATORS.includes(operator);
|
|
405
|
+
}
|
|
406
|
+
function getRollupFilterOperators2(attr) {
|
|
407
|
+
return getRollupFilterOperators(attr);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// src/filters/dynamic-value.ts
|
|
411
|
+
function isDynamicValue(value) {
|
|
412
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && "dynamic" in value;
|
|
413
|
+
}
|
|
414
|
+
function currentActor() {
|
|
415
|
+
return { dynamic: "actor", ref: "current" };
|
|
416
|
+
}
|
|
417
|
+
function today() {
|
|
418
|
+
return { dynamic: "date", anchor: "today" };
|
|
419
|
+
}
|
|
420
|
+
function now() {
|
|
421
|
+
return { dynamic: "date", anchor: "now" };
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// src/filters/normalize-operator.ts
|
|
425
|
+
var SYNONYM_ALIASES = {
|
|
426
|
+
// equality
|
|
427
|
+
eq: "is",
|
|
428
|
+
equals: "is",
|
|
429
|
+
equal: "is",
|
|
430
|
+
"==": "is",
|
|
431
|
+
"=": "is",
|
|
432
|
+
neq: "is_not",
|
|
433
|
+
notEqual: "is_not",
|
|
434
|
+
isNot: "is_not",
|
|
435
|
+
"!=": "is_not",
|
|
436
|
+
"<>": "is_not",
|
|
437
|
+
// ordering
|
|
438
|
+
lt: "less_than",
|
|
439
|
+
"<": "less_than",
|
|
440
|
+
gt: "greater_than",
|
|
441
|
+
">": "greater_than",
|
|
442
|
+
lte: "less_or_equal",
|
|
443
|
+
"<=": "less_or_equal",
|
|
444
|
+
gte: "greater_or_equal",
|
|
445
|
+
">=": "greater_or_equal",
|
|
446
|
+
// set
|
|
447
|
+
in: "any_of",
|
|
448
|
+
isAnyOf: "any_of",
|
|
449
|
+
oneOf: "any_of",
|
|
450
|
+
notIn: "none_of",
|
|
451
|
+
not_in: "none_of",
|
|
452
|
+
isNoneOf: "none_of",
|
|
453
|
+
notOneOf: "none_of",
|
|
454
|
+
// text
|
|
455
|
+
startsWith: "starts_with",
|
|
456
|
+
beginsWith: "starts_with",
|
|
457
|
+
endsWith: "ends_with",
|
|
458
|
+
doesNotContain: "not_contains",
|
|
459
|
+
notContain: "not_contains",
|
|
460
|
+
// nullity
|
|
461
|
+
isEmpty: "is_empty",
|
|
462
|
+
isNotEmpty: "is_not_empty"
|
|
463
|
+
};
|
|
464
|
+
function normalizeOperator(rawOp) {
|
|
465
|
+
return SYNONYM_ALIASES[rawOp] ?? rawOp;
|
|
466
|
+
}
|
|
467
|
+
function normalizeFilterRule(rule) {
|
|
468
|
+
const normalized = normalizeOperator(rule.operator);
|
|
469
|
+
return normalized === rule.operator ? rule : { ...rule, operator: normalized };
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
// src/filters/relative-date.ts
|
|
473
|
+
var MS_PER_DAY = 864e5;
|
|
474
|
+
var RELATIVE_DATE_UNITS = /* @__PURE__ */ new Set(["days", "weeks", "months", "years"]);
|
|
475
|
+
var RELATIVE_DATE_DIRECTIONS = /* @__PURE__ */ new Set(["past", "future"]);
|
|
476
|
+
function isRelativeDateValue(value) {
|
|
477
|
+
if (typeof value !== "object" || value === null) return false;
|
|
478
|
+
const rel = value;
|
|
479
|
+
return typeof rel.amount === "number" && Number.isFinite(rel.amount) && rel.amount > 0 && typeof rel.unit === "string" && RELATIVE_DATE_UNITS.has(rel.unit) && typeof rel.direction === "string" && RELATIVE_DATE_DIRECTIONS.has(rel.direction);
|
|
480
|
+
}
|
|
481
|
+
function utcDayStart(date) {
|
|
482
|
+
return Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
|
|
483
|
+
}
|
|
484
|
+
function shiftUtcDay(dayStartMs, amount, unit) {
|
|
485
|
+
if (unit === "days") return dayStartMs + amount * MS_PER_DAY;
|
|
486
|
+
if (unit === "weeks") return dayStartMs + amount * 7 * MS_PER_DAY;
|
|
487
|
+
const from = new Date(dayStartMs);
|
|
488
|
+
const year = from.getUTCFullYear() + (unit === "years" ? amount : 0);
|
|
489
|
+
const month = from.getUTCMonth() + (unit === "months" ? amount : 0);
|
|
490
|
+
const lastDayOfTargetMonth = new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
|
|
491
|
+
return Date.UTC(year, month, Math.min(from.getUTCDate(), lastDayOfTargetMonth));
|
|
492
|
+
}
|
|
493
|
+
function resolveIsWithinBounds(value, now2 = /* @__PURE__ */ new Date()) {
|
|
494
|
+
if (!isRelativeDateValue(value)) return null;
|
|
495
|
+
const todayStart = utcDayStart(now2);
|
|
496
|
+
const amount = Math.trunc(value.amount);
|
|
497
|
+
const bounds = value.direction === "past" ? {
|
|
498
|
+
startMs: shiftUtcDay(todayStart, -amount, value.unit),
|
|
499
|
+
endMs: todayStart + MS_PER_DAY
|
|
500
|
+
} : {
|
|
501
|
+
startMs: todayStart,
|
|
502
|
+
endMs: shiftUtcDay(todayStart, amount, value.unit) + MS_PER_DAY
|
|
503
|
+
};
|
|
504
|
+
if (!(Number.isFinite(bounds.startMs) && Number.isFinite(bounds.endMs))) return null;
|
|
505
|
+
return bounds;
|
|
506
|
+
}
|
|
507
|
+
function toUtcDayString(ms) {
|
|
508
|
+
return new Date(ms).toISOString().slice(0, 10);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
// src/filters/validation.ts
|
|
512
|
+
var REFERENCE_TYPES = /* @__PURE__ */ new Set(["relation", "document", "user"]);
|
|
513
|
+
var ID_LIKE_OPERATORS = [
|
|
514
|
+
"is",
|
|
515
|
+
"is_not",
|
|
516
|
+
"any_of",
|
|
517
|
+
"none_of",
|
|
518
|
+
"is_empty",
|
|
519
|
+
"is_not_empty"
|
|
520
|
+
];
|
|
521
|
+
var SYSTEM_FILTER_OPERATORS = {
|
|
522
|
+
// Identifier columns (uuid)
|
|
523
|
+
id: ID_LIKE_OPERATORS,
|
|
524
|
+
objectId: ID_LIKE_OPERATORS,
|
|
525
|
+
tenantId: ID_LIKE_OPERATORS,
|
|
526
|
+
// Free-form text columns share their counterpart's operator set
|
|
527
|
+
label: OPERATORS_BY_TYPE.text,
|
|
528
|
+
// Date columns
|
|
529
|
+
createdAt: OPERATORS_BY_TYPE.date,
|
|
530
|
+
updatedAt: OPERATORS_BY_TYPE.date,
|
|
531
|
+
deletedAt: OPERATORS_BY_TYPE.date,
|
|
532
|
+
// User columns (uuid → actor identity)
|
|
533
|
+
createdBy: OPERATORS_BY_TYPE.user,
|
|
534
|
+
lastUpdatedBy: OPERATORS_BY_TYPE.user
|
|
535
|
+
};
|
|
536
|
+
var SYSTEM_FILTER_ATTRIBUTE_TYPES = {
|
|
537
|
+
id: "text",
|
|
538
|
+
objectId: "text",
|
|
539
|
+
objectName: "text",
|
|
540
|
+
tenantId: "text",
|
|
541
|
+
label: "text",
|
|
542
|
+
createdAt: "date",
|
|
543
|
+
updatedAt: "date",
|
|
544
|
+
deletedAt: "date",
|
|
545
|
+
deletedBy: "user",
|
|
546
|
+
createdBy: "user",
|
|
547
|
+
lastUpdatedBy: "user",
|
|
548
|
+
visibility: "select",
|
|
549
|
+
ownedBy: "user"
|
|
550
|
+
};
|
|
551
|
+
var REMOVED_OPERATOR_REPLACEMENTS = {
|
|
552
|
+
before: '"less_than"',
|
|
553
|
+
after: '"greater_than"',
|
|
554
|
+
on_or_before: '"less_or_equal"',
|
|
555
|
+
on_or_after: '"greater_or_equal"',
|
|
556
|
+
is_checked: '"is" with value true',
|
|
557
|
+
is_not_checked: '"is" with value false',
|
|
558
|
+
day_month_eq: '"on_day_month"'
|
|
559
|
+
};
|
|
560
|
+
var SET_MEMBERSHIP_TYPES = new Set(
|
|
561
|
+
Object.entries(ATTRIBUTE_FILTER_OPERATORS).filter(([, ops]) => ops.includes("any_of") && !ops.includes("contains")).map(([type]) => type)
|
|
562
|
+
);
|
|
563
|
+
var SUBSTRING_TO_MEMBERSHIP = {
|
|
564
|
+
contains: "any_of",
|
|
565
|
+
not_contains: "none_of"
|
|
566
|
+
};
|
|
567
|
+
function resolveCanonicalOperator(rawOperator, effectiveType) {
|
|
568
|
+
const replacement = REMOVED_OPERATOR_REPLACEMENTS[rawOperator];
|
|
569
|
+
if (replacement) {
|
|
570
|
+
const m = `Unknown filter operator "${rawOperator}" \u2014 use ${replacement}`;
|
|
571
|
+
throw new ValidationError(m, [{ path: ["operator"], message: m }]);
|
|
572
|
+
}
|
|
573
|
+
const normalized = normalizeOperator(rawOperator);
|
|
574
|
+
const membership = SUBSTRING_TO_MEMBERSHIP[normalized];
|
|
575
|
+
if (membership && SET_MEMBERSHIP_TYPES.has(effectiveType)) {
|
|
576
|
+
const m = `Operator "${normalized}" is not valid for type "${effectiveType}" \u2014 use "${membership}"`;
|
|
577
|
+
throw new ValidationError(m, [{ path: ["operator"], message: m }]);
|
|
578
|
+
}
|
|
579
|
+
return normalized;
|
|
580
|
+
}
|
|
581
|
+
function assertOperatorForType(operator, type, context) {
|
|
582
|
+
const normalized = resolveCanonicalOperator(operator, type);
|
|
583
|
+
const ops = OPERATORS_BY_TYPE[type];
|
|
584
|
+
if (!ops?.includes(normalized)) {
|
|
585
|
+
const validList = ops?.length ? ops.join(", ") : "(no operators registered for this type)";
|
|
586
|
+
const summary = `Operator "${operator}" is not valid for ${context} type "${type}". Valid operators: ${validList}.`;
|
|
587
|
+
throw new ValidationError(summary, [
|
|
588
|
+
{
|
|
589
|
+
path: ["operator"],
|
|
590
|
+
message: summary
|
|
591
|
+
}
|
|
592
|
+
]);
|
|
593
|
+
}
|
|
594
|
+
return normalized;
|
|
595
|
+
}
|
|
596
|
+
function assertRelativeDateValue(rule) {
|
|
597
|
+
if (rule.operator !== "is_within") return;
|
|
598
|
+
if (!isRelativeDateValue(rule.value)) {
|
|
599
|
+
const m = `Operator "is_within" requires a relative-date value { amount: positive number, unit: days|weeks|months|years, direction: past|future }`;
|
|
600
|
+
throw new ValidationError(m, [{ path: ["value"], message: m }]);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
function assertDynamicValueForAttribute(rule, attrType) {
|
|
604
|
+
if (!isDynamicValue(rule.value)) return;
|
|
605
|
+
const v = rule.value;
|
|
606
|
+
if (v.dynamic === "actor" && attrType !== "user") {
|
|
607
|
+
const m = `actor token (@me) is only valid on user attributes, not "${attrType}"`;
|
|
608
|
+
throw new ValidationError(m, [{ path: ["value"], message: m }]);
|
|
609
|
+
}
|
|
610
|
+
if (v.dynamic === "date" && attrType !== "date") {
|
|
611
|
+
const m = `date token (@today/@now) is only valid on date attributes, not "${attrType}"`;
|
|
612
|
+
throw new ValidationError(m, [{ path: ["value"], message: m }]);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
function collectQualifiedRuleIssues(rule, context) {
|
|
616
|
+
try {
|
|
617
|
+
validateQualifiedRule({ ...rule }, context);
|
|
618
|
+
return [];
|
|
619
|
+
} catch (error) {
|
|
620
|
+
if (!(error instanceof ValidationError)) throw error;
|
|
621
|
+
return error.errors.map((issue) => ({ ...issue, path: [...issue.path] }));
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
function validateQualifiedRule(rule, context) {
|
|
625
|
+
const rootAttr = context.attributes.find((a) => a.name === rule.attribute);
|
|
626
|
+
const systemOps = SYSTEM_FILTER_OPERATORS[rule.attribute];
|
|
627
|
+
if (!(rootAttr || systemOps)) {
|
|
628
|
+
throw new ValidationError(`Unknown attribute: ${rule.attribute}`, [
|
|
629
|
+
{ path: ["attribute"], message: `Unknown attribute: ${rule.attribute}` }
|
|
630
|
+
]);
|
|
631
|
+
}
|
|
632
|
+
if (rule.quantifier !== void 0 && !rule.property) {
|
|
633
|
+
const m = `quantifier is only valid on qualified edge rules (set "property")`;
|
|
634
|
+
throw new ValidationError(m, [{ path: ["quantifier"], message: m }]);
|
|
635
|
+
}
|
|
636
|
+
if (!rootAttr) {
|
|
637
|
+
if (rule.property) {
|
|
638
|
+
throw new ValidationError(`Cannot qualify system attribute "${rule.attribute}"`, [
|
|
639
|
+
{ path: ["property"], message: `"${rule.attribute}" is a system column, not a reference` }
|
|
640
|
+
]);
|
|
641
|
+
}
|
|
642
|
+
const effectiveType = SYSTEM_FILTER_ATTRIBUTE_TYPES[rule.attribute] ?? "text";
|
|
643
|
+
const normalizedOperator = resolveCanonicalOperator(rule.operator, effectiveType);
|
|
644
|
+
if (!systemOps.includes(normalizedOperator)) {
|
|
645
|
+
const summary = `Operator "${rule.operator}" is not valid for system attribute "${rule.attribute}". Valid operators: ${systemOps.join(", ")}.`;
|
|
646
|
+
throw new ValidationError(summary, [{ path: ["operator"], message: summary }]);
|
|
647
|
+
}
|
|
648
|
+
rule.operator = normalizedOperator;
|
|
649
|
+
assertRelativeDateValue(rule);
|
|
650
|
+
return;
|
|
651
|
+
}
|
|
652
|
+
if (!rule.property) {
|
|
653
|
+
assertDynamicValueForAttribute(rule, rootAttr.type);
|
|
654
|
+
const ops = getAttributeFilterOperators(rootAttr);
|
|
655
|
+
const normalizedOperator = resolveCanonicalOperator(rule.operator, rootAttr.type);
|
|
656
|
+
if (!ops.includes(normalizedOperator)) {
|
|
657
|
+
const validList = ops.length ? ops.join(", ") : "(not filterable)";
|
|
658
|
+
const summary = `Operator "${rule.operator}" is not valid for attribute "${rootAttr.name}". Valid operators: ${validList}.`;
|
|
659
|
+
throw new ValidationError(summary, [{ path: ["operator"], message: summary }]);
|
|
660
|
+
}
|
|
661
|
+
rule.operator = normalizedOperator;
|
|
662
|
+
assertRelativeDateValue(rule);
|
|
663
|
+
return;
|
|
664
|
+
}
|
|
665
|
+
if (!REFERENCE_TYPES.has(rootAttr.type)) {
|
|
666
|
+
throw new ValidationError(`Cannot qualify ${rootAttr.type} attribute "${rule.attribute}"`, [
|
|
667
|
+
{ path: ["property"], message: `Attribute "${rule.attribute}" is not a reference type` }
|
|
668
|
+
]);
|
|
669
|
+
}
|
|
670
|
+
const propSchema = rootAttr.properties;
|
|
671
|
+
if (!propSchema) {
|
|
672
|
+
throw new ValidationError(`Attribute "${rule.attribute}" has no qualifyWith schema`, [
|
|
673
|
+
{ path: ["property"], message: `"${rule.attribute}" has no qualifyWith` }
|
|
674
|
+
]);
|
|
675
|
+
}
|
|
676
|
+
const propDef = propSchema.definitions.find((p) => p.name === rule.property);
|
|
677
|
+
if (!propDef) {
|
|
678
|
+
throw new ValidationError(
|
|
679
|
+
`Property "${rule.property}" not defined on "${rule.attribute}".qualifyWith()`,
|
|
680
|
+
[{ path: ["property"], message: `Unknown property: ${rule.property}` }]
|
|
681
|
+
);
|
|
682
|
+
}
|
|
683
|
+
rule.operator = assertOperatorForType(rule.operator, propDef.type, "property");
|
|
684
|
+
assertRelativeDateValue(rule);
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
// src/types/objects.ts
|
|
688
|
+
var RESOURCE_VISIBILITIES = ["workspace", "private"];
|
|
689
|
+
var LIST_VIEW_TAB_VISIBILITIES = ["all", ...RESOURCE_VISIBILITIES];
|
|
690
|
+
var SYSTEM_FIELD_NAMES = [
|
|
691
|
+
"id",
|
|
692
|
+
"createdAt",
|
|
693
|
+
"updatedAt",
|
|
694
|
+
"createdBy",
|
|
695
|
+
"lastUpdatedBy",
|
|
696
|
+
"visibility",
|
|
697
|
+
"ownedBy"
|
|
698
|
+
];
|
|
699
|
+
var RESERVED_ATTRIBUTE_NAMES = [
|
|
700
|
+
// System fields (auto-managed)
|
|
701
|
+
...SYSTEM_FIELD_NAMES,
|
|
702
|
+
// Other ObjectRecord properties
|
|
703
|
+
"objectId",
|
|
704
|
+
"label",
|
|
705
|
+
"embeddingText",
|
|
706
|
+
"values",
|
|
707
|
+
"metadata",
|
|
708
|
+
"deletedAt",
|
|
709
|
+
"deletedBy",
|
|
710
|
+
"schemaVersion",
|
|
711
|
+
// Physical SQL alias; custom attributes may otherwise use snake_case names.
|
|
712
|
+
"owned_by"
|
|
713
|
+
];
|
|
714
|
+
var RESERVED_OBJECT_NAMES = ["skill"];
|
|
715
|
+
|
|
716
|
+
// src/validators/view-config.schema.ts
|
|
717
|
+
var createModeSchema = z.enum(["redirect", "inline", "peek"]);
|
|
718
|
+
var nonEmptyStringArraySchema = z.array(z.string()).min(1);
|
|
719
|
+
var columnsSchema = z.array(z.string()).max(SCHEMA_LIMITS.columnsPerTab);
|
|
720
|
+
var sortRuleSchema = z.object({
|
|
721
|
+
attribute: z.string(),
|
|
722
|
+
direction: z.enum(["asc", "desc"])
|
|
723
|
+
}).strict();
|
|
724
|
+
var sortsSchema = z.array(sortRuleSchema).max(SCHEMA_LIMITS.sortsPerTab);
|
|
725
|
+
var relativeDateValueSchema = z.object({
|
|
726
|
+
amount: z.number(),
|
|
727
|
+
unit: z.enum(["days", "weeks", "months", "years"]),
|
|
728
|
+
direction: z.enum(["past", "future"])
|
|
729
|
+
}).strict();
|
|
730
|
+
var currencyFilterValueSchema = z.object({
|
|
731
|
+
value: z.number().nullable(),
|
|
732
|
+
code: z.array(z.string()).optional()
|
|
733
|
+
}).strict();
|
|
734
|
+
var phoneFilterValueSchema = z.object({
|
|
735
|
+
phoneNumber: z.string().nullable(),
|
|
736
|
+
countryCode: z.string().optional()
|
|
737
|
+
}).strict();
|
|
738
|
+
var dynamicFilterValueSchema = z.discriminatedUnion("dynamic", [
|
|
739
|
+
z.object({
|
|
740
|
+
dynamic: z.literal("actor"),
|
|
741
|
+
ref: z.literal("current")
|
|
742
|
+
}).strict(),
|
|
743
|
+
z.object({
|
|
744
|
+
dynamic: z.literal("date"),
|
|
745
|
+
anchor: z.enum(["today", "now"])
|
|
746
|
+
}).strict()
|
|
747
|
+
]);
|
|
748
|
+
var filterValueSchema = z.union([
|
|
749
|
+
z.string(),
|
|
750
|
+
z.number(),
|
|
751
|
+
z.boolean(),
|
|
752
|
+
z.array(z.string()),
|
|
753
|
+
relativeDateValueSchema,
|
|
754
|
+
currencyFilterValueSchema,
|
|
755
|
+
phoneFilterValueSchema,
|
|
756
|
+
dynamicFilterValueSchema,
|
|
757
|
+
z.null()
|
|
758
|
+
]);
|
|
759
|
+
var filterOperatorSchema = z.enum(
|
|
760
|
+
[
|
|
761
|
+
"is",
|
|
762
|
+
"is_not",
|
|
763
|
+
"contains",
|
|
764
|
+
"not_contains",
|
|
765
|
+
"starts_with",
|
|
766
|
+
"ends_with",
|
|
767
|
+
"is_empty",
|
|
768
|
+
"is_not_empty",
|
|
769
|
+
"less_than",
|
|
770
|
+
"greater_than",
|
|
771
|
+
"less_or_equal",
|
|
772
|
+
"greater_or_equal",
|
|
773
|
+
"is_within",
|
|
774
|
+
"on_day_month",
|
|
775
|
+
"any_of",
|
|
776
|
+
"none_of"
|
|
777
|
+
],
|
|
778
|
+
{
|
|
779
|
+
error: (issue) => {
|
|
780
|
+
const input = issue.input;
|
|
781
|
+
const replacement = typeof input === "string" ? REMOVED_OPERATOR_REPLACEMENTS[input] : void 0;
|
|
782
|
+
return replacement ? `Unknown filter operator "${input}" \u2014 use ${replacement}` : void 0;
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
);
|
|
786
|
+
var filterRuleSchema = z.object({
|
|
787
|
+
attribute: z.string(),
|
|
788
|
+
property: z.string().optional(),
|
|
789
|
+
quantifier: z.enum(["any", "none"]).optional(),
|
|
790
|
+
operator: filterOperatorSchema,
|
|
791
|
+
value: filterValueSchema
|
|
792
|
+
}).strict();
|
|
793
|
+
var filterRulesSchema = z.array(filterRuleSchema).max(SCHEMA_LIMITS.filterRulesPerTab);
|
|
794
|
+
var filterStateSchema = z.object({
|
|
795
|
+
combinator: z.enum(["and", "or"]),
|
|
796
|
+
rules: filterRulesSchema
|
|
797
|
+
}).strict();
|
|
798
|
+
var filterGroupSchema = z.object({
|
|
799
|
+
id: z.string(),
|
|
800
|
+
combinator: z.enum(["and", "or"]),
|
|
801
|
+
rules: filterRulesSchema
|
|
802
|
+
}).strict();
|
|
803
|
+
function addDuplicateIdIssues(values, ctx, pathPrefix = []) {
|
|
804
|
+
const seen = /* @__PURE__ */ new Set();
|
|
805
|
+
values.forEach((value, index) => {
|
|
806
|
+
if (seen.has(value.id)) {
|
|
807
|
+
ctx.addIssue({
|
|
808
|
+
code: "custom",
|
|
809
|
+
message: `Duplicate id "${value.id}"`,
|
|
810
|
+
path: [...pathPrefix, index, "id"]
|
|
811
|
+
});
|
|
812
|
+
}
|
|
813
|
+
seen.add(value.id);
|
|
814
|
+
});
|
|
815
|
+
}
|
|
816
|
+
function addDuplicateNameIssues(values, ctx, pathPrefix = []) {
|
|
817
|
+
const seen = /* @__PURE__ */ new Set();
|
|
818
|
+
values.forEach((value, index) => {
|
|
819
|
+
if (seen.has(value.name)) {
|
|
820
|
+
ctx.addIssue({
|
|
821
|
+
code: "custom",
|
|
822
|
+
message: `Duplicate name "${value.name}"`,
|
|
823
|
+
path: [...pathPrefix, index, "name"]
|
|
824
|
+
});
|
|
825
|
+
}
|
|
826
|
+
seen.add(value.name);
|
|
827
|
+
});
|
|
828
|
+
}
|
|
829
|
+
var attributeGroupFieldSchema = z.object({
|
|
830
|
+
id: z.string(),
|
|
831
|
+
label: z.string(),
|
|
832
|
+
description: z.string().optional(),
|
|
833
|
+
attributes: nonEmptyStringArraySchema,
|
|
834
|
+
displayTemplate: z.string().optional()
|
|
835
|
+
}).strict();
|
|
836
|
+
var fieldPresentationShape = {
|
|
837
|
+
span: z.union([
|
|
838
|
+
z.literal(1),
|
|
839
|
+
z.literal(2),
|
|
840
|
+
z.literal(3),
|
|
841
|
+
z.literal(4),
|
|
842
|
+
z.literal(5),
|
|
843
|
+
z.literal(6),
|
|
844
|
+
z.literal(7),
|
|
845
|
+
z.literal(8),
|
|
846
|
+
z.literal(9),
|
|
847
|
+
z.literal(10),
|
|
848
|
+
z.literal(11),
|
|
849
|
+
z.literal(12)
|
|
850
|
+
]).optional(),
|
|
851
|
+
label: z.string().optional(),
|
|
852
|
+
readOnly: z.boolean().optional()
|
|
853
|
+
};
|
|
854
|
+
var fieldSchema = z.object({
|
|
855
|
+
attribute: z.string().optional(),
|
|
856
|
+
attributeGroup: attributeGroupFieldSchema.optional(),
|
|
857
|
+
...fieldPresentationShape
|
|
858
|
+
}).strict().superRefine((field, ctx) => {
|
|
859
|
+
if (field.attribute === void 0 === (field.attributeGroup === void 0)) {
|
|
860
|
+
ctx.addIssue({
|
|
861
|
+
code: "custom",
|
|
862
|
+
message: "A field must define exactly one of attribute or attributeGroup"
|
|
863
|
+
});
|
|
864
|
+
}
|
|
865
|
+
});
|
|
866
|
+
var baseGroupShape = {
|
|
867
|
+
id: z.string(),
|
|
868
|
+
label: z.string(),
|
|
869
|
+
description: z.string().optional(),
|
|
870
|
+
collapsible: z.boolean().optional(),
|
|
871
|
+
collapsed: z.boolean().optional(),
|
|
872
|
+
order: z.number().optional()
|
|
873
|
+
};
|
|
874
|
+
var fieldGroupWriteSchema = z.object({
|
|
875
|
+
...baseGroupShape,
|
|
876
|
+
type: z.literal("fields"),
|
|
877
|
+
fields: z.array(fieldSchema).max(SCHEMA_LIMITS.fieldsPerGroup)
|
|
878
|
+
}).strict();
|
|
879
|
+
var relationGroupSchema = z.object({
|
|
880
|
+
...baseGroupShape,
|
|
881
|
+
type: z.literal("relation"),
|
|
882
|
+
attribute: z.string(),
|
|
883
|
+
columns: z.array(z.string()).max(SCHEMA_LIMITS.columnsPerTab).optional(),
|
|
884
|
+
readOnly: z.boolean().optional(),
|
|
885
|
+
allowCreate: z.boolean().optional()
|
|
886
|
+
}).strict();
|
|
887
|
+
var groupWriteSchema = z.discriminatedUnion("type", [fieldGroupWriteSchema, relationGroupSchema]);
|
|
888
|
+
var baseTabShape = {
|
|
889
|
+
id: z.string(),
|
|
890
|
+
name: z.string(),
|
|
891
|
+
label: z.string(),
|
|
892
|
+
icon: iconNameSchema.optional(),
|
|
893
|
+
order: z.number().optional()
|
|
894
|
+
};
|
|
895
|
+
var formTabWriteSchema = z.object({
|
|
896
|
+
...baseTabShape,
|
|
897
|
+
type: z.literal("form"),
|
|
898
|
+
groups: z.array(groupWriteSchema).min(1).max(SCHEMA_LIMITS.groupsPerFormTab),
|
|
899
|
+
formColumns: z.union([z.literal(1), z.literal(2), z.literal(3)]).optional(),
|
|
900
|
+
density: z.enum(["compact", "comfortable", "spacious"]).optional()
|
|
901
|
+
}).strict().superRefine((tab, ctx) => {
|
|
902
|
+
addDuplicateIdIssues(tab.groups, ctx, ["groups"]);
|
|
903
|
+
const totalFields = tab.groups.reduce(
|
|
904
|
+
(count, group) => count + (group.type === "fields" ? group.fields.length : 0),
|
|
905
|
+
0
|
|
906
|
+
);
|
|
907
|
+
if (totalFields > SCHEMA_LIMITS.fieldsPerFormTab) {
|
|
908
|
+
ctx.addIssue({
|
|
909
|
+
code: "too_big",
|
|
910
|
+
origin: "array",
|
|
911
|
+
maximum: SCHEMA_LIMITS.fieldsPerFormTab,
|
|
912
|
+
inclusive: true,
|
|
913
|
+
message: `A form tab can contain at most ${SCHEMA_LIMITS.fieldsPerFormTab} fields`,
|
|
914
|
+
path: ["groups"]
|
|
915
|
+
});
|
|
916
|
+
}
|
|
917
|
+
const seenAttributeGroupIds = /* @__PURE__ */ new Set();
|
|
918
|
+
tab.groups.forEach((group, groupIndex) => {
|
|
919
|
+
if (group.type !== "fields") return;
|
|
920
|
+
group.fields.forEach((field, fieldIndex) => {
|
|
921
|
+
if (field.attributeGroup === void 0) return;
|
|
922
|
+
const { id } = field.attributeGroup;
|
|
923
|
+
if (seenAttributeGroupIds.has(id)) {
|
|
924
|
+
ctx.addIssue({
|
|
925
|
+
code: "custom",
|
|
926
|
+
message: `Duplicate attribute group id "${id}"`,
|
|
927
|
+
path: ["groups", groupIndex, "fields", fieldIndex, "attributeGroup", "id"]
|
|
928
|
+
});
|
|
929
|
+
}
|
|
930
|
+
seenAttributeGroupIds.add(id);
|
|
931
|
+
});
|
|
932
|
+
});
|
|
933
|
+
});
|
|
934
|
+
var relationSourceSchema = z.object({
|
|
935
|
+
type: z.literal("relation"),
|
|
936
|
+
attribute: z.string()
|
|
937
|
+
}).strict();
|
|
938
|
+
var inverseSourceSchema = z.object({
|
|
939
|
+
type: z.literal("inverse"),
|
|
940
|
+
object: z.string(),
|
|
941
|
+
attribute: z.string()
|
|
942
|
+
}).strict();
|
|
943
|
+
var tableSourceSchema = z.discriminatedUnion("type", [
|
|
944
|
+
relationSourceSchema,
|
|
945
|
+
inverseSourceSchema
|
|
946
|
+
]);
|
|
947
|
+
var tableTabSchema = z.object({
|
|
948
|
+
...baseTabShape,
|
|
949
|
+
type: z.literal("table"),
|
|
950
|
+
source: tableSourceSchema,
|
|
951
|
+
columns: columnsSchema,
|
|
952
|
+
allowCreate: z.boolean().optional(),
|
|
953
|
+
createMode: createModeSchema.optional(),
|
|
954
|
+
allowEdit: z.boolean().optional(),
|
|
955
|
+
allowDelete: z.boolean().optional(),
|
|
956
|
+
filters: filterStateSchema.optional(),
|
|
957
|
+
sorts: sortsSchema.optional()
|
|
958
|
+
}).strict();
|
|
959
|
+
var JSON_PROPS_MAX_DEPTH = 64;
|
|
960
|
+
var JSON_PROPS_MAX_NODES = 1e4;
|
|
961
|
+
function isPlainJsonObject(value) {
|
|
962
|
+
const prototype = Object.getPrototypeOf(value);
|
|
963
|
+
return prototype === Object.prototype || prototype === null;
|
|
964
|
+
}
|
|
965
|
+
function addJsonIssue(ctx, message, path = []) {
|
|
966
|
+
ctx.addIssue({ code: "custom", message, path });
|
|
967
|
+
}
|
|
968
|
+
function pushJsonArrayChildren(current, frame, stack, ctx) {
|
|
969
|
+
for (const key of Reflect.ownKeys(current)) {
|
|
970
|
+
if (key === "length") continue;
|
|
971
|
+
if (key === "__proto__") {
|
|
972
|
+
addJsonIssue(ctx, "The __proto__ key is not allowed in custom props", [...frame.path, key]);
|
|
973
|
+
continue;
|
|
974
|
+
}
|
|
975
|
+
if (typeof key === "symbol" || !/^(0|[1-9]\d*)$/.test(key)) {
|
|
976
|
+
addJsonIssue(ctx, "Arrays cannot contain non-index JSON properties", [...frame.path, key]);
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
for (let index = current.length - 1; index >= 0; index--) {
|
|
980
|
+
const descriptor = Object.getOwnPropertyDescriptor(current, String(index));
|
|
981
|
+
const path = [...frame.path, index];
|
|
982
|
+
if (!(descriptor && "value" in descriptor)) {
|
|
983
|
+
addJsonIssue(ctx, "Sparse arrays are not valid JSON values", path);
|
|
984
|
+
continue;
|
|
985
|
+
}
|
|
986
|
+
stack.push({ kind: "enter", value: descriptor.value, path, depth: frame.depth + 1 });
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
function pushJsonObjectChildren(current, frame, stack, ctx) {
|
|
990
|
+
const keys = Reflect.ownKeys(current);
|
|
991
|
+
for (let index = keys.length - 1; index >= 0; index--) {
|
|
992
|
+
const key = keys[index];
|
|
993
|
+
const path = [...frame.path, key];
|
|
994
|
+
if (key === "__proto__") {
|
|
995
|
+
addJsonIssue(ctx, "The __proto__ key is not allowed in custom props", path);
|
|
996
|
+
continue;
|
|
997
|
+
}
|
|
998
|
+
if (typeof key === "symbol") {
|
|
999
|
+
addJsonIssue(ctx, "Symbol keys are not valid JSON keys", path);
|
|
1000
|
+
continue;
|
|
1001
|
+
}
|
|
1002
|
+
const descriptor = Object.getOwnPropertyDescriptor(current, key);
|
|
1003
|
+
if (!(descriptor?.enumerable && "value" in descriptor)) {
|
|
1004
|
+
addJsonIssue(ctx, "Custom props must contain enumerable data properties only", path);
|
|
1005
|
+
continue;
|
|
1006
|
+
}
|
|
1007
|
+
stack.push({ kind: "enter", value: descriptor.value, path, depth: frame.depth + 1 });
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
function validateJsonProps(value, ctx) {
|
|
1011
|
+
if (value === null || typeof value !== "object") {
|
|
1012
|
+
addJsonIssue(ctx, "Expected a plain JSON object");
|
|
1013
|
+
return;
|
|
1014
|
+
}
|
|
1015
|
+
try {
|
|
1016
|
+
if (Array.isArray(value) || !isPlainJsonObject(value)) {
|
|
1017
|
+
addJsonIssue(ctx, "Expected a plain JSON object");
|
|
1018
|
+
return;
|
|
1019
|
+
}
|
|
1020
|
+
} catch {
|
|
1021
|
+
addJsonIssue(ctx, "Custom props contain an object that cannot be safely inspected");
|
|
1022
|
+
return;
|
|
1023
|
+
}
|
|
1024
|
+
const activeChain = /* @__PURE__ */ new WeakSet();
|
|
1025
|
+
const stack = [{ kind: "enter", value, path: [], depth: 0 }];
|
|
1026
|
+
let visitedNodes = 0;
|
|
1027
|
+
while (stack.length > 0) {
|
|
1028
|
+
const frame = stack.pop();
|
|
1029
|
+
if (!frame) break;
|
|
1030
|
+
if (frame.kind === "exit") {
|
|
1031
|
+
activeChain.delete(frame.value);
|
|
1032
|
+
continue;
|
|
1033
|
+
}
|
|
1034
|
+
visitedNodes++;
|
|
1035
|
+
if (visitedNodes > JSON_PROPS_MAX_NODES) {
|
|
1036
|
+
addJsonIssue(
|
|
1037
|
+
ctx,
|
|
1038
|
+
`Custom props cannot exceed ${JSON_PROPS_MAX_NODES.toLocaleString("en-US")} total JSON nodes`,
|
|
1039
|
+
frame.path
|
|
1040
|
+
);
|
|
1041
|
+
return;
|
|
1042
|
+
}
|
|
1043
|
+
if (frame.depth > JSON_PROPS_MAX_DEPTH) {
|
|
1044
|
+
addJsonIssue(ctx, `Custom props cannot exceed depth ${JSON_PROPS_MAX_DEPTH}`, frame.path);
|
|
1045
|
+
continue;
|
|
1046
|
+
}
|
|
1047
|
+
const current = frame.value;
|
|
1048
|
+
if (current === null || typeof current === "string" || typeof current === "boolean" || typeof current === "number" && Number.isFinite(current)) {
|
|
1049
|
+
continue;
|
|
1050
|
+
}
|
|
1051
|
+
if (typeof current !== "object") {
|
|
1052
|
+
addJsonIssue(ctx, "Expected a JSON value", frame.path);
|
|
1053
|
+
continue;
|
|
1054
|
+
}
|
|
1055
|
+
if (activeChain.has(current)) {
|
|
1056
|
+
addJsonIssue(ctx, "Custom props cannot contain circular references", frame.path);
|
|
1057
|
+
continue;
|
|
1058
|
+
}
|
|
1059
|
+
try {
|
|
1060
|
+
if (Array.isArray(current)) {
|
|
1061
|
+
activeChain.add(current);
|
|
1062
|
+
stack.push({ kind: "exit", value: current });
|
|
1063
|
+
pushJsonArrayChildren(current, frame, stack, ctx);
|
|
1064
|
+
continue;
|
|
1065
|
+
}
|
|
1066
|
+
if (!isPlainJsonObject(current)) {
|
|
1067
|
+
addJsonIssue(ctx, "Expected an array or plain JSON object", frame.path);
|
|
1068
|
+
continue;
|
|
1069
|
+
}
|
|
1070
|
+
activeChain.add(current);
|
|
1071
|
+
stack.push({ kind: "exit", value: current });
|
|
1072
|
+
pushJsonObjectChildren(current, frame, stack, ctx);
|
|
1073
|
+
} catch {
|
|
1074
|
+
addJsonIssue(
|
|
1075
|
+
ctx,
|
|
1076
|
+
"Custom props contain an object that cannot be safely inspected",
|
|
1077
|
+
frame.path
|
|
1078
|
+
);
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
var jsonPropsSchema = z.unknown().superRefine(validateJsonProps).transform((value) => value);
|
|
1083
|
+
var customTabSchema = z.object({
|
|
1084
|
+
...baseTabShape,
|
|
1085
|
+
type: z.literal("custom"),
|
|
1086
|
+
component: z.string(),
|
|
1087
|
+
props: jsonPropsSchema.optional()
|
|
1088
|
+
}).strict();
|
|
1089
|
+
var activityTabSchema = z.object({
|
|
1090
|
+
...baseTabShape,
|
|
1091
|
+
type: z.literal("activity"),
|
|
1092
|
+
limit: z.number().optional()
|
|
1093
|
+
}).strict();
|
|
1094
|
+
var richtextTabSchema = z.object({
|
|
1095
|
+
...baseTabShape,
|
|
1096
|
+
type: z.literal("richtext"),
|
|
1097
|
+
attribute: z.string(),
|
|
1098
|
+
titleAttribute: z.string().optional()
|
|
1099
|
+
}).strict();
|
|
1100
|
+
var documentsTabSchema = z.object({
|
|
1101
|
+
...baseTabShape,
|
|
1102
|
+
type: z.literal("documents"),
|
|
1103
|
+
allowUpload: z.boolean().optional(),
|
|
1104
|
+
allowRemove: z.boolean().optional(),
|
|
1105
|
+
hideAttachments: z.boolean().optional()
|
|
1106
|
+
}).strict();
|
|
1107
|
+
var formsTabSchema = z.object({
|
|
1108
|
+
...baseTabShape,
|
|
1109
|
+
type: z.literal("forms"),
|
|
1110
|
+
objectName: z.string().optional()
|
|
1111
|
+
}).strict();
|
|
1112
|
+
var emailsTabSchema = z.object({
|
|
1113
|
+
...baseTabShape,
|
|
1114
|
+
type: z.literal("emails"),
|
|
1115
|
+
emailAttributeIds: z.array(z.string()).max(SCHEMA_LIMITS.emailAttributesPerTab)
|
|
1116
|
+
}).strict();
|
|
1117
|
+
var detailTabSchema = z.discriminatedUnion("type", [
|
|
1118
|
+
formTabWriteSchema,
|
|
1119
|
+
tableTabSchema,
|
|
1120
|
+
customTabSchema,
|
|
1121
|
+
activityTabSchema,
|
|
1122
|
+
richtextTabSchema,
|
|
1123
|
+
documentsTabSchema,
|
|
1124
|
+
formsTabSchema,
|
|
1125
|
+
emailsTabSchema
|
|
1126
|
+
]);
|
|
1127
|
+
var listTabCommonShape = {
|
|
1128
|
+
id: z.string(),
|
|
1129
|
+
label: z.string(),
|
|
1130
|
+
icon: iconNameSchema.optional(),
|
|
1131
|
+
default: z.boolean().optional(),
|
|
1132
|
+
// Which records the tab scopes to. `"all"` is the default and means "impose
|
|
1133
|
+
// no scope" — the mandatory viewer predicate alone decides, so the tab shows
|
|
1134
|
+
// workspace records plus the viewer's own private ones. Defaulted rather than
|
|
1135
|
+
// required so configs stored before the field existed still parse.
|
|
1136
|
+
visibility: z.enum(LIST_VIEW_TAB_VISIBILITIES).default("all"),
|
|
1137
|
+
columns: columnsSchema,
|
|
1138
|
+
filters: filterGroupSchema.optional(),
|
|
1139
|
+
sorts: sortsSchema.optional(),
|
|
1140
|
+
readOnly: z.boolean().optional(),
|
|
1141
|
+
createMode: createModeSchema.optional()
|
|
1142
|
+
};
|
|
1143
|
+
var listTableTabSchema = z.object({
|
|
1144
|
+
...listTabCommonShape,
|
|
1145
|
+
layout: z.literal("table"),
|
|
1146
|
+
columnSizing: z.record(z.string(), z.number()).optional()
|
|
1147
|
+
}).strict();
|
|
1148
|
+
var listKanbanTabSchema = z.object({
|
|
1149
|
+
...listTabCommonShape,
|
|
1150
|
+
layout: z.literal("kanban"),
|
|
1151
|
+
groupByAttribute: z.string(),
|
|
1152
|
+
cardUserAttribute: z.string().optional(),
|
|
1153
|
+
cardDateAttribute: z.string().optional(),
|
|
1154
|
+
kanbanColumnOrder: z.array(z.string()).optional(),
|
|
1155
|
+
kanbanColumnVisibility: z.record(z.string(), z.boolean()).optional(),
|
|
1156
|
+
kanbanPinnedColumns: z.array(z.string()).optional()
|
|
1157
|
+
}).strict();
|
|
1158
|
+
var listViewTabSchema = z.discriminatedUnion("layout", [
|
|
1159
|
+
listTableTabSchema,
|
|
1160
|
+
listKanbanTabSchema
|
|
1161
|
+
]);
|
|
1162
|
+
var _listViewConfigSchema = z.object({
|
|
1163
|
+
defaultFilters: filterGroupSchema.optional(),
|
|
1164
|
+
tabs: z.array(listViewTabSchema).min(1).max(SCHEMA_LIMITS.tabsPerView)
|
|
1165
|
+
}).strict().superRefine((config, ctx) => {
|
|
1166
|
+
addDuplicateIdIssues(config.tabs, ctx, ["tabs"]);
|
|
1167
|
+
let hasDefault = false;
|
|
1168
|
+
config.tabs.forEach((tab, index) => {
|
|
1169
|
+
if (!tab.default) return;
|
|
1170
|
+
if (hasDefault) {
|
|
1171
|
+
ctx.addIssue({
|
|
1172
|
+
code: "custom",
|
|
1173
|
+
message: "Only one list tab can be the default",
|
|
1174
|
+
path: ["tabs", index, "default"]
|
|
1175
|
+
});
|
|
1176
|
+
}
|
|
1177
|
+
hasDefault = true;
|
|
1178
|
+
});
|
|
1179
|
+
});
|
|
1180
|
+
var _detailViewConfigSchema = z.object({
|
|
1181
|
+
tabs: z.array(detailTabSchema).min(1).max(SCHEMA_LIMITS.tabsPerView),
|
|
1182
|
+
sidePanel: z.object({
|
|
1183
|
+
attributes: z.array(z.string()).max(SCHEMA_LIMITS.sidePanelAttributes),
|
|
1184
|
+
width: z.number().optional()
|
|
1185
|
+
}).strict().optional()
|
|
1186
|
+
}).strict().superRefine((config, ctx) => {
|
|
1187
|
+
addDuplicateIdIssues(config.tabs, ctx, ["tabs"]);
|
|
1188
|
+
addDuplicateNameIssues(config.tabs, ctx, ["tabs"]);
|
|
1189
|
+
});
|
|
1190
|
+
var listViewConfigSchema = _listViewConfigSchema;
|
|
1191
|
+
var detailViewConfigSchema = _detailViewConfigSchema;
|
|
1192
|
+
var viewTypeSchema = z.enum(["list", "detail"]);
|
|
1193
|
+
var viewConfigByTypeSchema = z.discriminatedUnion("type", [
|
|
1194
|
+
z.object({
|
|
1195
|
+
type: z.literal("list"),
|
|
1196
|
+
config: listViewConfigSchema
|
|
1197
|
+
}).strict(),
|
|
1198
|
+
z.object({
|
|
1199
|
+
type: z.literal("detail"),
|
|
1200
|
+
config: detailViewConfigSchema
|
|
1201
|
+
}).strict()
|
|
1202
|
+
]);
|
|
1203
|
+
function parseViewConfig(type, input) {
|
|
1204
|
+
switch (type) {
|
|
1205
|
+
case "list":
|
|
1206
|
+
return listViewConfigSchema.parse(input);
|
|
1207
|
+
case "detail":
|
|
1208
|
+
return detailViewConfigSchema.parse(input);
|
|
1209
|
+
default:
|
|
1210
|
+
return viewConfigByTypeSchema.parse({ type, config: input }).config;
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
export { ATTRIBUTE_FILTER_OPERATORS, LIST_VIEW_TAB_VISIBILITIES, NO_VALUE_OPERATORS, OPERATORS_BY_TYPE, REMOVED_OPERATOR_REPLACEMENTS, RESERVED_ATTRIBUTE_NAMES, RESERVED_OBJECT_NAMES, RESOURCE_VISIBILITIES, SYNONYM_ALIASES, SYSTEM_ATTRIBUTES, SYSTEM_ATTRIBUTE_I18N_KEYS, SYSTEM_FIELD_NAMES, SYSTEM_FILTER_ATTRIBUTE_TYPES, collectQualifiedRuleIssues, currentActor, detailTabSchema, detailViewConfigSchema, getAttributeCapabilities, getAttributeFilterOperators, getRollupFilterOperators2 as getRollupFilterOperators, getSystemAttributeI18nKey, getSystemAttributeList, inverseSourceSchema, isAttributeFilterable, isAttributeGroupable, isAttributeKanbanGroupable, isAttributeSearchable, isAttributeSortable, isDynamicValue, isManagedSystemAttribute, isNoValueOperator, isRelativeDateValue, listViewConfigSchema, listViewTabSchema, normalizeFilterRule, normalizeOperator, now, parseViewConfig, relationSourceSchema, resolveIsWithinBounds, tableSourceSchema, toUtcDayString, today, validateQualifiedRule, viewConfigByTypeSchema, viewTypeSchema };
|