@stndrds/schema 1.0.0-alpha.83 → 1.0.0-alpha.85
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/{chunk-NEVERCM3.js → chunk-E6XO2STS.js} +21 -1
- package/dist/{chunk-OR44EVWO.mjs → chunk-HKT7LEYM.mjs} +114 -102
- package/dist/{chunk-7VNLLASJ.mjs → chunk-JUVFK6XD.mjs} +2 -1
- package/dist/{chunk-WHDJLJRK.js → chunk-UGWL4KQR.js} +374 -362
- package/dist/{chunk-V2RPPE2Y.mjs → chunk-XAORXFAX.mjs} +21 -1
- package/dist/{chunk-HUT6HYXJ.js → chunk-ZW4N6FV7.js} +2 -1
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +9 -7
- package/dist/index.mjs +5 -3
- package/dist/{runtime-B6Dt5_Gc.d.ts → runtime-DSh9YK1-.d.ts} +8 -49
- package/dist/{runtime-Ttkdn9W7.d.mts → runtime-Dz1KblvE.d.mts} +8 -49
- package/dist/runtime.d.mts +2 -2
- package/dist/runtime.d.ts +2 -2
- package/dist/runtime.js +4 -4
- package/dist/runtime.mjs +3 -3
- package/dist/utils.d.mts +20 -1
- package/dist/utils.d.ts +20 -1
- package/dist/utils.js +4 -2
- package/dist/utils.mjs +3 -1
- package/dist/validation/validators.d.mts +1 -1
- package/dist/validation/validators.d.ts +1 -1
- package/dist/validation/validators.js +2 -2
- package/dist/validation/validators.mjs +1 -1
- package/dist/{validators-BeBrdQCB.d.mts → validators-CJmtOk1a.d.mts} +29 -1
- package/dist/{validators-UuAMCPc6.d.ts → validators-pv_b6bI_.d.ts} +29 -1
- package/package.json +2 -2
|
@@ -29,6 +29,26 @@ function generateTemplateName(label) {
|
|
|
29
29
|
function indexBy(items, keyFn) {
|
|
30
30
|
return new Map(items.map((item) => [keyFn(item), item]));
|
|
31
31
|
}
|
|
32
|
+
function deepEqual(a, b) {
|
|
33
|
+
if (a === b) return true;
|
|
34
|
+
if (a == null || b == null) return false;
|
|
35
|
+
if (typeof a !== typeof b) return false;
|
|
36
|
+
if (Array.isArray(a)) {
|
|
37
|
+
if (!Array.isArray(b)) return false;
|
|
38
|
+
if (a.length !== b.length) return false;
|
|
39
|
+
return a.every((item, index) => deepEqual(item, b[index]));
|
|
40
|
+
}
|
|
41
|
+
if (typeof a === "object" && typeof b === "object") {
|
|
42
|
+
const aObj = a;
|
|
43
|
+
const bObj = b;
|
|
44
|
+
const aKeys = Object.keys(aObj);
|
|
45
|
+
const bKeys = Object.keys(bObj);
|
|
46
|
+
if (aKeys.length !== bKeys.length) return false;
|
|
47
|
+
return aKeys.every((key) => key in bObj && deepEqual(aObj[key], bObj[key]));
|
|
48
|
+
}
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
|
|
32
52
|
|
|
33
53
|
|
|
34
54
|
|
|
@@ -38,4 +58,4 @@ function indexBy(items, keyFn) {
|
|
|
38
58
|
|
|
39
59
|
|
|
40
60
|
|
|
41
|
-
exports.asTenantId = asTenantId; exports.asUserId = asUserId; exports.generateId = generateId; exports.generatePrefixedId = generatePrefixedId; exports.slugify = slugify; exports.generateTemplateName = generateTemplateName; exports.indexBy = indexBy;
|
|
61
|
+
exports.asTenantId = asTenantId; exports.asUserId = asUserId; exports.generateId = generateId; exports.generatePrefixedId = generatePrefixedId; exports.slugify = slugify; exports.generateTemplateName = generateTemplateName; exports.indexBy = indexBy; exports.deepEqual = deepEqual;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
asTenantId,
|
|
3
3
|
asUserId,
|
|
4
|
+
deepEqual,
|
|
4
5
|
generateId
|
|
5
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-XAORXFAX.mjs";
|
|
6
7
|
import {
|
|
7
8
|
computeRecordStatus,
|
|
8
9
|
createFormAttributeValidator,
|
|
@@ -12,7 +13,7 @@ import {
|
|
|
12
13
|
validateDraftOrThrow,
|
|
13
14
|
validateObject,
|
|
14
15
|
validateObjectOrThrow
|
|
15
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-JUVFK6XD.mjs";
|
|
16
17
|
import {
|
|
17
18
|
__require
|
|
18
19
|
} from "./chunk-Y6FXYEAI.mjs";
|
|
@@ -3458,96 +3459,6 @@ function createMockAIConversationsRepository(stores) {
|
|
|
3458
3459
|
}
|
|
3459
3460
|
};
|
|
3460
3461
|
}
|
|
3461
|
-
function createMockAIUserMemoryRepository(stores) {
|
|
3462
|
-
const getKey = () => {
|
|
3463
|
-
const tenantId = getTenantId();
|
|
3464
|
-
const userId = requireUserId();
|
|
3465
|
-
return `${tenantId}:${userId}`;
|
|
3466
|
-
};
|
|
3467
|
-
return {
|
|
3468
|
-
get() {
|
|
3469
|
-
const key = getKey();
|
|
3470
|
-
return Promise.resolve(stores.aiUserMemory.get(key) ?? null);
|
|
3471
|
-
},
|
|
3472
|
-
upsert(data) {
|
|
3473
|
-
const key = getKey();
|
|
3474
|
-
const tenantId = getTenantId();
|
|
3475
|
-
const userId = requireUserId();
|
|
3476
|
-
const now = /* @__PURE__ */ new Date();
|
|
3477
|
-
const existing = stores.aiUserMemory.get(key);
|
|
3478
|
-
const memory = {
|
|
3479
|
-
id: existing?.id ?? generateId(),
|
|
3480
|
-
tenantId,
|
|
3481
|
-
userId,
|
|
3482
|
-
preferences: data.preferences ?? existing?.preferences ?? {},
|
|
3483
|
-
facts: data.facts ?? existing?.facts ?? [],
|
|
3484
|
-
createdAt: existing?.createdAt ?? now,
|
|
3485
|
-
updatedAt: now
|
|
3486
|
-
};
|
|
3487
|
-
stores.aiUserMemory.set(key, memory);
|
|
3488
|
-
return Promise.resolve(memory);
|
|
3489
|
-
},
|
|
3490
|
-
addFact(fact) {
|
|
3491
|
-
const key = getKey();
|
|
3492
|
-
const tenantId = getTenantId();
|
|
3493
|
-
const userId = requireUserId();
|
|
3494
|
-
const now = /* @__PURE__ */ new Date();
|
|
3495
|
-
const existing = stores.aiUserMemory.get(key);
|
|
3496
|
-
const memory = {
|
|
3497
|
-
id: existing?.id ?? generateId(),
|
|
3498
|
-
tenantId,
|
|
3499
|
-
userId,
|
|
3500
|
-
preferences: existing?.preferences ?? {},
|
|
3501
|
-
facts: [...existing?.facts ?? [], fact],
|
|
3502
|
-
createdAt: existing?.createdAt ?? now,
|
|
3503
|
-
updatedAt: now
|
|
3504
|
-
};
|
|
3505
|
-
stores.aiUserMemory.set(key, memory);
|
|
3506
|
-
return Promise.resolve(memory);
|
|
3507
|
-
},
|
|
3508
|
-
removeFact(fact) {
|
|
3509
|
-
const key = getKey();
|
|
3510
|
-
const tenantId = getTenantId();
|
|
3511
|
-
const userId = requireUserId();
|
|
3512
|
-
const now = /* @__PURE__ */ new Date();
|
|
3513
|
-
const existing = stores.aiUserMemory.get(key);
|
|
3514
|
-
const memory = {
|
|
3515
|
-
id: existing?.id ?? generateId(),
|
|
3516
|
-
tenantId,
|
|
3517
|
-
userId,
|
|
3518
|
-
preferences: existing?.preferences ?? {},
|
|
3519
|
-
facts: (existing?.facts ?? []).filter((f) => f !== fact),
|
|
3520
|
-
createdAt: existing?.createdAt ?? now,
|
|
3521
|
-
updatedAt: now
|
|
3522
|
-
};
|
|
3523
|
-
stores.aiUserMemory.set(key, memory);
|
|
3524
|
-
return Promise.resolve(memory);
|
|
3525
|
-
},
|
|
3526
|
-
setPreference(prefKey, value) {
|
|
3527
|
-
const memoryKey = getKey();
|
|
3528
|
-
const tenantId = getTenantId();
|
|
3529
|
-
const userId = requireUserId();
|
|
3530
|
-
const now = /* @__PURE__ */ new Date();
|
|
3531
|
-
const existing = stores.aiUserMemory.get(memoryKey);
|
|
3532
|
-
const memory = {
|
|
3533
|
-
id: existing?.id ?? generateId(),
|
|
3534
|
-
tenantId,
|
|
3535
|
-
userId,
|
|
3536
|
-
preferences: { ...existing?.preferences ?? {}, [prefKey]: value },
|
|
3537
|
-
facts: existing?.facts ?? [],
|
|
3538
|
-
createdAt: existing?.createdAt ?? now,
|
|
3539
|
-
updatedAt: now
|
|
3540
|
-
};
|
|
3541
|
-
stores.aiUserMemory.set(memoryKey, memory);
|
|
3542
|
-
return Promise.resolve(memory);
|
|
3543
|
-
},
|
|
3544
|
-
clear() {
|
|
3545
|
-
const key = getKey();
|
|
3546
|
-
stores.aiUserMemory.delete(key);
|
|
3547
|
-
return Promise.resolve();
|
|
3548
|
-
}
|
|
3549
|
-
};
|
|
3550
|
-
}
|
|
3551
3462
|
function createMockAIUsageMetricsRepository(stores) {
|
|
3552
3463
|
const getDateKey = (date2) => {
|
|
3553
3464
|
const tenantId = getTenantId();
|
|
@@ -4592,7 +4503,6 @@ function createEmptyStores() {
|
|
|
4592
4503
|
workflowAccessGrants: /* @__PURE__ */ new Map(),
|
|
4593
4504
|
aiConversations: /* @__PURE__ */ new Map(),
|
|
4594
4505
|
aiMessages: /* @__PURE__ */ new Map(),
|
|
4595
|
-
aiUserMemory: /* @__PURE__ */ new Map(),
|
|
4596
4506
|
aiUsageMetrics: /* @__PURE__ */ new Map(),
|
|
4597
4507
|
relationAttributes: /* @__PURE__ */ new Map()
|
|
4598
4508
|
};
|
|
@@ -5556,7 +5466,6 @@ function createMockAdapter() {
|
|
|
5556
5466
|
workflowAccessGrants: createMockWorkflowAccessGrantsRepository(stores),
|
|
5557
5467
|
// AI repositories
|
|
5558
5468
|
aiConversations: createMockAIConversationsRepository(stores),
|
|
5559
|
-
aiUserMemory: createMockAIUserMemoryRepository(stores),
|
|
5560
5469
|
aiUsageMetrics: createMockAIUsageMetricsRepository(stores),
|
|
5561
5470
|
// Relation attributes repository
|
|
5562
5471
|
relationAttributes: createMockRelationAttributesRepository(stores),
|
|
@@ -5583,7 +5492,6 @@ function createMockAdapter() {
|
|
|
5583
5492
|
stores.workflowAccessGrants.clear();
|
|
5584
5493
|
stores.aiConversations.clear();
|
|
5585
5494
|
stores.aiMessages.clear();
|
|
5586
|
-
stores.aiUserMemory.clear();
|
|
5587
5495
|
stores.aiUsageMetrics.clear();
|
|
5588
5496
|
stores.relationAttributes.clear();
|
|
5589
5497
|
}
|
|
@@ -5915,6 +5823,9 @@ var FORBIDDEN_PROPERTY_TYPES = [
|
|
|
5915
5823
|
"document",
|
|
5916
5824
|
"richtext"
|
|
5917
5825
|
];
|
|
5826
|
+
function hasOptions2(attr) {
|
|
5827
|
+
return attr.type === "select" || attr.type === "status" || attr.type === "multiselect";
|
|
5828
|
+
}
|
|
5918
5829
|
|
|
5919
5830
|
// src/builders/attribute-validators.ts
|
|
5920
5831
|
import { ICONS } from "@stndrds/constants";
|
|
@@ -6019,6 +5930,20 @@ function validateOptions(options, attributeName) {
|
|
|
6019
5930
|
validateIconName(option.icon, `option "${option.id}" of "${attributeName}"`);
|
|
6020
5931
|
}
|
|
6021
5932
|
}
|
|
5933
|
+
for (const option of options) {
|
|
5934
|
+
if (option.inverse === void 0) continue;
|
|
5935
|
+
const inverseOption = options.find((o) => o.value === option.inverse);
|
|
5936
|
+
if (!inverseOption) {
|
|
5937
|
+
throw new Error(
|
|
5938
|
+
`[AttributeBuilder] Option "${option.value}" in "${attributeName}" has inverse "${option.inverse}" which does not match any option value.`
|
|
5939
|
+
);
|
|
5940
|
+
}
|
|
5941
|
+
if (inverseOption.inverse !== option.value) {
|
|
5942
|
+
throw new Error(
|
|
5943
|
+
`[AttributeBuilder] Inverse mismatch in "${attributeName}": "${option.value}" points to "${option.inverse}", but "${option.inverse}" points to "${inverseOption.inverse ?? "(none)"}". Inverse pairs must be symmetric.`
|
|
5944
|
+
);
|
|
5945
|
+
}
|
|
5946
|
+
}
|
|
6022
5947
|
}
|
|
6023
5948
|
|
|
6024
5949
|
// src/builders/attribute-builders.ts
|
|
@@ -10303,6 +10228,7 @@ var BilateralSyncService = class extends BaseService {
|
|
|
10303
10228
|
const addedIds = newData.ids.filter((id) => !oldData.ids.includes(id));
|
|
10304
10229
|
const removedIds = oldData.ids.filter((id) => !newData.ids.includes(id));
|
|
10305
10230
|
const commonIds = newData.ids.filter((id) => oldData.ids.includes(id));
|
|
10231
|
+
const inverseMappings = this.buildInverseMappings(sourceAttr);
|
|
10306
10232
|
await Promise.all([
|
|
10307
10233
|
// Add new relations
|
|
10308
10234
|
...addedIds.map(
|
|
@@ -10312,7 +10238,9 @@ var BilateralSyncService = class extends BaseService {
|
|
|
10312
10238
|
sourceRecordId,
|
|
10313
10239
|
sourceSchema.name,
|
|
10314
10240
|
sourceAttr.name,
|
|
10315
|
-
newData.properties.get(targetId)
|
|
10241
|
+
newData.properties.get(targetId),
|
|
10242
|
+
inverseMappings,
|
|
10243
|
+
bilateral
|
|
10316
10244
|
)
|
|
10317
10245
|
),
|
|
10318
10246
|
// Remove deleted relations
|
|
@@ -10328,7 +10256,9 @@ var BilateralSyncService = class extends BaseService {
|
|
|
10328
10256
|
sourceSchema.name,
|
|
10329
10257
|
sourceAttr.name,
|
|
10330
10258
|
newData.properties.get(targetId),
|
|
10331
|
-
oldData.properties.get(targetId)
|
|
10259
|
+
oldData.properties.get(targetId),
|
|
10260
|
+
inverseMappings,
|
|
10261
|
+
bilateral
|
|
10332
10262
|
)
|
|
10333
10263
|
)
|
|
10334
10264
|
]);
|
|
@@ -10372,7 +10302,7 @@ var BilateralSyncService = class extends BaseService {
|
|
|
10372
10302
|
* Add an ID to an inverse relation (with properties).
|
|
10373
10303
|
* @private
|
|
10374
10304
|
*/
|
|
10375
|
-
async addInverseRelation(targetRecordId, inverseAttr, sourceRecordId, sourceObject, sourceAttribute, properties) {
|
|
10305
|
+
async addInverseRelation(targetRecordId, inverseAttr, sourceRecordId, sourceObject, sourceAttribute, properties, inverseMappings, bilateral) {
|
|
10376
10306
|
const targetRecord = await this.adapter.objectRecords.findById(targetRecordId);
|
|
10377
10307
|
if (!targetRecord) {
|
|
10378
10308
|
return;
|
|
@@ -10403,14 +10333,27 @@ var BilateralSyncService = class extends BaseService {
|
|
|
10403
10333
|
this.adapter
|
|
10404
10334
|
);
|
|
10405
10335
|
}
|
|
10336
|
+
if (inverseMappings && bilateral) {
|
|
10337
|
+
const invertedProps = this.invertProperties(properties, inverseMappings);
|
|
10338
|
+
const targetSchemaObj = await this.schemaService.getObjectSchemaByName(bilateral.object);
|
|
10339
|
+
if (targetSchemaObj) {
|
|
10340
|
+
await this.relationPropertiesService.syncRelationProperties(
|
|
10341
|
+
targetSchemaObj,
|
|
10342
|
+
targetRecordId,
|
|
10343
|
+
bilateral.attribute,
|
|
10344
|
+
[{ id: sourceRecordId, props: invertedProps }],
|
|
10345
|
+
this.adapter
|
|
10346
|
+
);
|
|
10347
|
+
}
|
|
10348
|
+
}
|
|
10406
10349
|
}
|
|
10407
10350
|
}
|
|
10408
10351
|
/**
|
|
10409
10352
|
* Update properties of an existing inverse relation.
|
|
10410
10353
|
* @private
|
|
10411
10354
|
*/
|
|
10412
|
-
async updateInverseRelationProperties(targetRecordId, _inverseAttr, sourceRecordId, sourceObject, sourceAttribute, newProperties, oldProperties) {
|
|
10413
|
-
if (
|
|
10355
|
+
async updateInverseRelationProperties(targetRecordId, _inverseAttr, sourceRecordId, sourceObject, sourceAttribute, newProperties, oldProperties, inverseMappings, bilateral) {
|
|
10356
|
+
if (deepEqual(newProperties, oldProperties)) {
|
|
10414
10357
|
return;
|
|
10415
10358
|
}
|
|
10416
10359
|
if (!this.adapter.relationAttributes) {
|
|
@@ -10428,12 +10371,32 @@ var BilateralSyncService = class extends BaseService {
|
|
|
10428
10371
|
[{ id: targetRecordId, props: newProperties }],
|
|
10429
10372
|
this.adapter
|
|
10430
10373
|
);
|
|
10374
|
+
if (inverseMappings && bilateral) {
|
|
10375
|
+
const invertedProps = this.invertProperties(newProperties, inverseMappings);
|
|
10376
|
+
const targetSchemaObj = await this.schemaService.getObjectSchemaByName(bilateral.object);
|
|
10377
|
+
if (targetSchemaObj) {
|
|
10378
|
+
await this.relationPropertiesService.syncRelationProperties(
|
|
10379
|
+
targetSchemaObj,
|
|
10380
|
+
targetRecordId,
|
|
10381
|
+
bilateral.attribute,
|
|
10382
|
+
[{ id: sourceRecordId, props: invertedProps }],
|
|
10383
|
+
this.adapter
|
|
10384
|
+
);
|
|
10385
|
+
}
|
|
10386
|
+
}
|
|
10431
10387
|
} else {
|
|
10432
10388
|
await this.adapter.relationAttributes.deleteBySource(
|
|
10433
10389
|
sourceObject,
|
|
10434
10390
|
sourceRecordId,
|
|
10435
10391
|
sourceAttribute
|
|
10436
10392
|
);
|
|
10393
|
+
if (bilateral) {
|
|
10394
|
+
await this.adapter.relationAttributes.deleteBySource(
|
|
10395
|
+
bilateral.object,
|
|
10396
|
+
targetRecordId,
|
|
10397
|
+
bilateral.attribute
|
|
10398
|
+
);
|
|
10399
|
+
}
|
|
10437
10400
|
}
|
|
10438
10401
|
}
|
|
10439
10402
|
/**
|
|
@@ -10465,6 +10428,54 @@ var BilateralSyncService = class extends BaseService {
|
|
|
10465
10428
|
});
|
|
10466
10429
|
await this.invalidateTargetRecordCaches(targetRecordId, targetRecord.objectId);
|
|
10467
10430
|
}
|
|
10431
|
+
/**
|
|
10432
|
+
* Build inverse value mappings from property definitions.
|
|
10433
|
+
* Scans all select/status properties for options with `inverse` field.
|
|
10434
|
+
* @returns Map<propertyName, Map<sourceValue, inverseValue>>
|
|
10435
|
+
* @private
|
|
10436
|
+
*/
|
|
10437
|
+
buildInverseMappings(sourceAttr) {
|
|
10438
|
+
const mappings = /* @__PURE__ */ new Map();
|
|
10439
|
+
const definitions = sourceAttr.properties?.definitions;
|
|
10440
|
+
if (!definitions) return mappings;
|
|
10441
|
+
for (const def of definitions) {
|
|
10442
|
+
if (!hasOptions2(def)) continue;
|
|
10443
|
+
const options = def.options;
|
|
10444
|
+
const valueMap = /* @__PURE__ */ new Map();
|
|
10445
|
+
for (const option of options) {
|
|
10446
|
+
if (option.inverse) {
|
|
10447
|
+
valueMap.set(option.value, option.inverse);
|
|
10448
|
+
}
|
|
10449
|
+
}
|
|
10450
|
+
if (valueMap.size > 0) {
|
|
10451
|
+
mappings.set(def.name, valueMap);
|
|
10452
|
+
}
|
|
10453
|
+
}
|
|
10454
|
+
return mappings;
|
|
10455
|
+
}
|
|
10456
|
+
/**
|
|
10457
|
+
* Apply inverse mappings to a set of properties.
|
|
10458
|
+
* Properties without a mapping are copied as-is.
|
|
10459
|
+
* @private
|
|
10460
|
+
*/
|
|
10461
|
+
invertProperties(props, mappings) {
|
|
10462
|
+
const result = {};
|
|
10463
|
+
for (const [key, value] of Object.entries(props)) {
|
|
10464
|
+
const valueMap = mappings.get(key);
|
|
10465
|
+
if (!valueMap) {
|
|
10466
|
+
result[key] = value;
|
|
10467
|
+
} else if (typeof value === "string") {
|
|
10468
|
+
result[key] = valueMap.get(value) ?? value;
|
|
10469
|
+
} else if (Array.isArray(value)) {
|
|
10470
|
+
result[key] = value.map(
|
|
10471
|
+
(v) => typeof v === "string" ? valueMap.get(v) ?? v : v
|
|
10472
|
+
);
|
|
10473
|
+
} else {
|
|
10474
|
+
result[key] = value;
|
|
10475
|
+
}
|
|
10476
|
+
}
|
|
10477
|
+
return result;
|
|
10478
|
+
}
|
|
10468
10479
|
/**
|
|
10469
10480
|
* Normalize a relation value to an array of IDs.
|
|
10470
10481
|
* @private
|
|
@@ -12547,7 +12558,7 @@ var RecordService = class extends BaseService {
|
|
|
12547
12558
|
}
|
|
12548
12559
|
}
|
|
12549
12560
|
}
|
|
12550
|
-
for (const [attrName, value] of Object.entries(
|
|
12561
|
+
for (const [attrName, value] of Object.entries(dataWithDefaults)) {
|
|
12551
12562
|
const attr = schema.attributes.find((a) => a.name === attrName);
|
|
12552
12563
|
if (attr?.type === "relation" && isBilateralRelation(attr)) {
|
|
12553
12564
|
await this.bilateralSyncService.syncBilateralRelation(
|
|
@@ -12759,7 +12770,7 @@ var RecordService = class extends BaseService {
|
|
|
12759
12770
|
}
|
|
12760
12771
|
}
|
|
12761
12772
|
}
|
|
12762
|
-
for (const [attrName, value] of Object.entries(
|
|
12773
|
+
for (const [attrName, value] of Object.entries(dataToUpdate)) {
|
|
12763
12774
|
const attr = schema.attributes.find((a) => a.name === attrName);
|
|
12764
12775
|
if (attr?.type === "relation" && isBilateralRelation(attr)) {
|
|
12765
12776
|
const oldValue = bilateralOldValues[attrName];
|
|
@@ -18108,6 +18119,7 @@ export {
|
|
|
18108
18119
|
RESERVED_ATTRIBUTE_NAMES,
|
|
18109
18120
|
PolicyViolationError,
|
|
18110
18121
|
FORBIDDEN_PROPERTY_TYPES,
|
|
18122
|
+
hasOptions2 as hasOptions,
|
|
18111
18123
|
SYSTEM_ATTRIBUTES,
|
|
18112
18124
|
getSystemAttributeList,
|
|
18113
18125
|
isSystemAttribute,
|
|
@@ -134,7 +134,8 @@ var optionSchema = z.object({
|
|
|
134
134
|
color: z.string().optional(),
|
|
135
135
|
icon: z.string().optional(),
|
|
136
136
|
description: z.string().optional(),
|
|
137
|
-
group: z.enum(["idle", "in_progress", "finished"]).optional()
|
|
137
|
+
group: z.enum(["idle", "in_progress", "finished"]).optional(),
|
|
138
|
+
inverse: z.string().optional()
|
|
138
139
|
});
|
|
139
140
|
var optionsArraySchema = z.array(optionSchema).min(1).refine(
|
|
140
141
|
(options) => {
|