@stndrds/schema 1.0.0-alpha.280 → 1.0.0-alpha.282
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-Ig0ig9wp.d.ts → all-C3EaFLCU.d.ts} +7 -17
- package/dist/{all-C0hXd79K.d.mts → all-CQMswOrw.d.mts} +7 -17
- package/dist/{attributes-D8eHv5Kf.d.ts → attributes-CU871AfG.d.ts} +12 -12
- package/dist/{attributes--M1ifW8_.d.mts → attributes-DoiGyNFk.d.mts} +12 -12
- package/dist/{chunk-FAEOVIDJ.js → chunk-DIMTNM3F.js} +7 -3
- package/dist/{chunk-NUEIGMYS.mjs → chunk-EFSS7PGC.mjs} +1 -1
- package/dist/{chunk-XDA5PZRT.mjs → chunk-HOVUEYEQ.mjs} +34 -0
- package/dist/{chunk-MXYCCUNB.js → chunk-KIMECN6D.js} +68 -44
- package/dist/{chunk-M3WFXOA4.js → chunk-L4KLYMUI.js} +34 -0
- package/dist/{chunk-XTBGGJ3G.js → chunk-LBGLB443.js} +3 -3
- package/dist/{chunk-PUMM6SPY.mjs → chunk-PLTLAMWJ.mjs} +1 -1
- package/dist/{chunk-TBAD2T7Q.mjs → chunk-QGRYOIHT.mjs} +37 -13
- package/dist/{chunk-MSIGO7JA.mjs → chunk-R34LOMT7.mjs} +5 -1
- package/dist/{chunk-3PGLMGTR.js → chunk-V4MZOTLV.js} +4 -4
- package/dist/exceptions.d.mts +22 -3
- package/dist/exceptions.d.ts +22 -3
- package/dist/exceptions.js +39 -39
- package/dist/exceptions.mjs +1 -1
- package/dist/{helpers-DyoPqiSz.d.ts → helpers-BNr-Dppk.d.ts} +3 -3
- package/dist/{helpers-BiABdSxK.d.mts → helpers-CfEOUBmB.d.mts} +3 -3
- package/dist/{index-SpFpkWVC.d.ts → index-Br7koyHF.d.ts} +53 -27
- package/dist/{index-C3P5Dnwt.d.mts → index-D9XBjFnu.d.mts} +53 -27
- package/dist/index.d.mts +568 -151
- package/dist/index.d.ts +568 -151
- package/dist/index.js +1389 -292
- package/dist/index.mjs +1174 -99
- package/dist/{migrations-B1kkIhIX.d.ts → migrations-BGWgXHXb.d.ts} +1 -1
- package/dist/{migrations-BNlQVzDC.d.mts → migrations-C-GN1xx_.d.mts} +1 -1
- package/dist/{objects-DmMqHn3L.d.mts → objects-BRypaBpi.d.mts} +2 -4
- package/dist/{objects-DgFojgwH.d.ts → objects-BiOMwzLL.d.ts} +2 -4
- package/dist/{types-DHqXzkgW.d.mts → types-80c2rOUZ.d.mts} +1 -1
- package/dist/{types-DYYFto8d.d.ts → types-DqYz8Iv_.d.ts} +1 -1
- package/dist/utils.js +8 -8
- package/dist/utils.mjs +2 -2
- package/dist/validation/all.d.mts +7 -7
- package/dist/validation/all.d.ts +7 -7
- package/dist/validation/all.js +29 -29
- package/dist/validation/all.mjs +4 -4
- 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/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 +4 -4
- package/dist/validation/config/index.d.ts +4 -4
- package/dist/validation/config/index.js +11 -11
- package/dist/validation/config/index.mjs +2 -2
- 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 -5
- package/dist/validation/object/index.d.ts +5 -5
- package/dist/validation/object/index.js +14 -14
- package/dist/validation/object/index.mjs +2 -2
- 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/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { canonicalStringify, generateId } from './chunk-
|
|
2
|
-
export { asTenantId, asUserId, canonicalStringify, deepEqual, generateId, indexBy } from './chunk-
|
|
3
|
-
import { SYSTEM_FILTER_ATTRIBUTE_TYPES, RESERVED_OBJECT_NAMES, listViewConfigSchema, detailViewConfigSchema, RESERVED_ATTRIBUTE_NAMES, isAttributeSortable, getAttributeCapabilities, resolveIsWithinBounds, normalizeForEdgeRpc, getOperatorPolarity, extractCurrencyFilterValue } from './chunk-
|
|
4
|
-
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, canonicalizeFilterValue, collectQualifiedRuleIssues, currentActor, detailTabSchema, detailViewConfigSchema, extractCurrencyFilterValue, extractFilterValue, getAttributeCapabilities, getAttributeFilterOperators, getOperatorPolarity, getRollupFilterOperators, getSystemAttributeI18nKey, getSystemAttributeList, inverseSourceSchema, isAttributeFilterable, isAttributeGroupable, isAttributeKanbanGroupable, isAttributeSearchable, isDynamicValue, isManagedSystemAttribute, isNoValueOperator, isRelativeDateValue, isSetMembershipOperator, listViewConfigSchema, listViewTabSchema, normalizeFilterRule, normalizeForEdgeRpc, normalizeOperator, now, parseResourceVisibility, parseViewConfig, relationSourceSchema, resolveEffectiveFilterType, resolveIsWithinBounds, resolveUtcDayBounds, tableSourceSchema, toMultiValueOperator, toUtcDayString, today, validateQualifiedRule, viewConfigByTypeSchema, viewTypeSchema } from './chunk-
|
|
5
|
-
import { iconNameSchema, parseAttributeConfigForCreate, parseComputedFormula } from './chunk-
|
|
6
|
-
export { ComputedFormulaParseError, SCHEMA_LIMITS, colorIdSchema, iconNameSchema, multiselectOptionWriteSchema, parseAttributeConfig, parseAttributeConfigForCreate, parseAttributeConfigForUpdate, parseComputedFormula, selectOptionWriteSchema, statusGroupSchema, statusOptionWriteSchema } from './chunk-
|
|
7
|
-
import { createObjectValidator, createAttributeValidator, isNullishOrEmptyString } from './chunk-
|
|
8
|
-
export { createFormAttributeValidator, isNullishOrEmptyString, isValuePresent, rejectUnknownAttributesOrThrow, validateDraft, validateDraftOrThrow, validateObject, validateObjectOrThrow } from './chunk-
|
|
1
|
+
import { canonicalStringify, generateId } from './chunk-EFSS7PGC.mjs';
|
|
2
|
+
export { asTenantId, asUserId, canonicalStringify, deepEqual, generateId, indexBy } from './chunk-EFSS7PGC.mjs';
|
|
3
|
+
import { SYSTEM_FILTER_ATTRIBUTE_TYPES, RESERVED_OBJECT_NAMES, listViewConfigSchema, detailViewConfigSchema, LIST_VIEW_TAB_VISIBILITIES, RESERVED_ATTRIBUTE_NAMES, isAttributeSortable, getAttributeCapabilities, resolveIsWithinBounds, normalizeForEdgeRpc, getOperatorPolarity, extractCurrencyFilterValue } from './chunk-QGRYOIHT.mjs';
|
|
4
|
+
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, canonicalizeFilterValue, collectQualifiedRuleIssues, currentActor, detailTabSchema, detailViewConfigSchema, extractCurrencyFilterValue, extractFilterValue, getAttributeCapabilities, getAttributeFilterOperators, getOperatorPolarity, getRollupFilterOperators, getSystemAttributeI18nKey, getSystemAttributeList, inverseSourceSchema, isAttributeFilterable, isAttributeGroupable, isAttributeKanbanGroupable, isAttributeSearchable, isDynamicValue, isManagedSystemAttribute, isNoValueOperator, isRelativeDateValue, isSetMembershipOperator, listViewConfigSchema, listViewTabSchema, normalizeFilterRule, normalizeForEdgeRpc, normalizeOperator, now, parseResourceVisibility, parseViewConfig, relationSourceSchema, resolveEffectiveFilterType, resolveIsWithinBounds, resolveUtcDayBounds, tableSourceSchema, toMultiValueOperator, toUtcDayString, today, validateQualifiedRule, viewConfigByTypeSchema, viewTypeSchema } from './chunk-QGRYOIHT.mjs';
|
|
5
|
+
import { iconNameSchema, parseAttributeConfigForCreate, parseComputedFormula } from './chunk-R34LOMT7.mjs';
|
|
6
|
+
export { ComputedFormulaParseError, SCHEMA_LIMITS, colorIdSchema, iconNameSchema, multiselectOptionWriteSchema, parseAttributeConfig, parseAttributeConfigForCreate, parseAttributeConfigForUpdate, parseComputedFormula, selectOptionWriteSchema, statusGroupSchema, statusOptionWriteSchema } from './chunk-R34LOMT7.mjs';
|
|
7
|
+
import { createObjectValidator, createAttributeValidator, isNullishOrEmptyString } from './chunk-PLTLAMWJ.mjs';
|
|
8
|
+
export { createFormAttributeValidator, isNullishOrEmptyString, isValuePresent, rejectUnknownAttributesOrThrow, validateDraft, validateDraftOrThrow, validateObject, validateObjectOrThrow } from './chunk-PLTLAMWJ.mjs';
|
|
9
9
|
import './chunk-QVLQPW3O.mjs';
|
|
10
10
|
import './chunk-ZDQ5AP26.mjs';
|
|
11
11
|
import './chunk-LV3FEUKU.mjs';
|
|
@@ -15,8 +15,8 @@ export { createCheckboxValidator } from './chunk-OSSGN43B.mjs';
|
|
|
15
15
|
export { createDateValidator } from './chunk-Q44QKLN4.mjs';
|
|
16
16
|
export { createNumberValidator } from './chunk-UANQJ2GH.mjs';
|
|
17
17
|
export { TEXT_FORMAT_PATTERNS, createTextValidator, resolveTextPattern } from './chunk-O73ROMWQ.mjs';
|
|
18
|
-
import { SchemaError, SchemaErrorCode, ValidationError, DuplicateError, NotFoundError } from './chunk-
|
|
19
|
-
export { AccessDeniedError, AttributeInUseError, AttributeNotFoundError, ChangeTypeNotSupportedError, ConcurrentModificationError, DestructiveSyncNotAllowedError, DuplicateError, ForbiddenError, MemoryNotFoundError, MigrationTimeoutError, NotFoundError, NotImplementedError, ObjectNotFoundError, ObjectReferencedError, OrphanSystemAttributeError, ProtectedResourceError, ProtectedRoleError, RecordNotFoundError, RecordReferencedError, RepositoryError, RoleNotFoundError, SchemaError, SchemaErrorCode, SchemaPlanNotFoundError, SearchBackendError, StorageError, SyncCascadeError, SyncConflictError, SyncError, SystemEntityImmutableError, ValidationError, isAttributeInUseError, isNotFoundError, isObjectReferencedError, isProtectedResourceError, isRecordReferencedError, isSchemaError, isValidationError } from './chunk-
|
|
18
|
+
import { SchemaError, SchemaErrorCode, ValidationError, DuplicateError, NotFoundError } from './chunk-HOVUEYEQ.mjs';
|
|
19
|
+
export { AccessDeniedError, AttributeInUseError, AttributeNotFoundError, ChangeTypeNotSupportedError, ConcurrentModificationError, DestructiveSyncNotAllowedError, DuplicateError, ForbiddenError, MemoryNotFoundError, MigrationTimeoutError, NotFoundError, NotImplementedError, ObjectNotFoundError, ObjectReferencedError, OrphanSystemAttributeError, ProtectedResourceError, ProtectedRoleError, RecordNotFoundError, RecordReferencedError, RepositoryError, RoleNotFoundError, SchemaError, SchemaErrorCode, SchemaPlanNotFoundError, SearchBackendError, StorageError, SyncCascadeError, SyncConflictError, SyncError, SystemEntityImmutableError, ValidationError, isAttributeInUseError, isNotFoundError, isObjectReferencedError, isProtectedResourceError, isRecordReferencedError, isSchemaError, isValidationError } from './chunk-HOVUEYEQ.mjs';
|
|
20
20
|
import './chunk-AYVHMVKQ.mjs';
|
|
21
21
|
import './chunk-YUFTHPOE.mjs';
|
|
22
22
|
import { formatPhoneForDisplay, normalizeCountrylessPhoneNumber, normalizePhoneNumber } from './chunk-R5LAJCBU.mjs';
|
|
@@ -184,6 +184,18 @@ var SESSION_TERMINAL_STATUSES = [
|
|
|
184
184
|
function isTerminalSessionStatus(status2) {
|
|
185
185
|
return SESSION_TERMINAL_STATUSES.includes(status2);
|
|
186
186
|
}
|
|
187
|
+
var CLAIMABLE_SESSION_STATUSES = [
|
|
188
|
+
"idle",
|
|
189
|
+
"completed",
|
|
190
|
+
"waiting_human",
|
|
191
|
+
"waiting_agents",
|
|
192
|
+
"cancelled",
|
|
193
|
+
"failed",
|
|
194
|
+
"timeout"
|
|
195
|
+
];
|
|
196
|
+
function isClaimableSessionStatus(status2) {
|
|
197
|
+
return CLAIMABLE_SESSION_STATUSES.includes(status2);
|
|
198
|
+
}
|
|
187
199
|
var DEFAULT_APPROVAL_POLICY = Object.freeze({
|
|
188
200
|
mutation: "ask",
|
|
189
201
|
destructive: "ask",
|
|
@@ -193,6 +205,18 @@ var TODO_PLAN_STATUSES = ["active", "completed", "abandoned"];
|
|
|
193
205
|
function agentDisplayName(agent2) {
|
|
194
206
|
return agent2.label?.trim() || agent2.name;
|
|
195
207
|
}
|
|
208
|
+
var TOOL_APPROVAL_STATES = [
|
|
209
|
+
"approval-requested",
|
|
210
|
+
"approval-responded",
|
|
211
|
+
"approval-dispatched"
|
|
212
|
+
];
|
|
213
|
+
var OPEN_TOOL_PART_STATES = ["streaming", "running", ...TOOL_APPROVAL_STATES];
|
|
214
|
+
function isOpenToolPartState(state) {
|
|
215
|
+
return OPEN_TOOL_PART_STATES.includes(state);
|
|
216
|
+
}
|
|
217
|
+
function isToolApprovalState(state) {
|
|
218
|
+
return TOOL_APPROVAL_STATES.includes(state);
|
|
219
|
+
}
|
|
196
220
|
var TODO_STATUSES = ["pending", "in_progress", "completed", "blocked"];
|
|
197
221
|
var MAX_TODOS = 50;
|
|
198
222
|
var MAX_TODO_ID_CHARS = 80;
|
|
@@ -296,6 +320,15 @@ function resolveFieldRequired(input) {
|
|
|
296
320
|
function getSlotFieldTargets(field) {
|
|
297
321
|
return field.additionalSlotIds?.length ? [field.slotId, ...field.additionalSlotIds] : [field.slotId];
|
|
298
322
|
}
|
|
323
|
+
function formFieldKey(field) {
|
|
324
|
+
return isFormSlotFieldRef(field) ? `${field.slotId}.${field.attribute}` : `free.${field.attribute.name}`;
|
|
325
|
+
}
|
|
326
|
+
function formFieldFlatKey(field) {
|
|
327
|
+
return isFormSlotFieldRef(field) ? field.attribute : field.attribute.name;
|
|
328
|
+
}
|
|
329
|
+
function readFormFieldValue(values, field) {
|
|
330
|
+
return values[formFieldKey(field)] ?? values[formFieldFlatKey(field)];
|
|
331
|
+
}
|
|
299
332
|
|
|
300
333
|
// src/types/forms/rows.ts
|
|
301
334
|
function isFormFieldsRow(row) {
|
|
@@ -375,9 +408,6 @@ function isListView(view) {
|
|
|
375
408
|
function isFieldGroup(group2) {
|
|
376
409
|
return group2.type === "fields";
|
|
377
410
|
}
|
|
378
|
-
function isRelationGroup(group2) {
|
|
379
|
-
return group2.type === "relation";
|
|
380
|
-
}
|
|
381
411
|
|
|
382
412
|
// src/types/pagination.ts
|
|
383
413
|
var COUNT_MODES = ["none", "estimated", "exact"];
|
|
@@ -386,8 +416,7 @@ function parseCountMode(value) {
|
|
|
386
416
|
return value;
|
|
387
417
|
}
|
|
388
418
|
throw new ValidationError(
|
|
389
|
-
|
|
390
|
-
"countMode must be one of: " + COUNT_MODES.join(", ") + " (received: " + String(value) + ")",
|
|
419
|
+
`countMode must be one of: ${COUNT_MODES.join(", ")} (received: ${String(value)})`,
|
|
391
420
|
[]
|
|
392
421
|
);
|
|
393
422
|
}
|
|
@@ -859,6 +888,12 @@ function relationPropertyDefs(attribute) {
|
|
|
859
888
|
if (attribute?.type !== "relation") return void 0;
|
|
860
889
|
return attribute.properties?.definitions;
|
|
861
890
|
}
|
|
891
|
+
function qualifiedPropertyDefs(attribute) {
|
|
892
|
+
if (attribute?.type === "relation" || attribute?.type === "document") {
|
|
893
|
+
return attribute.properties?.definitions;
|
|
894
|
+
}
|
|
895
|
+
return void 0;
|
|
896
|
+
}
|
|
862
897
|
function extractValueRefs(value) {
|
|
863
898
|
if (isNullishOrEmptyString(value)) return [];
|
|
864
899
|
if (typeof value === "string") return [{ id: value }];
|
|
@@ -2122,6 +2157,16 @@ var RollupAttributeBuilder = class extends BaseAttributeBuilder {
|
|
|
2122
2157
|
this.attr.targetAttributeOptions = options;
|
|
2123
2158
|
return this;
|
|
2124
2159
|
}
|
|
2160
|
+
/**
|
|
2161
|
+
* Set the currency code a sum/avg over a currency target renders with
|
|
2162
|
+
* (#2644). Mirror of the target attribute's `defaultCurrency` — the stored
|
|
2163
|
+
* value stays a bare number; this only carries the symbol to the screen.
|
|
2164
|
+
* @param code - ISO 4217 code (e.g. "EUR")
|
|
2165
|
+
*/
|
|
2166
|
+
targetCurrency(code) {
|
|
2167
|
+
this.attr.targetCurrencyCode = code;
|
|
2168
|
+
return this;
|
|
2169
|
+
}
|
|
2125
2170
|
/**
|
|
2126
2171
|
* Build the attribute, validating computed-field configuration eagerly so a
|
|
2127
2172
|
* misconfiguration surfaces at schema-definition time (with a fix-it hint)
|
|
@@ -2798,6 +2843,21 @@ var ObjectBuilder = class {
|
|
|
2798
2843
|
this.obj.metadata = { ...this.obj.metadata, order: value };
|
|
2799
2844
|
return this;
|
|
2800
2845
|
}
|
|
2846
|
+
/**
|
|
2847
|
+
* Hide this object from navigation surfaces — the sidebar data section and
|
|
2848
|
+
* the command palette, which already honour `metadata.hidden`. For objects
|
|
2849
|
+
* that own a dedicated surface: `drives` has the Drive page, so listing it
|
|
2850
|
+
* beside business objects would offer the same thing twice under two
|
|
2851
|
+
* different affordances.
|
|
2852
|
+
*
|
|
2853
|
+
* The object stays whole everywhere else: API, search, permissions, agent
|
|
2854
|
+
* tools, filters and record pages all continue to see it. This hides a
|
|
2855
|
+
* navigation entry; it never restricts access.
|
|
2856
|
+
*/
|
|
2857
|
+
hidden() {
|
|
2858
|
+
this.obj.metadata = { ...this.obj.metadata, hidden: true };
|
|
2859
|
+
return this;
|
|
2860
|
+
}
|
|
2801
2861
|
/**
|
|
2802
2862
|
* Set the label expression template for displaying records
|
|
2803
2863
|
* This is REQUIRED for every object.
|
|
@@ -3047,74 +3107,6 @@ var GroupBuilder = class {
|
|
|
3047
3107
|
return this.data;
|
|
3048
3108
|
}
|
|
3049
3109
|
};
|
|
3050
|
-
var RelationGroupBuilder = class {
|
|
3051
|
-
constructor(id, label, attribute) {
|
|
3052
|
-
this.data = { type: "relation" };
|
|
3053
|
-
this.data.id = id;
|
|
3054
|
-
this.data.label = label;
|
|
3055
|
-
this.data.attribute = attribute;
|
|
3056
|
-
}
|
|
3057
|
-
/**
|
|
3058
|
-
* Set group description
|
|
3059
|
-
*/
|
|
3060
|
-
description(value) {
|
|
3061
|
-
this.data.description = value;
|
|
3062
|
-
return this;
|
|
3063
|
-
}
|
|
3064
|
-
/**
|
|
3065
|
-
* Make group collapsible
|
|
3066
|
-
* @param collapsed - Initial collapsed state (default: false)
|
|
3067
|
-
*/
|
|
3068
|
-
collapsible(collapsed = false) {
|
|
3069
|
-
this.data.collapsible = true;
|
|
3070
|
-
this.data.collapsed = collapsed;
|
|
3071
|
-
return this;
|
|
3072
|
-
}
|
|
3073
|
-
/**
|
|
3074
|
-
* Set display order
|
|
3075
|
-
*/
|
|
3076
|
-
order(value) {
|
|
3077
|
-
this.data.order = value;
|
|
3078
|
-
return this;
|
|
3079
|
-
}
|
|
3080
|
-
/**
|
|
3081
|
-
* Set columns to display in the relations table
|
|
3082
|
-
* @example .columns("name", "email", "phone")
|
|
3083
|
-
*/
|
|
3084
|
-
columns(...names) {
|
|
3085
|
-
this.data.columns = names;
|
|
3086
|
-
return this;
|
|
3087
|
-
}
|
|
3088
|
-
/**
|
|
3089
|
-
* Set the group as read-only (no add/remove/edit)
|
|
3090
|
-
*/
|
|
3091
|
-
readOnly(value = true) {
|
|
3092
|
-
this.data.readOnly = value;
|
|
3093
|
-
return this;
|
|
3094
|
-
}
|
|
3095
|
-
/**
|
|
3096
|
-
* Allow creating new related records inline
|
|
3097
|
-
*/
|
|
3098
|
-
allowCreate(value = true) {
|
|
3099
|
-
this.data.allowCreate = value;
|
|
3100
|
-
return this;
|
|
3101
|
-
}
|
|
3102
|
-
/**
|
|
3103
|
-
* Build the relation group definition
|
|
3104
|
-
*/
|
|
3105
|
-
build() {
|
|
3106
|
-
if (!this.data.id) {
|
|
3107
|
-
throw new Error("[RelationGroupBuilder] id is required");
|
|
3108
|
-
}
|
|
3109
|
-
if (!this.data.label) {
|
|
3110
|
-
throw new Error("[RelationGroupBuilder] label is required");
|
|
3111
|
-
}
|
|
3112
|
-
if (!this.data.attribute) {
|
|
3113
|
-
throw new Error("[RelationGroupBuilder] attribute is required");
|
|
3114
|
-
}
|
|
3115
|
-
return this.data;
|
|
3116
|
-
}
|
|
3117
|
-
};
|
|
3118
3110
|
var TableTabConfig = class {
|
|
3119
3111
|
/** @internal */
|
|
3120
3112
|
constructor(view, tabData) {
|
|
@@ -3465,7 +3457,7 @@ var TabBuilder = class {
|
|
|
3465
3457
|
// ─────────────────────────────────────────────────────────────────────────
|
|
3466
3458
|
/**
|
|
3467
3459
|
* Create a form tab with groups
|
|
3468
|
-
* @example .form(group("info", "Info").fields("name", "email")
|
|
3460
|
+
* @example .form(group("info", "Info").fields("name", "email"))
|
|
3469
3461
|
*/
|
|
3470
3462
|
form(...groups) {
|
|
3471
3463
|
if (groups.length === 0) {
|
|
@@ -3476,9 +3468,7 @@ var TabBuilder = class {
|
|
|
3476
3468
|
const tab = {
|
|
3477
3469
|
...this.base,
|
|
3478
3470
|
type: "form",
|
|
3479
|
-
groups: groups.map(
|
|
3480
|
-
(g) => g instanceof GroupBuilder || g instanceof RelationGroupBuilder ? g.build() : g
|
|
3481
|
-
)
|
|
3471
|
+
groups: groups.map((g) => g instanceof GroupBuilder ? g.build() : g)
|
|
3482
3472
|
};
|
|
3483
3473
|
return this.view._addTab(tab);
|
|
3484
3474
|
}
|
|
@@ -4022,9 +4012,6 @@ function listView(name, label) {
|
|
|
4022
4012
|
function group(id, label) {
|
|
4023
4013
|
return new GroupBuilder(id, label);
|
|
4024
4014
|
}
|
|
4025
|
-
function relationGroup(id, label, attribute) {
|
|
4026
|
-
return new RelationGroupBuilder(id, label, attribute);
|
|
4027
|
-
}
|
|
4028
4015
|
|
|
4029
4016
|
// src/feature-flags/flag-builder.ts
|
|
4030
4017
|
function validateFlagName(name) {
|
|
@@ -4361,7 +4348,25 @@ var FlagService = class {
|
|
|
4361
4348
|
* @returns Map of flag names to resolved values
|
|
4362
4349
|
*/
|
|
4363
4350
|
async resolveAll(context = {}) {
|
|
4364
|
-
const
|
|
4351
|
+
const flagNames = this.collectFlagNames();
|
|
4352
|
+
const overrides = this.repository && flagNames.size > 0 ? await this.getAllOverrides(context, [...flagNames]) : emptyOverrides();
|
|
4353
|
+
return this.resolveNames(flagNames, overrides, context);
|
|
4354
|
+
}
|
|
4355
|
+
/**
|
|
4356
|
+
* Resolve every flag from static defaults only, never touching the
|
|
4357
|
+
* overrides repository.
|
|
4358
|
+
*
|
|
4359
|
+
* For callers running outside any tenant context (e.g. tenant-less public
|
|
4360
|
+
* HTTP routes such as the connectors OAuth callback): overrides are
|
|
4361
|
+
* tenant-scoped in storage, so without a tenant there is nothing to fetch —
|
|
4362
|
+
* and asking the repository anyway would require the very context that is
|
|
4363
|
+
* absent.
|
|
4364
|
+
*/
|
|
4365
|
+
resolveAllStatic() {
|
|
4366
|
+
return this.resolveNames(this.collectFlagNames(), emptyOverrides(), {});
|
|
4367
|
+
}
|
|
4368
|
+
/** Flag names known to this service: registry entries plus static defaults. */
|
|
4369
|
+
collectFlagNames() {
|
|
4365
4370
|
const flagNames = /* @__PURE__ */ new Set();
|
|
4366
4371
|
for (const name of this.registry.listNames()) {
|
|
4367
4372
|
flagNames.add(name);
|
|
@@ -4369,10 +4374,12 @@ var FlagService = class {
|
|
|
4369
4374
|
for (const name of this.staticDefaults.keys()) {
|
|
4370
4375
|
flagNames.add(name);
|
|
4371
4376
|
}
|
|
4372
|
-
|
|
4377
|
+
return flagNames;
|
|
4378
|
+
}
|
|
4379
|
+
resolveNames(flagNames, overrides, context) {
|
|
4380
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
4373
4381
|
for (const name of flagNames) {
|
|
4374
|
-
|
|
4375
|
-
resolved.set(name, value);
|
|
4382
|
+
resolved.set(name, this.resolveValue(name, overrides, context));
|
|
4376
4383
|
}
|
|
4377
4384
|
return resolved;
|
|
4378
4385
|
}
|
|
@@ -4760,6 +4767,12 @@ var MEMORY_VIEW = detailView("memory-detail", "Memory").for("memory").default().
|
|
|
4760
4767
|
}).tab("content", "Content").richtext("content").titleAttribute("name").build();
|
|
4761
4768
|
var MEMORY_LIST_VIEW = listView("memory-list", "Memories").for("memory").default().tab("workspace", "Memories").default().icon("table").visibility("workspace").table().columns("name", "kind", "description", "createdAt").sort("name", "asc").tab("mine", "My memories").icon("lock").visibility("private").table().columns("name", "kind", "description", "createdAt").sort("name", "asc").build();
|
|
4762
4769
|
|
|
4770
|
+
// src/native/drive.object.ts
|
|
4771
|
+
var DRIVE_OBJECT_NAME = "drives";
|
|
4772
|
+
var DRIVE_OBJECT = object({ name: DRIVE_OBJECT_NAME, label: "Drive" }).sealed().icon("folder").hidden().pluralLabel("Drives").labelExpression("{{ name }}").embeddingExpression("{{ name }}\n{{ description }}").attribute(text({ name: "name", label: "Name" }).required()).attribute(text({ name: "description", label: "Description" }).multiline()).build();
|
|
4773
|
+
var DRIVE_VIEW = detailView("drive-detail", "Drive").for(DRIVE_OBJECT_NAME).default().sidePanel({ attributes: ["description"] }).tab("documents", "Documents").documents().build();
|
|
4774
|
+
var DRIVE_LIST_VIEW = listView("drive-list", "Drives").for(DRIVE_OBJECT_NAME).default().tab("workspace", "Shared").default().icon("users").visibility("workspace").table().columns("name", "description", "updatedAt").sort("name", "asc").tab("mine", "My drives").icon("lock").visibility("private").table().columns("name", "description", "updatedAt").sort("name", "asc").build();
|
|
4775
|
+
|
|
4763
4776
|
// src/views/registry.ts
|
|
4764
4777
|
function cloneViewDefinition(view) {
|
|
4765
4778
|
return structuredClone(view);
|
|
@@ -5306,6 +5319,9 @@ var LIVE_EVENT_TYPE_REGISTRY = {
|
|
|
5306
5319
|
"notification.count.patch": true,
|
|
5307
5320
|
"conversation.renamed": true,
|
|
5308
5321
|
"browser.preview.updated": true,
|
|
5322
|
+
"reflex.state.changed": true,
|
|
5323
|
+
"reflex.run.completed": true,
|
|
5324
|
+
"reflex.authoring.progress": true,
|
|
5309
5325
|
"channel.revoked": true
|
|
5310
5326
|
};
|
|
5311
5327
|
var LIVE_EVENT_TYPES = Object.keys(LIVE_EVENT_TYPE_REGISTRY);
|
|
@@ -5409,6 +5425,12 @@ function isLiveEventPayloadForType(type, payload) {
|
|
|
5409
5425
|
return isConversationRenamedPayload(payload);
|
|
5410
5426
|
case "browser.preview.updated":
|
|
5411
5427
|
return isBrowserPreviewUpdatedPayload(payload);
|
|
5428
|
+
case "reflex.state.changed":
|
|
5429
|
+
return isReflexStateChangedPayload(payload);
|
|
5430
|
+
case "reflex.run.completed":
|
|
5431
|
+
return isReflexRunCompletedPayload(payload);
|
|
5432
|
+
case "reflex.authoring.progress":
|
|
5433
|
+
return isReflexAuthoringProgressPayload(payload);
|
|
5412
5434
|
case "channel.revoked":
|
|
5413
5435
|
return isChannelRevokedPayload(payload);
|
|
5414
5436
|
default:
|
|
@@ -5483,7 +5505,9 @@ function isRecordFieldPatch(value) {
|
|
|
5483
5505
|
return isRecord2(value) && hasString(value, "fieldKey") && Object.hasOwn(value, "value") && hasVersion(value, "version");
|
|
5484
5506
|
}
|
|
5485
5507
|
function isRecordPatchPayload(payload) {
|
|
5486
|
-
return payload.type === "record.patch" && hasString(payload, "objectId") && hasString(payload, "recordId") && hasVersion(payload, "recordVersion") && hasOptional(payload, "label", isString) && hasOptional(payload, "metadata", isRecord2) &&
|
|
5508
|
+
return payload.type === "record.patch" && hasString(payload, "objectId") && hasString(payload, "recordId") && hasVersion(payload, "recordVersion") && hasOptional(payload, "label", isString) && hasOptional(payload, "metadata", isRecord2) && // Strictly `true`: the applier evicts an entity on this bit, so truthy
|
|
5509
|
+
// junk on the wire must not pass as the presence flag (#2637).
|
|
5510
|
+
hasOptional(payload, "fieldsWithheld", (value) => value === true) && Array.isArray(payload.fieldPatches) && payload.fieldPatches.every(isRecordFieldPatch) && hasString(payload, "updatedAt");
|
|
5487
5511
|
}
|
|
5488
5512
|
function isRecordDeletedPayload(payload) {
|
|
5489
5513
|
return payload.type === "record.deleted" && hasString(payload, "objectId") && hasString(payload, "recordId") && hasVersion(payload, "recordVersion") && hasString(payload, "deletedAt");
|
|
@@ -5539,6 +5563,27 @@ function isBrowserPreviewUpdatedPayload(payload) {
|
|
|
5539
5563
|
const preview = payload.preview;
|
|
5540
5564
|
return payload.type === "browser.preview.updated" && hasOnlyKeys(payload, BROWSER_PREVIEW_UPDATED_PAYLOAD_KEYS) && isRecord2(preview) && hasOnlyKeys(preview, BROWSER_PREVIEW_DESCRIPTOR_KEYS) && hasNonEmptyString(preview, "previewId") && hasNonEmptyString(preview, "rootSessionId") && hasNonEmptyString(preview, "agentSessionId") && hasNonEmptyString(preview, "browserSession") && isOneOf(preview.status, BROWSER_PREVIEW_STATUSES) && hasVersion(preview, "sequence") && hasIsoDateString(preview, "updatedAt") && preview.previewId === `browser:${preview.agentSessionId}:${preview.browserSession}`;
|
|
5541
5565
|
}
|
|
5566
|
+
var REFLEX_STATES = ["armed", "disarmed"];
|
|
5567
|
+
var REFLEX_AUTHORING_STATUSES = [
|
|
5568
|
+
"authoring",
|
|
5569
|
+
"compiling",
|
|
5570
|
+
"replaying",
|
|
5571
|
+
"promoted",
|
|
5572
|
+
"failed"
|
|
5573
|
+
];
|
|
5574
|
+
var REFLEX_SERVED_MODES = [
|
|
5575
|
+
"promoted",
|
|
5576
|
+
"lkg"
|
|
5577
|
+
];
|
|
5578
|
+
function isReflexStateChangedPayload(payload) {
|
|
5579
|
+
return payload.type === "reflex.state.changed" && hasNonEmptyString(payload, "reflexId") && isOneOf(payload.state, REFLEX_STATES) && hasIsoDateString(payload, "updatedAt");
|
|
5580
|
+
}
|
|
5581
|
+
function isReflexRunCompletedPayload(payload) {
|
|
5582
|
+
return payload.type === "reflex.run.completed" && hasNonEmptyString(payload, "reflexId") && hasNonEmptyString(payload, "runId") && isOneOf(payload.served, REFLEX_SERVED_MODES) && hasVersion(payload, "version") && hasVersion(payload, "wallMs") && hasIsoDateString(payload, "completedAt");
|
|
5583
|
+
}
|
|
5584
|
+
function isReflexAuthoringProgressPayload(payload) {
|
|
5585
|
+
return payload.type === "reflex.authoring.progress" && hasNonEmptyString(payload, "reflexId") && isOneOf(payload.status, REFLEX_AUTHORING_STATUSES) && hasIsoDateString(payload, "updatedAt");
|
|
5586
|
+
}
|
|
5542
5587
|
function isChannelRevokedPayload(payload) {
|
|
5543
5588
|
return payload.type === "channel.revoked" && hasString(payload, "channel") && isOneOf(payload.reason, CHANNEL_REVOKED_REASONS);
|
|
5544
5589
|
}
|
|
@@ -6328,7 +6373,11 @@ function evaluateCallNode(functionName, args, input) {
|
|
|
6328
6373
|
assertComputedFunctionName(functionName);
|
|
6329
6374
|
validateArity(functionName, args.length);
|
|
6330
6375
|
if (functionName === "if") {
|
|
6331
|
-
|
|
6376
|
+
const condition = evaluateAst(args[0], input);
|
|
6377
|
+
if (condition === null) {
|
|
6378
|
+
return null;
|
|
6379
|
+
}
|
|
6380
|
+
return condition ? evaluateAst(args[1], input) : evaluateAst(args[2], input);
|
|
6332
6381
|
}
|
|
6333
6382
|
return evaluateCall(
|
|
6334
6383
|
functionName,
|
|
@@ -6374,8 +6423,10 @@ function evaluateBinary(operator, left, right) {
|
|
|
6374
6423
|
return compareWith(left, right, (result) => result <= 0);
|
|
6375
6424
|
case "==":
|
|
6376
6425
|
return equalScalar(left, right);
|
|
6377
|
-
case "!=":
|
|
6378
|
-
|
|
6426
|
+
case "!=": {
|
|
6427
|
+
const equal = equalScalar(left, right);
|
|
6428
|
+
return equal === null ? null : !equal;
|
|
6429
|
+
}
|
|
6379
6430
|
default:
|
|
6380
6431
|
return unreachable(operator);
|
|
6381
6432
|
}
|
|
@@ -6391,6 +6442,9 @@ function compareWith(left, right, predicate) {
|
|
|
6391
6442
|
return result === null ? null : predicate(result);
|
|
6392
6443
|
}
|
|
6393
6444
|
function compare(left, right) {
|
|
6445
|
+
if (!areCommensurable([left, right])) {
|
|
6446
|
+
return null;
|
|
6447
|
+
}
|
|
6394
6448
|
const leftNumber = toFiniteNumber(left);
|
|
6395
6449
|
const rightNumber = toFiniteNumber(right);
|
|
6396
6450
|
if (leftNumber !== null && rightNumber !== null) {
|
|
@@ -6407,6 +6461,9 @@ function equalScalar(left, right) {
|
|
|
6407
6461
|
if (left === null || left === void 0 || right === null || right === void 0) {
|
|
6408
6462
|
return false;
|
|
6409
6463
|
}
|
|
6464
|
+
if (!areCommensurable([left, right])) {
|
|
6465
|
+
return null;
|
|
6466
|
+
}
|
|
6410
6467
|
return compare(left, right) === 0;
|
|
6411
6468
|
}
|
|
6412
6469
|
function assertComputedFunctionName(name) {
|
|
@@ -6427,8 +6484,14 @@ function evaluateCall(functionName, args) {
|
|
|
6427
6484
|
case "concat":
|
|
6428
6485
|
return args.filter((arg) => arg !== null && arg !== void 0).map(String).join("");
|
|
6429
6486
|
case "sum":
|
|
6487
|
+
if (!areCommensurable(args)) {
|
|
6488
|
+
return null;
|
|
6489
|
+
}
|
|
6430
6490
|
return numericValues(args).reduce((total, value) => total + value, 0);
|
|
6431
6491
|
case "avg": {
|
|
6492
|
+
if (!areCommensurable(args)) {
|
|
6493
|
+
return null;
|
|
6494
|
+
}
|
|
6432
6495
|
const values = numericValues(args);
|
|
6433
6496
|
return values.length > 0 ? values.reduce((total, value) => total + value, 0) / values.length : null;
|
|
6434
6497
|
}
|
|
@@ -6466,7 +6529,22 @@ function unreachable(value) {
|
|
|
6466
6529
|
function numericValues(values) {
|
|
6467
6530
|
return flatten(values).map(toFiniteNumber).filter((value) => value !== null);
|
|
6468
6531
|
}
|
|
6532
|
+
function areCommensurable(values) {
|
|
6533
|
+
const codes = /* @__PURE__ */ new Set();
|
|
6534
|
+
for (const value of flatten(values)) {
|
|
6535
|
+
if (isCurrencyValue(value)) {
|
|
6536
|
+
codes.add(currencyCode(value));
|
|
6537
|
+
}
|
|
6538
|
+
}
|
|
6539
|
+
return codes.size <= 1;
|
|
6540
|
+
}
|
|
6541
|
+
function currencyCode(value) {
|
|
6542
|
+
return value.code.toUpperCase();
|
|
6543
|
+
}
|
|
6469
6544
|
function numericBinary(left, right, operation) {
|
|
6545
|
+
if (!areCommensurable([left, right])) {
|
|
6546
|
+
return null;
|
|
6547
|
+
}
|
|
6470
6548
|
const leftNumber = toFiniteNumber(left);
|
|
6471
6549
|
const rightNumber = toFiniteNumber(right);
|
|
6472
6550
|
if (leftNumber === null || rightNumber === null) {
|
|
@@ -6476,6 +6554,9 @@ function numericBinary(left, right, operation) {
|
|
|
6476
6554
|
return Number.isFinite(result) ? result : null;
|
|
6477
6555
|
}
|
|
6478
6556
|
function minMax(values, mode) {
|
|
6557
|
+
if (!areCommensurable(values)) {
|
|
6558
|
+
return null;
|
|
6559
|
+
}
|
|
6479
6560
|
const numbers = numericValues(values);
|
|
6480
6561
|
if (numbers.length > 0) {
|
|
6481
6562
|
return mode === "min" ? Math.min(...numbers) : Math.max(...numbers);
|
|
@@ -6554,6 +6635,9 @@ function toDate(value) {
|
|
|
6554
6635
|
return Number.isNaN(date2.getTime()) ? null : date2;
|
|
6555
6636
|
}
|
|
6556
6637
|
function uniqueKey(value) {
|
|
6638
|
+
if (isCurrencyValue(value)) {
|
|
6639
|
+
return `currency:${currencyCode(value)}:${value.value}`;
|
|
6640
|
+
}
|
|
6557
6641
|
const numberValue = toFiniteNumber(value);
|
|
6558
6642
|
if (numberValue !== null) {
|
|
6559
6643
|
return `number:${numberValue}`;
|
|
@@ -7506,4 +7590,995 @@ var persistedSchemaPlanSchema = z.preprocess(
|
|
|
7506
7590
|
structuralPersistedSchemaPlanSchema
|
|
7507
7591
|
);
|
|
7508
7592
|
|
|
7509
|
-
|
|
7593
|
+
// src/architect/define-operation.ts
|
|
7594
|
+
function defineOperation(def) {
|
|
7595
|
+
return def;
|
|
7596
|
+
}
|
|
7597
|
+
var operationBase = { id: z.string().min(1) };
|
|
7598
|
+
var viewOperationBase = { ...operationBase, viewId: z.string().min(1) };
|
|
7599
|
+
function mapView(state, viewId, fn) {
|
|
7600
|
+
if (!state.views.some((v) => v.id === viewId)) {
|
|
7601
|
+
throw new ValidationError(`View "${viewId}" is not in the draftable state`, []);
|
|
7602
|
+
}
|
|
7603
|
+
return { ...state, views: state.views.map((v) => v.id === viewId ? fn(v) : v) };
|
|
7604
|
+
}
|
|
7605
|
+
function moveWithin(items, from, toIndex) {
|
|
7606
|
+
const next = [...items];
|
|
7607
|
+
const [item] = next.splice(from, 1);
|
|
7608
|
+
next.splice(toIndex, 0, item);
|
|
7609
|
+
return next;
|
|
7610
|
+
}
|
|
7611
|
+
function reorderById(items, order, what) {
|
|
7612
|
+
if (order.length !== items.length) {
|
|
7613
|
+
throw new ValidationError(
|
|
7614
|
+
`${what} order lists ${order.length} ids for ${items.length} items`,
|
|
7615
|
+
[]
|
|
7616
|
+
);
|
|
7617
|
+
}
|
|
7618
|
+
return order.map((id) => {
|
|
7619
|
+
const found = items.find((item) => item.id === id);
|
|
7620
|
+
if (!found) throw new ValidationError(`${what} "${id}" is not in this collection`, []);
|
|
7621
|
+
return found;
|
|
7622
|
+
});
|
|
7623
|
+
}
|
|
7624
|
+
|
|
7625
|
+
// src/architect/operations/detail-view.ts
|
|
7626
|
+
function mapFormTab(view, tabId, fn) {
|
|
7627
|
+
const found = view.tabs.find((t) => t.id === tabId);
|
|
7628
|
+
if (!found) throw new ValidationError(`Tab "${tabId}" is not in view "${view.id}"`, []);
|
|
7629
|
+
if (found.type !== "form") {
|
|
7630
|
+
throw new ValidationError(`Tab "${tabId}" is not a form tab`, []);
|
|
7631
|
+
}
|
|
7632
|
+
return { ...view, tabs: view.tabs.map((t) => t.id === tabId ? fn(found) : t) };
|
|
7633
|
+
}
|
|
7634
|
+
function requireGroup(tab, groupId) {
|
|
7635
|
+
const found = tab.groups.find((g) => g.id === groupId);
|
|
7636
|
+
if (!found) throw new ValidationError(`Group "${groupId}" is not in tab "${tab.id}"`, []);
|
|
7637
|
+
return found;
|
|
7638
|
+
}
|
|
7639
|
+
function locateField(tab, fieldId) {
|
|
7640
|
+
for (const group2 of tab.groups) {
|
|
7641
|
+
const field = group2.fields.find((f) => f.id === fieldId);
|
|
7642
|
+
if (field) return { group: group2, field };
|
|
7643
|
+
}
|
|
7644
|
+
throw new ValidationError(`Field slot "${fieldId}" is not in tab "${tab.id}"`, []);
|
|
7645
|
+
}
|
|
7646
|
+
var tabPayload = z.custom(
|
|
7647
|
+
(value) => typeof value === "object" && value !== null && "id" in value && "type" in value,
|
|
7648
|
+
{ message: "A tab must be an object carrying id and type" }
|
|
7649
|
+
);
|
|
7650
|
+
var groupPayload = z.custom(
|
|
7651
|
+
(value) => typeof value === "object" && value !== null && "id" in value && "fields" in value,
|
|
7652
|
+
{ message: "A group must be an object carrying id and fields" }
|
|
7653
|
+
);
|
|
7654
|
+
var fieldPayload = z.custom(
|
|
7655
|
+
(value) => typeof value === "object" && value !== null && "id" in value,
|
|
7656
|
+
{ message: "A field slot must be an object carrying an id" }
|
|
7657
|
+
);
|
|
7658
|
+
var addTabSchema = z.object({
|
|
7659
|
+
...viewOperationBase,
|
|
7660
|
+
type: z.literal("add_tab"),
|
|
7661
|
+
tab: tabPayload
|
|
7662
|
+
});
|
|
7663
|
+
var addTab = defineOperation({
|
|
7664
|
+
type: "add_tab",
|
|
7665
|
+
schema: addTabSchema,
|
|
7666
|
+
apply: (state, op) => mapView(state, op.viewId, (view) => {
|
|
7667
|
+
if (view.tabs.some((t) => t.id === op.tab.id)) {
|
|
7668
|
+
throw new ValidationError(`Tab "${op.tab.id}" already exists in view "${op.viewId}"`, []);
|
|
7669
|
+
}
|
|
7670
|
+
return { ...view, tabs: [...view.tabs, op.tab] };
|
|
7671
|
+
}),
|
|
7672
|
+
focus: (op) => ({ viewId: op.viewId, tabId: op.tab.id }),
|
|
7673
|
+
describe: (op) => `Ajoute l'onglet \xAB ${op.tab.label} \xBB`
|
|
7674
|
+
});
|
|
7675
|
+
var removeTabSchema = z.object({
|
|
7676
|
+
...viewOperationBase,
|
|
7677
|
+
type: z.literal("remove_tab"),
|
|
7678
|
+
tabId: z.string().min(1)
|
|
7679
|
+
});
|
|
7680
|
+
var removeTab = defineOperation({
|
|
7681
|
+
type: "remove_tab",
|
|
7682
|
+
schema: removeTabSchema,
|
|
7683
|
+
apply: (state, op) => mapView(state, op.viewId, (view) => {
|
|
7684
|
+
if (!view.tabs.some((t) => t.id === op.tabId)) {
|
|
7685
|
+
throw new ValidationError(`Tab "${op.tabId}" is not in view "${op.viewId}"`, []);
|
|
7686
|
+
}
|
|
7687
|
+
return { ...view, tabs: view.tabs.filter((t) => t.id !== op.tabId) };
|
|
7688
|
+
}),
|
|
7689
|
+
focus: (op) => ({ viewId: op.viewId }),
|
|
7690
|
+
describe: (op) => `Supprime l'onglet ${op.tabId}`
|
|
7691
|
+
});
|
|
7692
|
+
var updateTabSchema = z.object({
|
|
7693
|
+
...viewOperationBase,
|
|
7694
|
+
type: z.literal("update_tab"),
|
|
7695
|
+
tabId: z.string().min(1),
|
|
7696
|
+
changes: z.object({
|
|
7697
|
+
label: z.string().min(1).optional(),
|
|
7698
|
+
icon: z.custom((v) => typeof v === "string" && v.length > 0).optional(),
|
|
7699
|
+
order: z.number().int().optional()
|
|
7700
|
+
}).refine((c) => Object.keys(c).length > 0, "update_tab needs at least one change")
|
|
7701
|
+
});
|
|
7702
|
+
var updateTab = defineOperation({
|
|
7703
|
+
type: "update_tab",
|
|
7704
|
+
schema: updateTabSchema,
|
|
7705
|
+
apply: (state, op) => mapView(state, op.viewId, (view) => {
|
|
7706
|
+
if (!view.tabs.some((t) => t.id === op.tabId)) {
|
|
7707
|
+
throw new ValidationError(`Tab "${op.tabId}" is not in view "${op.viewId}"`, []);
|
|
7708
|
+
}
|
|
7709
|
+
return {
|
|
7710
|
+
...view,
|
|
7711
|
+
tabs: view.tabs.map((t) => t.id === op.tabId ? { ...t, ...op.changes } : t)
|
|
7712
|
+
};
|
|
7713
|
+
}),
|
|
7714
|
+
focus: (op) => ({ viewId: op.viewId, tabId: op.tabId }),
|
|
7715
|
+
describe: (op) => op.changes.label ? `Renomme l'onglet en \xAB ${op.changes.label} \xBB` : `Modifie l'onglet ${op.tabId}`
|
|
7716
|
+
});
|
|
7717
|
+
var reorderTabsSchema = z.object({
|
|
7718
|
+
...viewOperationBase,
|
|
7719
|
+
type: z.literal("reorder_tabs"),
|
|
7720
|
+
tabOrder: z.array(z.string().min(1))
|
|
7721
|
+
});
|
|
7722
|
+
var reorderTabs = defineOperation({
|
|
7723
|
+
type: "reorder_tabs",
|
|
7724
|
+
schema: reorderTabsSchema,
|
|
7725
|
+
apply: (state, op) => mapView(state, op.viewId, (view) => ({
|
|
7726
|
+
...view,
|
|
7727
|
+
tabs: reorderById(view.tabs, op.tabOrder, "Tab")
|
|
7728
|
+
})),
|
|
7729
|
+
focus: (op) => ({ viewId: op.viewId }),
|
|
7730
|
+
describe: () => "R\xE9ordonne les onglets"
|
|
7731
|
+
});
|
|
7732
|
+
var addGroupSchema = z.object({
|
|
7733
|
+
...viewOperationBase,
|
|
7734
|
+
type: z.literal("add_group"),
|
|
7735
|
+
tabId: z.string().min(1),
|
|
7736
|
+
group: groupPayload
|
|
7737
|
+
});
|
|
7738
|
+
var addGroup = defineOperation({
|
|
7739
|
+
type: "add_group",
|
|
7740
|
+
schema: addGroupSchema,
|
|
7741
|
+
apply: (state, op) => mapView(
|
|
7742
|
+
state,
|
|
7743
|
+
op.viewId,
|
|
7744
|
+
(view) => mapFormTab(view, op.tabId, (tab) => {
|
|
7745
|
+
if (tab.groups.some((g) => g.id === op.group.id)) {
|
|
7746
|
+
throw new ValidationError(
|
|
7747
|
+
`Group "${op.group.id}" already exists in tab "${op.tabId}"`,
|
|
7748
|
+
[]
|
|
7749
|
+
);
|
|
7750
|
+
}
|
|
7751
|
+
return { ...tab, groups: [...tab.groups, op.group] };
|
|
7752
|
+
})
|
|
7753
|
+
),
|
|
7754
|
+
focus: (op) => ({ viewId: op.viewId, tabId: op.tabId, groupId: op.group.id }),
|
|
7755
|
+
describe: (op) => `Ajoute le groupe \xAB ${op.group.label} \xBB`
|
|
7756
|
+
});
|
|
7757
|
+
var removeGroupSchema = z.object({
|
|
7758
|
+
...viewOperationBase,
|
|
7759
|
+
type: z.literal("remove_group"),
|
|
7760
|
+
tabId: z.string().min(1),
|
|
7761
|
+
groupId: z.string().min(1)
|
|
7762
|
+
});
|
|
7763
|
+
var removeGroup = defineOperation({
|
|
7764
|
+
type: "remove_group",
|
|
7765
|
+
schema: removeGroupSchema,
|
|
7766
|
+
apply: (state, op) => mapView(
|
|
7767
|
+
state,
|
|
7768
|
+
op.viewId,
|
|
7769
|
+
(view) => mapFormTab(view, op.tabId, (tab) => {
|
|
7770
|
+
requireGroup(tab, op.groupId);
|
|
7771
|
+
return { ...tab, groups: tab.groups.filter((g) => g.id !== op.groupId) };
|
|
7772
|
+
})
|
|
7773
|
+
),
|
|
7774
|
+
focus: (op) => ({ viewId: op.viewId, tabId: op.tabId }),
|
|
7775
|
+
describe: (op) => `Supprime le groupe ${op.groupId}`
|
|
7776
|
+
});
|
|
7777
|
+
var updateGroupSchema = z.object({
|
|
7778
|
+
...viewOperationBase,
|
|
7779
|
+
type: z.literal("update_group"),
|
|
7780
|
+
tabId: z.string().min(1),
|
|
7781
|
+
groupId: z.string().min(1),
|
|
7782
|
+
changes: z.object({
|
|
7783
|
+
label: z.string().min(1).optional(),
|
|
7784
|
+
description: z.string().optional(),
|
|
7785
|
+
collapsible: z.boolean().optional(),
|
|
7786
|
+
collapsed: z.boolean().optional(),
|
|
7787
|
+
order: z.number().int().optional()
|
|
7788
|
+
}).refine((c) => Object.keys(c).length > 0, "update_group needs at least one change")
|
|
7789
|
+
});
|
|
7790
|
+
var updateGroup = defineOperation({
|
|
7791
|
+
type: "update_group",
|
|
7792
|
+
schema: updateGroupSchema,
|
|
7793
|
+
apply: (state, op) => mapView(
|
|
7794
|
+
state,
|
|
7795
|
+
op.viewId,
|
|
7796
|
+
(view) => mapFormTab(view, op.tabId, (tab) => {
|
|
7797
|
+
requireGroup(tab, op.groupId);
|
|
7798
|
+
return {
|
|
7799
|
+
...tab,
|
|
7800
|
+
groups: tab.groups.map((g) => g.id === op.groupId ? { ...g, ...op.changes } : g)
|
|
7801
|
+
};
|
|
7802
|
+
})
|
|
7803
|
+
),
|
|
7804
|
+
focus: (op) => ({ viewId: op.viewId, tabId: op.tabId, groupId: op.groupId }),
|
|
7805
|
+
describe: (op) => op.changes.label ? `Renomme le groupe en \xAB ${op.changes.label} \xBB` : "Modifie le groupe"
|
|
7806
|
+
});
|
|
7807
|
+
var reorderGroupsSchema = z.object({
|
|
7808
|
+
...viewOperationBase,
|
|
7809
|
+
type: z.literal("reorder_groups"),
|
|
7810
|
+
tabId: z.string().min(1),
|
|
7811
|
+
groupOrder: z.array(z.string().min(1))
|
|
7812
|
+
});
|
|
7813
|
+
var reorderGroups = defineOperation({
|
|
7814
|
+
type: "reorder_groups",
|
|
7815
|
+
schema: reorderGroupsSchema,
|
|
7816
|
+
apply: (state, op) => mapView(
|
|
7817
|
+
state,
|
|
7818
|
+
op.viewId,
|
|
7819
|
+
(view) => mapFormTab(view, op.tabId, (tab) => ({
|
|
7820
|
+
...tab,
|
|
7821
|
+
groups: reorderById(tab.groups, op.groupOrder, "Group")
|
|
7822
|
+
}))
|
|
7823
|
+
),
|
|
7824
|
+
focus: (op) => ({ viewId: op.viewId, tabId: op.tabId }),
|
|
7825
|
+
describe: () => "R\xE9ordonne les groupes"
|
|
7826
|
+
});
|
|
7827
|
+
var addFieldSchema = z.object({
|
|
7828
|
+
...viewOperationBase,
|
|
7829
|
+
type: z.literal("add_field"),
|
|
7830
|
+
tabId: z.string().min(1),
|
|
7831
|
+
groupId: z.string().min(1),
|
|
7832
|
+
field: fieldPayload,
|
|
7833
|
+
index: z.number().int().min(0).optional()
|
|
7834
|
+
});
|
|
7835
|
+
var addField = defineOperation({
|
|
7836
|
+
type: "add_field",
|
|
7837
|
+
schema: addFieldSchema,
|
|
7838
|
+
apply: (state, op) => mapView(
|
|
7839
|
+
state,
|
|
7840
|
+
op.viewId,
|
|
7841
|
+
(view) => mapFormTab(view, op.tabId, (tab) => {
|
|
7842
|
+
requireGroup(tab, op.groupId);
|
|
7843
|
+
if (tab.groups.some((g) => g.fields.some((f) => f.id === op.field.id))) {
|
|
7844
|
+
throw new ValidationError(
|
|
7845
|
+
`Field slot "${op.field.id}" already exists in tab "${op.tabId}"`,
|
|
7846
|
+
[]
|
|
7847
|
+
);
|
|
7848
|
+
}
|
|
7849
|
+
return {
|
|
7850
|
+
...tab,
|
|
7851
|
+
groups: tab.groups.map((group2) => {
|
|
7852
|
+
if (group2.id !== op.groupId) return group2;
|
|
7853
|
+
const at = op.index ?? group2.fields.length;
|
|
7854
|
+
return {
|
|
7855
|
+
...group2,
|
|
7856
|
+
fields: [...group2.fields.slice(0, at), op.field, ...group2.fields.slice(at)]
|
|
7857
|
+
};
|
|
7858
|
+
})
|
|
7859
|
+
};
|
|
7860
|
+
})
|
|
7861
|
+
),
|
|
7862
|
+
focus: (op) => ({
|
|
7863
|
+
viewId: op.viewId,
|
|
7864
|
+
tabId: op.tabId,
|
|
7865
|
+
groupId: op.groupId,
|
|
7866
|
+
fieldId: op.field.id
|
|
7867
|
+
}),
|
|
7868
|
+
describe: (op) => `Ajoute le champ ${op.field.attribute ?? op.field.id}`
|
|
7869
|
+
});
|
|
7870
|
+
var removeFieldSchema = z.object({
|
|
7871
|
+
...viewOperationBase,
|
|
7872
|
+
type: z.literal("remove_field"),
|
|
7873
|
+
tabId: z.string().min(1),
|
|
7874
|
+
fieldId: z.string().min(1)
|
|
7875
|
+
});
|
|
7876
|
+
var removeField = defineOperation({
|
|
7877
|
+
type: "remove_field",
|
|
7878
|
+
schema: removeFieldSchema,
|
|
7879
|
+
apply: (state, op) => mapView(
|
|
7880
|
+
state,
|
|
7881
|
+
op.viewId,
|
|
7882
|
+
(view) => mapFormTab(view, op.tabId, (tab) => {
|
|
7883
|
+
const { group: group2 } = locateField(tab, op.fieldId);
|
|
7884
|
+
return {
|
|
7885
|
+
...tab,
|
|
7886
|
+
groups: tab.groups.map(
|
|
7887
|
+
(g) => g.id === group2.id ? { ...g, fields: g.fields.filter((f) => f.id !== op.fieldId) } : g
|
|
7888
|
+
)
|
|
7889
|
+
};
|
|
7890
|
+
})
|
|
7891
|
+
),
|
|
7892
|
+
focus: (op) => ({ viewId: op.viewId, tabId: op.tabId }),
|
|
7893
|
+
describe: (op) => `Retire le champ ${op.fieldId}`
|
|
7894
|
+
});
|
|
7895
|
+
var moveFieldSchema = z.object({
|
|
7896
|
+
...viewOperationBase,
|
|
7897
|
+
type: z.literal("move_field"),
|
|
7898
|
+
tabId: z.string().min(1),
|
|
7899
|
+
fieldId: z.string().min(1),
|
|
7900
|
+
toGroupId: z.string().min(1),
|
|
7901
|
+
toIndex: z.number().int().min(0)
|
|
7902
|
+
});
|
|
7903
|
+
var moveField = defineOperation({
|
|
7904
|
+
type: "move_field",
|
|
7905
|
+
schema: moveFieldSchema,
|
|
7906
|
+
apply: (state, op) => mapView(
|
|
7907
|
+
state,
|
|
7908
|
+
op.viewId,
|
|
7909
|
+
(view) => mapFormTab(view, op.tabId, (tab) => {
|
|
7910
|
+
const { group: source, field } = locateField(tab, op.fieldId);
|
|
7911
|
+
const target = requireGroup(tab, op.toGroupId);
|
|
7912
|
+
if (source.id === target.id) {
|
|
7913
|
+
const from = source.fields.findIndex((f) => f.id === op.fieldId);
|
|
7914
|
+
return {
|
|
7915
|
+
...tab,
|
|
7916
|
+
groups: tab.groups.map(
|
|
7917
|
+
(g) => g.id === source.id ? { ...g, fields: moveWithin(g.fields, from, op.toIndex) } : g
|
|
7918
|
+
)
|
|
7919
|
+
};
|
|
7920
|
+
}
|
|
7921
|
+
return {
|
|
7922
|
+
...tab,
|
|
7923
|
+
groups: tab.groups.map((group2) => {
|
|
7924
|
+
if (group2.id === source.id) {
|
|
7925
|
+
return { ...group2, fields: group2.fields.filter((f) => f.id !== op.fieldId) };
|
|
7926
|
+
}
|
|
7927
|
+
if (group2.id === target.id) {
|
|
7928
|
+
return {
|
|
7929
|
+
...group2,
|
|
7930
|
+
fields: [
|
|
7931
|
+
...group2.fields.slice(0, op.toIndex),
|
|
7932
|
+
field,
|
|
7933
|
+
...group2.fields.slice(op.toIndex)
|
|
7934
|
+
]
|
|
7935
|
+
};
|
|
7936
|
+
}
|
|
7937
|
+
return group2;
|
|
7938
|
+
})
|
|
7939
|
+
};
|
|
7940
|
+
})
|
|
7941
|
+
),
|
|
7942
|
+
focus: (op) => ({
|
|
7943
|
+
viewId: op.viewId,
|
|
7944
|
+
tabId: op.tabId,
|
|
7945
|
+
groupId: op.toGroupId,
|
|
7946
|
+
fieldId: op.fieldId
|
|
7947
|
+
}),
|
|
7948
|
+
describe: (op) => `D\xE9place le champ ${op.fieldId} vers le groupe ${op.toGroupId}`
|
|
7949
|
+
});
|
|
7950
|
+
var updateFieldSchema = z.object({
|
|
7951
|
+
...viewOperationBase,
|
|
7952
|
+
type: z.literal("update_field"),
|
|
7953
|
+
tabId: z.string().min(1),
|
|
7954
|
+
fieldId: z.string().min(1),
|
|
7955
|
+
changes: z.object({
|
|
7956
|
+
label: z.string().optional(),
|
|
7957
|
+
readOnly: z.boolean().optional(),
|
|
7958
|
+
span: z.number().int().min(1).max(12).optional()
|
|
7959
|
+
}).refine((c) => Object.keys(c).length > 0, "update_field needs at least one change")
|
|
7960
|
+
});
|
|
7961
|
+
var updateField = defineOperation({
|
|
7962
|
+
type: "update_field",
|
|
7963
|
+
schema: updateFieldSchema,
|
|
7964
|
+
apply: (state, op) => mapView(
|
|
7965
|
+
state,
|
|
7966
|
+
op.viewId,
|
|
7967
|
+
(view) => mapFormTab(view, op.tabId, (tab) => {
|
|
7968
|
+
locateField(tab, op.fieldId);
|
|
7969
|
+
return {
|
|
7970
|
+
...tab,
|
|
7971
|
+
groups: tab.groups.map((group2) => ({
|
|
7972
|
+
...group2,
|
|
7973
|
+
fields: group2.fields.map(
|
|
7974
|
+
(f) => f.id === op.fieldId ? { ...f, ...op.changes } : f
|
|
7975
|
+
)
|
|
7976
|
+
}))
|
|
7977
|
+
};
|
|
7978
|
+
})
|
|
7979
|
+
),
|
|
7980
|
+
focus: (op) => ({ viewId: op.viewId, tabId: op.tabId, fieldId: op.fieldId }),
|
|
7981
|
+
describe: (op) => `Modifie le champ ${op.fieldId}`
|
|
7982
|
+
});
|
|
7983
|
+
var updateTableTabSchema = z.object({
|
|
7984
|
+
...viewOperationBase,
|
|
7985
|
+
type: z.literal("update_table_tab"),
|
|
7986
|
+
tabId: z.string().min(1),
|
|
7987
|
+
changes: z.object({
|
|
7988
|
+
columns: z.array(z.string().min(1)).optional(),
|
|
7989
|
+
filters: z.custom().optional(),
|
|
7990
|
+
sorts: z.custom().optional(),
|
|
7991
|
+
allowCreate: z.boolean().optional(),
|
|
7992
|
+
allowEdit: z.boolean().optional(),
|
|
7993
|
+
allowDelete: z.boolean().optional(),
|
|
7994
|
+
createMode: z.enum(["redirect", "inline", "peek"]).optional()
|
|
7995
|
+
}).refine((c) => Object.keys(c).length > 0, "update_table_tab needs at least one change")
|
|
7996
|
+
});
|
|
7997
|
+
var updateTableTab = defineOperation({
|
|
7998
|
+
type: "update_table_tab",
|
|
7999
|
+
schema: updateTableTabSchema,
|
|
8000
|
+
apply: (state, op) => mapView(state, op.viewId, (view) => {
|
|
8001
|
+
const found = view.tabs.find((t) => t.id === op.tabId);
|
|
8002
|
+
if (!found) throw new ValidationError(`Tab "${op.tabId}" is not in view "${view.id}"`, []);
|
|
8003
|
+
if (found.type !== "table") {
|
|
8004
|
+
throw new ValidationError(`Tab "${op.tabId}" is not a table tab`, []);
|
|
8005
|
+
}
|
|
8006
|
+
return {
|
|
8007
|
+
...view,
|
|
8008
|
+
tabs: view.tabs.map((t) => t.id === op.tabId ? { ...t, ...op.changes } : t)
|
|
8009
|
+
};
|
|
8010
|
+
}),
|
|
8011
|
+
focus: (op) => ({ viewId: op.viewId, tabId: op.tabId }),
|
|
8012
|
+
describe: (op) => op.changes.columns ? `Affiche ${op.changes.columns.length} colonne(s) dans l'onglet ${op.tabId}` : `Modifie l'onglet ${op.tabId}`
|
|
8013
|
+
});
|
|
8014
|
+
var setSidePanelSchema = z.object({
|
|
8015
|
+
...viewOperationBase,
|
|
8016
|
+
type: z.literal("set_side_panel"),
|
|
8017
|
+
sidePanel: z.object({ attributes: z.array(z.string().min(1)), width: z.number().int().min(1).optional() }).nullable()
|
|
8018
|
+
});
|
|
8019
|
+
var setSidePanel = defineOperation({
|
|
8020
|
+
type: "set_side_panel",
|
|
8021
|
+
schema: setSidePanelSchema,
|
|
8022
|
+
apply: (state, op) => mapView(state, op.viewId, (view) => ({
|
|
8023
|
+
...view,
|
|
8024
|
+
config: {
|
|
8025
|
+
...view.config,
|
|
8026
|
+
sidePanel: op.sidePanel ?? void 0
|
|
8027
|
+
}
|
|
8028
|
+
})),
|
|
8029
|
+
focus: (op) => ({ viewId: op.viewId }),
|
|
8030
|
+
describe: (op) => op.sidePanel ? "Active le panneau lat\xE9ral" : "Retire le panneau lat\xE9ral"
|
|
8031
|
+
});
|
|
8032
|
+
var DETAIL_VIEW_OPERATIONS = [
|
|
8033
|
+
addTab,
|
|
8034
|
+
removeTab,
|
|
8035
|
+
updateTab,
|
|
8036
|
+
reorderTabs,
|
|
8037
|
+
addGroup,
|
|
8038
|
+
removeGroup,
|
|
8039
|
+
updateGroup,
|
|
8040
|
+
reorderGroups,
|
|
8041
|
+
addField,
|
|
8042
|
+
removeField,
|
|
8043
|
+
moveField,
|
|
8044
|
+
updateField,
|
|
8045
|
+
updateTableTab,
|
|
8046
|
+
setSidePanel
|
|
8047
|
+
];
|
|
8048
|
+
var listTabBase = { ...viewOperationBase, tabId: z.string().min(1) };
|
|
8049
|
+
function mapListTab(state, viewId, tabId, fn) {
|
|
8050
|
+
return mapView(state, viewId, (view) => {
|
|
8051
|
+
const tabs = view.config.tabs ?? [];
|
|
8052
|
+
if (!tabs.some((t) => t.id === tabId)) {
|
|
8053
|
+
throw new ValidationError(`List tab "${tabId}" is not in view "${viewId}"`, []);
|
|
8054
|
+
}
|
|
8055
|
+
return {
|
|
8056
|
+
...view,
|
|
8057
|
+
config: { ...view.config, tabs: tabs.map((t) => t.id === tabId ? fn(t) : t) }
|
|
8058
|
+
};
|
|
8059
|
+
});
|
|
8060
|
+
}
|
|
8061
|
+
var listTabPayload = z.custom(
|
|
8062
|
+
(value) => typeof value === "object" && value !== null && "id" in value,
|
|
8063
|
+
{ message: "A list tab must be an object carrying an id" }
|
|
8064
|
+
);
|
|
8065
|
+
var filterGroupPayload = z.custom(
|
|
8066
|
+
(value) => value === null || typeof value === "object"
|
|
8067
|
+
);
|
|
8068
|
+
var sortRulesPayload = z.custom((value) => Array.isArray(value));
|
|
8069
|
+
function setOnTab(type, key, valueSchema, describe) {
|
|
8070
|
+
const schema = z.object({ ...listTabBase, type: z.literal(type), value: valueSchema });
|
|
8071
|
+
return defineOperation({
|
|
8072
|
+
type,
|
|
8073
|
+
schema,
|
|
8074
|
+
apply: (state, op) => mapListTab(state, op.viewId, op.tabId, (tab) => {
|
|
8075
|
+
if (op.value === null) {
|
|
8076
|
+
const { [key]: _dropped, ...rest } = tab;
|
|
8077
|
+
return rest;
|
|
8078
|
+
}
|
|
8079
|
+
return { ...tab, [key]: op.value };
|
|
8080
|
+
}),
|
|
8081
|
+
focus: (op) => ({ viewId: op.viewId, tabId: op.tabId }),
|
|
8082
|
+
describe: (op) => describe(op.value)
|
|
8083
|
+
});
|
|
8084
|
+
}
|
|
8085
|
+
var addListTabSchema = z.object({
|
|
8086
|
+
...viewOperationBase,
|
|
8087
|
+
type: z.literal("add_list_tab"),
|
|
8088
|
+
tab: listTabPayload
|
|
8089
|
+
});
|
|
8090
|
+
var addListTab = defineOperation({
|
|
8091
|
+
type: "add_list_tab",
|
|
8092
|
+
schema: addListTabSchema,
|
|
8093
|
+
apply: (state, op) => mapView(state, op.viewId, (view) => {
|
|
8094
|
+
const tabs = view.config.tabs ?? [];
|
|
8095
|
+
if (tabs.some((t) => t.id === op.tab.id)) {
|
|
8096
|
+
throw new ValidationError(
|
|
8097
|
+
`List tab "${op.tab.id}" already exists in view "${op.viewId}"`,
|
|
8098
|
+
[]
|
|
8099
|
+
);
|
|
8100
|
+
}
|
|
8101
|
+
return { ...view, config: { ...view.config, tabs: [...tabs, op.tab] } };
|
|
8102
|
+
}),
|
|
8103
|
+
focus: (op) => ({ viewId: op.viewId, tabId: op.tab.id }),
|
|
8104
|
+
describe: (op) => `Ajoute l'onglet \xAB ${op.tab.label} \xBB`
|
|
8105
|
+
});
|
|
8106
|
+
var removeListTabSchema = z.object({
|
|
8107
|
+
...listTabBase,
|
|
8108
|
+
type: z.literal("remove_list_tab")
|
|
8109
|
+
});
|
|
8110
|
+
var removeListTab = defineOperation({
|
|
8111
|
+
type: "remove_list_tab",
|
|
8112
|
+
schema: removeListTabSchema,
|
|
8113
|
+
apply: (state, op) => mapView(state, op.viewId, (view) => {
|
|
8114
|
+
const tabs = view.config.tabs ?? [];
|
|
8115
|
+
if (!tabs.some((t) => t.id === op.tabId)) {
|
|
8116
|
+
throw new ValidationError(`List tab "${op.tabId}" is not in view "${op.viewId}"`, []);
|
|
8117
|
+
}
|
|
8118
|
+
return {
|
|
8119
|
+
...view,
|
|
8120
|
+
config: { ...view.config, tabs: tabs.filter((t) => t.id !== op.tabId) }
|
|
8121
|
+
};
|
|
8122
|
+
}),
|
|
8123
|
+
focus: (op) => ({ viewId: op.viewId }),
|
|
8124
|
+
describe: (op) => `Supprime l'onglet ${op.tabId}`
|
|
8125
|
+
});
|
|
8126
|
+
var updateListTabSchema = z.object({
|
|
8127
|
+
...listTabBase,
|
|
8128
|
+
type: z.literal("update_list_tab"),
|
|
8129
|
+
changes: z.object({
|
|
8130
|
+
label: z.string().min(1).optional(),
|
|
8131
|
+
icon: z.custom((v) => typeof v === "string" && v.length > 0).optional(),
|
|
8132
|
+
default: z.boolean().optional(),
|
|
8133
|
+
visibility: z.enum(LIST_VIEW_TAB_VISIBILITIES).optional()
|
|
8134
|
+
}).refine((c) => Object.keys(c).length > 0, "update_list_tab needs at least one change")
|
|
8135
|
+
});
|
|
8136
|
+
var updateListTab = defineOperation({
|
|
8137
|
+
type: "update_list_tab",
|
|
8138
|
+
schema: updateListTabSchema,
|
|
8139
|
+
apply: (state, op) => mapListTab(state, op.viewId, op.tabId, (tab) => ({ ...tab, ...op.changes })),
|
|
8140
|
+
focus: (op) => ({ viewId: op.viewId, tabId: op.tabId }),
|
|
8141
|
+
describe: (op) => op.changes.label ? `Renomme l'onglet en \xAB ${op.changes.label} \xBB` : `Modifie l'onglet ${op.tabId}`
|
|
8142
|
+
});
|
|
8143
|
+
var reorderListTabsSchema = z.object({
|
|
8144
|
+
...viewOperationBase,
|
|
8145
|
+
type: z.literal("reorder_list_tabs"),
|
|
8146
|
+
tabOrder: z.array(z.string().min(1))
|
|
8147
|
+
});
|
|
8148
|
+
var reorderListTabs = defineOperation({
|
|
8149
|
+
type: "reorder_list_tabs",
|
|
8150
|
+
schema: reorderListTabsSchema,
|
|
8151
|
+
apply: (state, op) => mapView(state, op.viewId, (view) => ({
|
|
8152
|
+
...view,
|
|
8153
|
+
config: {
|
|
8154
|
+
...view.config,
|
|
8155
|
+
tabs: reorderById(view.config.tabs ?? [], op.tabOrder, "List tab")
|
|
8156
|
+
}
|
|
8157
|
+
})),
|
|
8158
|
+
focus: (op) => ({ viewId: op.viewId }),
|
|
8159
|
+
describe: () => "R\xE9ordonne les onglets"
|
|
8160
|
+
});
|
|
8161
|
+
var setColumns = setOnTab(
|
|
8162
|
+
"set_columns",
|
|
8163
|
+
"columns",
|
|
8164
|
+
z.array(z.string().min(1)),
|
|
8165
|
+
// Defensive on shape: a summary is rendered in a list beside other summaries,
|
|
8166
|
+
// and one malformed payload must not take the page down with it.
|
|
8167
|
+
(value) => `Affiche ${Array.isArray(value) ? value.length : 0} colonne(s)`
|
|
8168
|
+
);
|
|
8169
|
+
var setColumnSizing = setOnTab(
|
|
8170
|
+
"set_column_sizing",
|
|
8171
|
+
"columnSizing",
|
|
8172
|
+
z.record(z.string(), z.number().int().positive()),
|
|
8173
|
+
() => "Ajuste la largeur des colonnes"
|
|
8174
|
+
);
|
|
8175
|
+
var setLayout = setOnTab(
|
|
8176
|
+
"set_layout",
|
|
8177
|
+
"layout",
|
|
8178
|
+
z.enum(["table", "kanban"]),
|
|
8179
|
+
(value) => `Passe en affichage ${value}`
|
|
8180
|
+
);
|
|
8181
|
+
var setGroupBy = setOnTab(
|
|
8182
|
+
"set_group_by",
|
|
8183
|
+
"groupByAttribute",
|
|
8184
|
+
z.string().min(1).nullable(),
|
|
8185
|
+
(value) => value ? `Regroupe par ${value}` : "Retire le regroupement"
|
|
8186
|
+
);
|
|
8187
|
+
var setFilters = setOnTab(
|
|
8188
|
+
"set_filters",
|
|
8189
|
+
"filters",
|
|
8190
|
+
filterGroupPayload.nullable(),
|
|
8191
|
+
(value) => value ? "Modifie les filtres" : "Retire les filtres"
|
|
8192
|
+
);
|
|
8193
|
+
var setSorts = setOnTab(
|
|
8194
|
+
"set_sorts",
|
|
8195
|
+
"sorts",
|
|
8196
|
+
sortRulesPayload.nullable(),
|
|
8197
|
+
(value) => value ? "Modifie le tri" : "Retire le tri"
|
|
8198
|
+
);
|
|
8199
|
+
var setCreateMode = setOnTab(
|
|
8200
|
+
"set_create_mode",
|
|
8201
|
+
"createMode",
|
|
8202
|
+
z.enum(["redirect", "inline", "peek"]),
|
|
8203
|
+
(value) => `Cr\xE9ation en mode ${value}`
|
|
8204
|
+
);
|
|
8205
|
+
var setReadOnly = setOnTab(
|
|
8206
|
+
"set_read_only",
|
|
8207
|
+
"readOnly",
|
|
8208
|
+
z.boolean(),
|
|
8209
|
+
(value) => value ? "Passe l'onglet en lecture seule" : "Rend l'onglet modifiable"
|
|
8210
|
+
);
|
|
8211
|
+
var setCardUserAttribute = setOnTab(
|
|
8212
|
+
"set_card_user_attribute",
|
|
8213
|
+
"cardUserAttribute",
|
|
8214
|
+
z.string().min(1).nullable(),
|
|
8215
|
+
(value) => value ? `Affiche ${value} sur les cartes` : "Retire l'utilisateur des cartes"
|
|
8216
|
+
);
|
|
8217
|
+
var setCardDateAttribute = setOnTab(
|
|
8218
|
+
"set_card_date_attribute",
|
|
8219
|
+
"cardDateAttribute",
|
|
8220
|
+
z.string().min(1).nullable(),
|
|
8221
|
+
(value) => value ? `Affiche ${value} sur les cartes` : "Retire la date des cartes"
|
|
8222
|
+
);
|
|
8223
|
+
var setDefaultFiltersSchema = z.object({
|
|
8224
|
+
...viewOperationBase,
|
|
8225
|
+
type: z.literal("set_default_filters"),
|
|
8226
|
+
filters: filterGroupPayload.nullable()
|
|
8227
|
+
});
|
|
8228
|
+
var setDefaultFilters = defineOperation({
|
|
8229
|
+
type: "set_default_filters",
|
|
8230
|
+
schema: setDefaultFiltersSchema,
|
|
8231
|
+
apply: (state, op) => mapView(state, op.viewId, (view) => {
|
|
8232
|
+
if (op.filters === null) {
|
|
8233
|
+
const { defaultFilters: _dropped, ...rest } = view.config;
|
|
8234
|
+
return { ...view, config: rest };
|
|
8235
|
+
}
|
|
8236
|
+
return { ...view, config: { ...view.config, defaultFilters: op.filters } };
|
|
8237
|
+
}),
|
|
8238
|
+
focus: (op) => ({ viewId: op.viewId }),
|
|
8239
|
+
describe: (op) => op.filters ? "Modifie les filtres de la vue" : "Retire les filtres de la vue"
|
|
8240
|
+
});
|
|
8241
|
+
var LIST_VIEW_OPERATIONS = [
|
|
8242
|
+
setDefaultFilters,
|
|
8243
|
+
addListTab,
|
|
8244
|
+
removeListTab,
|
|
8245
|
+
updateListTab,
|
|
8246
|
+
reorderListTabs,
|
|
8247
|
+
setColumns,
|
|
8248
|
+
setColumnSizing,
|
|
8249
|
+
setLayout,
|
|
8250
|
+
setGroupBy,
|
|
8251
|
+
setFilters,
|
|
8252
|
+
setSorts,
|
|
8253
|
+
setCreateMode,
|
|
8254
|
+
setReadOnly,
|
|
8255
|
+
setCardUserAttribute,
|
|
8256
|
+
setCardDateAttribute
|
|
8257
|
+
];
|
|
8258
|
+
function requireObject(state, objectId) {
|
|
8259
|
+
if (!state.objects.some((o) => o.id === objectId)) {
|
|
8260
|
+
throw new ValidationError(`Object "${objectId}" is not in the draftable state`, []);
|
|
8261
|
+
}
|
|
8262
|
+
}
|
|
8263
|
+
var objectOperationBase = { ...operationBase, objectId: z.string().min(1) };
|
|
8264
|
+
var addObjectSchema = z.object({
|
|
8265
|
+
...objectOperationBase,
|
|
8266
|
+
type: z.literal("add_object"),
|
|
8267
|
+
name: z.string().min(1),
|
|
8268
|
+
label: z.string().min(1),
|
|
8269
|
+
icon: z.string().min(1).optional()
|
|
8270
|
+
});
|
|
8271
|
+
var addObject = defineOperation({
|
|
8272
|
+
type: "add_object",
|
|
8273
|
+
schema: addObjectSchema,
|
|
8274
|
+
apply: (state, op) => {
|
|
8275
|
+
if (state.objects.some((o) => o.name === op.name)) {
|
|
8276
|
+
throw new ValidationError(`Object "${op.name}" already exists`, []);
|
|
8277
|
+
}
|
|
8278
|
+
if (state.objects.some((o) => o.id === op.objectId)) {
|
|
8279
|
+
throw new ValidationError(`Object id "${op.objectId}" is already taken`, []);
|
|
8280
|
+
}
|
|
8281
|
+
const created = {
|
|
8282
|
+
id: op.objectId,
|
|
8283
|
+
name: op.name,
|
|
8284
|
+
label: op.label,
|
|
8285
|
+
...op.icon === void 0 ? {} : { icon: op.icon }
|
|
8286
|
+
};
|
|
8287
|
+
return { ...state, objects: [...state.objects, created] };
|
|
8288
|
+
},
|
|
8289
|
+
// The caller generates objectId, so a draft object is addressable by route
|
|
8290
|
+
// before it exists — that is what lets the app navigate to it live.
|
|
8291
|
+
focus: (op) => ({ objectId: op.objectId }),
|
|
8292
|
+
describe: (op) => `Cr\xE9e l'objet \xAB ${op.label} \xBB`
|
|
8293
|
+
});
|
|
8294
|
+
var updateObjectSchema = z.object({
|
|
8295
|
+
...objectOperationBase,
|
|
8296
|
+
type: z.literal("update_object"),
|
|
8297
|
+
changes: z.object({ label: z.string().min(1).optional(), icon: z.string().min(1).optional() }).refine((c) => Object.keys(c).length > 0, "update_object needs at least one change")
|
|
8298
|
+
});
|
|
8299
|
+
var updateObject = defineOperation({
|
|
8300
|
+
type: "update_object",
|
|
8301
|
+
schema: updateObjectSchema,
|
|
8302
|
+
apply: (state, op) => {
|
|
8303
|
+
requireObject(state, op.objectId);
|
|
8304
|
+
return {
|
|
8305
|
+
...state,
|
|
8306
|
+
objects: state.objects.map((o) => o.id === op.objectId ? { ...o, ...op.changes } : o)
|
|
8307
|
+
};
|
|
8308
|
+
},
|
|
8309
|
+
focus: (op) => ({ objectId: op.objectId }),
|
|
8310
|
+
describe: (op) => op.changes.label ? `Renomme l'objet en \xAB ${op.changes.label} \xBB` : "Modifie l'objet"
|
|
8311
|
+
});
|
|
8312
|
+
var removeObjectSchema = z.object({ ...objectOperationBase, type: z.literal("remove_object") });
|
|
8313
|
+
var removeObject = defineOperation({
|
|
8314
|
+
type: "remove_object",
|
|
8315
|
+
schema: removeObjectSchema,
|
|
8316
|
+
apply: (state, op) => {
|
|
8317
|
+
requireObject(state, op.objectId);
|
|
8318
|
+
const objectName = state.objects.find((o) => o.id === op.objectId)?.name;
|
|
8319
|
+
return {
|
|
8320
|
+
...state,
|
|
8321
|
+
objects: state.objects.filter((o) => o.id !== op.objectId),
|
|
8322
|
+
attributes: state.attributes.filter((a) => a.objectId !== op.objectId),
|
|
8323
|
+
sampleRecords: state.sampleRecords.filter((r) => r.objectId !== op.objectId),
|
|
8324
|
+
views: state.views.filter((v) => v.objectName !== objectName)
|
|
8325
|
+
};
|
|
8326
|
+
},
|
|
8327
|
+
focus: () => ({}),
|
|
8328
|
+
describe: (op) => `Supprime l'objet ${op.objectId}`
|
|
8329
|
+
});
|
|
8330
|
+
var addAttributeSchema = z.object({
|
|
8331
|
+
...objectOperationBase,
|
|
8332
|
+
type: z.literal("add_attribute"),
|
|
8333
|
+
attributeId: z.string().min(1),
|
|
8334
|
+
name: z.string().min(1),
|
|
8335
|
+
label: z.string().min(1),
|
|
8336
|
+
attributeType: z.string().min(1)
|
|
8337
|
+
});
|
|
8338
|
+
var addAttribute = defineOperation({
|
|
8339
|
+
type: "add_attribute",
|
|
8340
|
+
schema: addAttributeSchema,
|
|
8341
|
+
apply: (state, op) => {
|
|
8342
|
+
requireObject(state, op.objectId);
|
|
8343
|
+
if (state.attributes.some((a) => a.objectId === op.objectId && a.name === op.name)) {
|
|
8344
|
+
throw new ValidationError(
|
|
8345
|
+
`Attribute "${op.name}" already exists on object "${op.objectId}"`,
|
|
8346
|
+
[]
|
|
8347
|
+
);
|
|
8348
|
+
}
|
|
8349
|
+
return {
|
|
8350
|
+
...state,
|
|
8351
|
+
attributes: [
|
|
8352
|
+
...state.attributes,
|
|
8353
|
+
{
|
|
8354
|
+
id: op.attributeId,
|
|
8355
|
+
objectId: op.objectId,
|
|
8356
|
+
name: op.name,
|
|
8357
|
+
label: op.label,
|
|
8358
|
+
attributeType: op.attributeType
|
|
8359
|
+
}
|
|
8360
|
+
]
|
|
8361
|
+
};
|
|
8362
|
+
},
|
|
8363
|
+
focus: (op) => ({ objectId: op.objectId }),
|
|
8364
|
+
describe: (op) => `Ajoute l'attribut \xAB ${op.label} \xBB`
|
|
8365
|
+
});
|
|
8366
|
+
var updateAttributeSchema = z.object({
|
|
8367
|
+
...objectOperationBase,
|
|
8368
|
+
type: z.literal("update_attribute"),
|
|
8369
|
+
attributeId: z.string().min(1),
|
|
8370
|
+
changes: z.object({ label: z.string().min(1).optional() }).refine((c) => Object.keys(c).length > 0, "update_attribute needs at least one change")
|
|
8371
|
+
});
|
|
8372
|
+
var updateAttribute = defineOperation({
|
|
8373
|
+
type: "update_attribute",
|
|
8374
|
+
schema: updateAttributeSchema,
|
|
8375
|
+
apply: (state, op) => {
|
|
8376
|
+
if (!state.attributes.some((a) => a.id === op.attributeId)) {
|
|
8377
|
+
throw new ValidationError(`Attribute "${op.attributeId}" is not in the draftable state`, []);
|
|
8378
|
+
}
|
|
8379
|
+
return {
|
|
8380
|
+
...state,
|
|
8381
|
+
attributes: state.attributes.map(
|
|
8382
|
+
(a) => a.id === op.attributeId ? { ...a, ...op.changes } : a
|
|
8383
|
+
)
|
|
8384
|
+
};
|
|
8385
|
+
},
|
|
8386
|
+
// Carries objectId so the scope can load the attribute's parent. Without it
|
|
8387
|
+
// the reader returns an empty state and the fold rejects the operation before
|
|
8388
|
+
// the draft is ever persisted — renaming an existing field was impossible.
|
|
8389
|
+
focus: (op) => ({ objectId: op.objectId }),
|
|
8390
|
+
describe: (op) => op.changes.label ? `Renomme l'attribut en \xAB ${op.changes.label} \xBB` : "Modifie l'attribut"
|
|
8391
|
+
});
|
|
8392
|
+
var removeAttributeSchema = z.object({
|
|
8393
|
+
...objectOperationBase,
|
|
8394
|
+
type: z.literal("remove_attribute"),
|
|
8395
|
+
attributeId: z.string().min(1)
|
|
8396
|
+
});
|
|
8397
|
+
var removeAttribute = defineOperation({
|
|
8398
|
+
type: "remove_attribute",
|
|
8399
|
+
schema: removeAttributeSchema,
|
|
8400
|
+
apply: (state, op) => {
|
|
8401
|
+
if (!state.attributes.some((a) => a.id === op.attributeId)) {
|
|
8402
|
+
throw new ValidationError(`Attribute "${op.attributeId}" is not in the draftable state`, []);
|
|
8403
|
+
}
|
|
8404
|
+
return { ...state, attributes: state.attributes.filter((a) => a.id !== op.attributeId) };
|
|
8405
|
+
},
|
|
8406
|
+
// Same reason as update_attribute: the parent object must be in scope.
|
|
8407
|
+
focus: (op) => ({ objectId: op.objectId }),
|
|
8408
|
+
describe: (op) => `Supprime l'attribut ${op.attributeId}`
|
|
8409
|
+
});
|
|
8410
|
+
var addSampleRecordSchema = z.object({
|
|
8411
|
+
...objectOperationBase,
|
|
8412
|
+
type: z.literal("add_sample_record"),
|
|
8413
|
+
recordId: z.string().min(1),
|
|
8414
|
+
values: z.record(z.string(), z.unknown())
|
|
8415
|
+
});
|
|
8416
|
+
var addSampleRecord = defineOperation({
|
|
8417
|
+
type: "add_sample_record",
|
|
8418
|
+
schema: addSampleRecordSchema,
|
|
8419
|
+
apply: (state, op) => {
|
|
8420
|
+
requireObject(state, op.objectId);
|
|
8421
|
+
if (state.sampleRecords.some((r) => r.id === op.recordId)) {
|
|
8422
|
+
throw new ValidationError(`Sample record "${op.recordId}" already exists`, []);
|
|
8423
|
+
}
|
|
8424
|
+
return {
|
|
8425
|
+
...state,
|
|
8426
|
+
sampleRecords: [
|
|
8427
|
+
...state.sampleRecords,
|
|
8428
|
+
{ id: op.recordId, objectId: op.objectId, values: op.values }
|
|
8429
|
+
]
|
|
8430
|
+
};
|
|
8431
|
+
},
|
|
8432
|
+
// A sample is a draft record, not a render-time fiction: publishing
|
|
8433
|
+
// materialises it, discarding the draft discards it.
|
|
8434
|
+
focus: (op) => ({ objectId: op.objectId, recordId: op.recordId }),
|
|
8435
|
+
describe: () => "Ajoute un exemple"
|
|
8436
|
+
});
|
|
8437
|
+
var removeSampleRecordSchema = z.object({
|
|
8438
|
+
...operationBase,
|
|
8439
|
+
type: z.literal("remove_sample_record"),
|
|
8440
|
+
recordId: z.string().min(1)
|
|
8441
|
+
});
|
|
8442
|
+
var removeSampleRecord = defineOperation({
|
|
8443
|
+
type: "remove_sample_record",
|
|
8444
|
+
schema: removeSampleRecordSchema,
|
|
8445
|
+
apply: (state, op) => {
|
|
8446
|
+
if (!state.sampleRecords.some((r) => r.id === op.recordId)) {
|
|
8447
|
+
throw new ValidationError(`Sample record "${op.recordId}" is not in the draft`, []);
|
|
8448
|
+
}
|
|
8449
|
+
return { ...state, sampleRecords: state.sampleRecords.filter((r) => r.id !== op.recordId) };
|
|
8450
|
+
},
|
|
8451
|
+
focus: () => ({}),
|
|
8452
|
+
describe: () => "Retire un exemple"
|
|
8453
|
+
});
|
|
8454
|
+
var SCHEMA_OPERATIONS = [
|
|
8455
|
+
addObject,
|
|
8456
|
+
updateObject,
|
|
8457
|
+
removeObject,
|
|
8458
|
+
addAttribute,
|
|
8459
|
+
updateAttribute,
|
|
8460
|
+
removeAttribute,
|
|
8461
|
+
addSampleRecord,
|
|
8462
|
+
removeSampleRecord
|
|
8463
|
+
];
|
|
8464
|
+
|
|
8465
|
+
// src/architect/registry.ts
|
|
8466
|
+
function build() {
|
|
8467
|
+
const map = /* @__PURE__ */ new Map();
|
|
8468
|
+
for (const definition of [
|
|
8469
|
+
...SCHEMA_OPERATIONS,
|
|
8470
|
+
...DETAIL_VIEW_OPERATIONS,
|
|
8471
|
+
...LIST_VIEW_OPERATIONS
|
|
8472
|
+
]) {
|
|
8473
|
+
if (map.has(definition.type)) {
|
|
8474
|
+
throw new DuplicateError("architect operation", definition.type);
|
|
8475
|
+
}
|
|
8476
|
+
map.set(definition.type, definition);
|
|
8477
|
+
}
|
|
8478
|
+
return map;
|
|
8479
|
+
}
|
|
8480
|
+
var OPERATION_REGISTRY = build();
|
|
8481
|
+
var ALL_OPERATION_TYPES = [...OPERATION_REGISTRY.keys()];
|
|
8482
|
+
|
|
8483
|
+
// src/architect/apply.ts
|
|
8484
|
+
function defOf(operation) {
|
|
8485
|
+
const definition = OPERATION_REGISTRY.get(operation.type);
|
|
8486
|
+
if (!definition) {
|
|
8487
|
+
throw new ValidationError(
|
|
8488
|
+
`Operation "${operation.id}" has unknown type "${operation.type}"`,
|
|
8489
|
+
[]
|
|
8490
|
+
);
|
|
8491
|
+
}
|
|
8492
|
+
return definition;
|
|
8493
|
+
}
|
|
8494
|
+
function applyOperations(state, operations) {
|
|
8495
|
+
return operations.reduce(
|
|
8496
|
+
(acc, operation) => defOf(operation).apply(acc, operation),
|
|
8497
|
+
state
|
|
8498
|
+
);
|
|
8499
|
+
}
|
|
8500
|
+
function focusOf(operation) {
|
|
8501
|
+
return defOf(operation).focus(operation);
|
|
8502
|
+
}
|
|
8503
|
+
function describeOperations(operations, ctx) {
|
|
8504
|
+
return operations.map((operation) => defOf(operation).describe(operation, ctx));
|
|
8505
|
+
}
|
|
8506
|
+
function parseOperation(candidate) {
|
|
8507
|
+
if (typeof candidate !== "object" || candidate === null || !("type" in candidate)) {
|
|
8508
|
+
throw new ValidationError("An operation must be an object carrying a type", []);
|
|
8509
|
+
}
|
|
8510
|
+
const type = candidate.type;
|
|
8511
|
+
if (typeof type !== "string") {
|
|
8512
|
+
throw new ValidationError("An operation's type must be a string", []);
|
|
8513
|
+
}
|
|
8514
|
+
const definition = OPERATION_REGISTRY.get(type);
|
|
8515
|
+
if (!definition) {
|
|
8516
|
+
throw new ValidationError(`Unknown operation type "${type}"`, []);
|
|
8517
|
+
}
|
|
8518
|
+
const parsed = definition.schema.safeParse(candidate);
|
|
8519
|
+
if (!parsed.success) {
|
|
8520
|
+
throw new ValidationError(
|
|
8521
|
+
`Operation "${type}" is invalid: ${parsed.error.issues.map((i) => `${i.path.join(".")} ${i.message}`).join("; ")}`,
|
|
8522
|
+
[]
|
|
8523
|
+
);
|
|
8524
|
+
}
|
|
8525
|
+
return parsed.data;
|
|
8526
|
+
}
|
|
8527
|
+
|
|
8528
|
+
// src/architect/field-ids.ts
|
|
8529
|
+
function makeFieldId(groupId, seed, collisionIndex) {
|
|
8530
|
+
const base = `fld_${groupId}_${seed}`;
|
|
8531
|
+
return collisionIndex === 0 ? base : `${base}_${collisionIndex}`;
|
|
8532
|
+
}
|
|
8533
|
+
function seedOf(field, index) {
|
|
8534
|
+
if (field.attributeGroup) return field.attributeGroup.id;
|
|
8535
|
+
if (field.attribute) return field.attribute;
|
|
8536
|
+
return `slot${index}`;
|
|
8537
|
+
}
|
|
8538
|
+
function withIds(group2) {
|
|
8539
|
+
const seen = /* @__PURE__ */ new Map();
|
|
8540
|
+
const fields = group2.fields.map((field, index) => {
|
|
8541
|
+
if (field.id) return field;
|
|
8542
|
+
const seed = seedOf(field, index);
|
|
8543
|
+
const collisionIndex = seen.get(seed) ?? 0;
|
|
8544
|
+
seen.set(seed, collisionIndex + 1);
|
|
8545
|
+
return { ...field, id: makeFieldId(group2.id, seed, collisionIndex) };
|
|
8546
|
+
});
|
|
8547
|
+
return { ...group2, fields };
|
|
8548
|
+
}
|
|
8549
|
+
function ensureFieldIds(tabs) {
|
|
8550
|
+
return tabs.map(
|
|
8551
|
+
(tab) => tab.type === "form" ? { ...tab, groups: tab.groups.map(withIds) } : tab
|
|
8552
|
+
);
|
|
8553
|
+
}
|
|
8554
|
+
|
|
8555
|
+
// src/architect/view-projection.ts
|
|
8556
|
+
function toDraftableView(view) {
|
|
8557
|
+
return {
|
|
8558
|
+
id: view.id ?? "",
|
|
8559
|
+
objectName: view.object,
|
|
8560
|
+
type: view.type,
|
|
8561
|
+
label: view.label,
|
|
8562
|
+
tabs: isDetailView(view) ? view.config.tabs ?? [] : [],
|
|
8563
|
+
config: view.config
|
|
8564
|
+
};
|
|
8565
|
+
}
|
|
8566
|
+
function fromDraftableView(original, drafted) {
|
|
8567
|
+
if (original.type === "detail") {
|
|
8568
|
+
return {
|
|
8569
|
+
...original,
|
|
8570
|
+
label: drafted.label,
|
|
8571
|
+
config: {
|
|
8572
|
+
...drafted.config,
|
|
8573
|
+
tabs: drafted.tabs
|
|
8574
|
+
}
|
|
8575
|
+
};
|
|
8576
|
+
}
|
|
8577
|
+
return {
|
|
8578
|
+
...original,
|
|
8579
|
+
label: drafted.label,
|
|
8580
|
+
config: drafted.config
|
|
8581
|
+
};
|
|
8582
|
+
}
|
|
8583
|
+
|
|
8584
|
+
export { AGENT_UI_BATCH_MAX_BYTES, AGENT_UI_BATCH_MAX_ITEMS, ALLOWED_PROPERTY_TYPES, ALL_ACTIONS, ALL_OPERATION_TYPES, ALL_SYSTEM_RESOURCES, AUDIT_ACTIONS, AUDIT_RESOURCE_TYPES, ActivityTabConfig, AgentBuilder, BEHAVIOR_PROPERTIES, BROWSER_PREVIEW_STATUSES, BYTE_UNIT_LABELS, CLAIMABLE_SESSION_STATUSES, COMPUTED_FUNCTIONS, COMPUTED_FUNCTION_METADATA, COMPUTED_FUNCTION_NAMES, CONNECTOR_CALLBACK_PARAM, COUNT_MODES, ComputedFormulaCompileError, CustomTabConfig, DB_COLUMN_FIELDS, DEFAULT_AGENT_EXECUTION_CONFIG, DEFAULT_APPROVAL_POLICY, DEFAULT_LABEL_FALLBACK, DEFAULT_ROLES, DEFAULT_ROLE_DESCRIPTIONS, DEFAULT_ROLE_LABELS, DEFAULT_ROLE_PERMISSIONS, DOCUMENT_SYSTEM_ATTRIBUTES, DRIVE_LIST_VIEW, DRIVE_OBJECT, DRIVE_OBJECT_NAME, DRIVE_VIEW, DetailViewBuilder, DocumentsTabConfig, EMPTY_VALUE_PLACEHOLDER, ESTIMATED_COUNT_CAP, EmailsTabConfig, FORM_FORBIDDEN_ATTRIBUTE_TYPES, FlagRegistry, FlagService, FormBuilder, FormRegistry, FormRowBuilder, FormStepBuilder, GroupBuilder, IDENTITY_PROPERTIES, LIVE_EVENT_TYPES, ListViewBuilder, ListViewTabConfigBuilder, MAX_PRESET_DEPTH, MAX_TODOS, MAX_TODO_DESCRIPTION_CHARS, MAX_TODO_ID_CHARS, MAX_TODO_RESULT_CHARS, MEMORY_LIST_VIEW, MEMORY_OBJECT, MEMORY_VIEW, MeetingsTabConfig, NATIVE_AGENT_UI_PART_IDS_METADATA_KEY, NATIVE_AGENT_UI_PART_IDS_METADATA_SCHEMA_VERSION, NOTIFICATION_INBOX_STATES, NOTIFICATION_KINDS, NOTIFICATION_PRIORITIES, NOTIFICATION_SENSITIVITIES, NOTIFICATION_TYPES_V1, NOTIFICATION_TYPE_AGENT_QUESTION_REQUESTED, NOTIFICATION_TYPE_AGENT_SESSION_COMPLETED, NOTIFICATION_TYPE_AGENT_SESSION_FAILED, NOTIFICATION_TYPE_AGENT_SESSION_TIMEOUT, NOTIFICATION_TYPE_AGENT_SESSION_WAITING_HUMAN, NOTIFICATION_TYPE_AGENT_TASK_ASSIGNED, NOTIFICATION_WORK_STATES, NoopGeocodingAdapter, OPEN_TOOL_PART_STATES, OPERATION_REGISTRY, OPERATOR_SPECS, ObjectBuilder, PRESENTATION_PROPERTIES, QUALIFIED_SEPARATOR, RECORD_CREATOR_ROOT_ACTOR_METADATA_KEY, RELATION_TARGET_ANY, RichtextTabConfig, SCHEMA_PLAN_LIMITS, SESSION_TERMINAL_STATUSES, SKILL_LIST_VIEW, SKILL_OBJECT, SKILL_VIEW, STANDARD_SCHEMA_VENDOR, SYSTEM_RESOURCES, SYSTEM_RESOURCE_LABELS, TODAY_DEFAULT, TODO_PLAN_STATUSES, TODO_STATUSES, TOOL_APPROVAL_STATES, TabBuilder, TableTabConfig, USER_STATUSES, USER_WORK_POSTURES, accessLevelToActions, actionsToAccessLevel, agent, agentDisplayName, applyOperations, applyPipes, applyRelationProps, assertAcyclicComputedDependencies, booleanFlag, buildAgentFallbackTitle, buildPermissionFlags, buildPropertySchema, buildQualifiedAttribute, checkbox, compileComputedFormula, compileRollupAttribute, computeByteMagnitude, conversationDisplayTitle, createFlagRegistry, createFlagService, createStandardSchemaProps, currency, date, dateInTimezone, dateValueStart, defineOperation, deriveInitials, describeOperations, destructiveSchema, detailView, document, ensureFieldIds, evaluateComputedAst, evaluateComputedFormula, evaluateComputedFormulaWithResult, evaluateFilterState, evaluateRecordFilterState, extractAttributeNames, extractValueRefs, flagRegistry, focusOf, form, formFieldFlatKey, formFieldKey, formRegistry, formatAttributeValue, formatByteSize, formatComputedResult, formatLocationValue, formula, fromDraftableView, generateDefaultDetailView, generateDefaultListView, getActiveTab, getErrorMessage, getLiveProtocolPayloadChannel, getRecordCreatorPrincipalId, getSlotFieldTargets, getUserDisplayName, group, hasDestructiveEntries, hasOptions, includesAction, inferInverseCardinality, inferRollupReturnType, isAgentUIMessageBatch, isAttributeSortable2 as isAttributeSortable, isBilateralRelation, isCheckboxEquality, isClaimableSessionStatus, isComputedFunctionName, isDateRangeValue, isDefaultRole, isDetailView, isDocumentAttribute, isEmptyObject, isFieldGroup, isFormDefinition, isFormFieldsRow, isFormFreeFieldRef, isFormHeadingRow, isFormSeparatorRow, isFormSlotFieldRef, isFormTextRow, isLabelExpression, isListView, isLiveEventEnvelope, isLiveEventPayload, isLiveEventPayloadForType, isLiveEventType, isNotEmpty, isOpenToolPartState, isPlainRecord2 as isPlainRecord, isStandardSchema, isTerminalSessionStatus, isTerminalState, isToolApprovalState, isUniversalRelation, jsonFlag, legacyStatusToSessionState, listView, liveChannelKey, location, makeFieldId, matchesAccepts, multiselect, nativeAgentUIPartIdMetadataKey, normalizeDateValue, number, numberFlag, object, parseCountMode, parseLiveChannelKey, parseNativeAgentUIPartIdsMetadata, parseOperation, parseOptionalCountMode, parseQualifiedAttribute, persistedDefaultViewTargetSchema, persistedSchemaPlanSchema, phone, plannedAttributeSchema, plannedInlineAttributeSchema, plannedObjectSchema, proposedDefaultViewTargetSchema, qualifiedPropertyDefs, readFormFieldValue, registry, relation, relationPropertyDefs, renderLabelExpression, resetViewToDefault, resolveAttributeDefaultValue, resolveFieldRequired, resolvePropertyDefinitions, richtext, rollup, rollupToFormulaExpression, schemaPlanSchema, select, sessionStateToLegacyStatus, status, stringFlag, text, toDraftableView, toUndefinedIfEmpty, user, validateAttributeName, validateLabelExpression, validateObjectName, validateViewName, viewRegistry, viewStateKey, viewSyncPayload };
|