@stndrds/schema 1.0.0-alpha.84 → 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-HTE7NOF3.mjs → chunk-HKT7LEYM.mjs} +114 -9
- package/dist/{chunk-7VNLLASJ.mjs → chunk-JUVFK6XD.mjs} +2 -1
- package/dist/{chunk-I4D33CVC.js → chunk-UGWL4KQR.js} +305 -200
- 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-BUk5CZfD.d.ts → runtime-DSh9YK1-.d.ts} +1 -1
- package/dist/{runtime-BGZqT9aX.d.mts → runtime-Dz1KblvE.d.mts} +1 -1
- 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";
|
|
@@ -5822,6 +5823,9 @@ var FORBIDDEN_PROPERTY_TYPES = [
|
|
|
5822
5823
|
"document",
|
|
5823
5824
|
"richtext"
|
|
5824
5825
|
];
|
|
5826
|
+
function hasOptions2(attr) {
|
|
5827
|
+
return attr.type === "select" || attr.type === "status" || attr.type === "multiselect";
|
|
5828
|
+
}
|
|
5825
5829
|
|
|
5826
5830
|
// src/builders/attribute-validators.ts
|
|
5827
5831
|
import { ICONS } from "@stndrds/constants";
|
|
@@ -5926,6 +5930,20 @@ function validateOptions(options, attributeName) {
|
|
|
5926
5930
|
validateIconName(option.icon, `option "${option.id}" of "${attributeName}"`);
|
|
5927
5931
|
}
|
|
5928
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
|
+
}
|
|
5929
5947
|
}
|
|
5930
5948
|
|
|
5931
5949
|
// src/builders/attribute-builders.ts
|
|
@@ -10210,6 +10228,7 @@ var BilateralSyncService = class extends BaseService {
|
|
|
10210
10228
|
const addedIds = newData.ids.filter((id) => !oldData.ids.includes(id));
|
|
10211
10229
|
const removedIds = oldData.ids.filter((id) => !newData.ids.includes(id));
|
|
10212
10230
|
const commonIds = newData.ids.filter((id) => oldData.ids.includes(id));
|
|
10231
|
+
const inverseMappings = this.buildInverseMappings(sourceAttr);
|
|
10213
10232
|
await Promise.all([
|
|
10214
10233
|
// Add new relations
|
|
10215
10234
|
...addedIds.map(
|
|
@@ -10219,7 +10238,9 @@ var BilateralSyncService = class extends BaseService {
|
|
|
10219
10238
|
sourceRecordId,
|
|
10220
10239
|
sourceSchema.name,
|
|
10221
10240
|
sourceAttr.name,
|
|
10222
|
-
newData.properties.get(targetId)
|
|
10241
|
+
newData.properties.get(targetId),
|
|
10242
|
+
inverseMappings,
|
|
10243
|
+
bilateral
|
|
10223
10244
|
)
|
|
10224
10245
|
),
|
|
10225
10246
|
// Remove deleted relations
|
|
@@ -10235,7 +10256,9 @@ var BilateralSyncService = class extends BaseService {
|
|
|
10235
10256
|
sourceSchema.name,
|
|
10236
10257
|
sourceAttr.name,
|
|
10237
10258
|
newData.properties.get(targetId),
|
|
10238
|
-
oldData.properties.get(targetId)
|
|
10259
|
+
oldData.properties.get(targetId),
|
|
10260
|
+
inverseMappings,
|
|
10261
|
+
bilateral
|
|
10239
10262
|
)
|
|
10240
10263
|
)
|
|
10241
10264
|
]);
|
|
@@ -10279,7 +10302,7 @@ var BilateralSyncService = class extends BaseService {
|
|
|
10279
10302
|
* Add an ID to an inverse relation (with properties).
|
|
10280
10303
|
* @private
|
|
10281
10304
|
*/
|
|
10282
|
-
async addInverseRelation(targetRecordId, inverseAttr, sourceRecordId, sourceObject, sourceAttribute, properties) {
|
|
10305
|
+
async addInverseRelation(targetRecordId, inverseAttr, sourceRecordId, sourceObject, sourceAttribute, properties, inverseMappings, bilateral) {
|
|
10283
10306
|
const targetRecord = await this.adapter.objectRecords.findById(targetRecordId);
|
|
10284
10307
|
if (!targetRecord) {
|
|
10285
10308
|
return;
|
|
@@ -10310,14 +10333,27 @@ var BilateralSyncService = class extends BaseService {
|
|
|
10310
10333
|
this.adapter
|
|
10311
10334
|
);
|
|
10312
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
|
+
}
|
|
10313
10349
|
}
|
|
10314
10350
|
}
|
|
10315
10351
|
/**
|
|
10316
10352
|
* Update properties of an existing inverse relation.
|
|
10317
10353
|
* @private
|
|
10318
10354
|
*/
|
|
10319
|
-
async updateInverseRelationProperties(targetRecordId, _inverseAttr, sourceRecordId, sourceObject, sourceAttribute, newProperties, oldProperties) {
|
|
10320
|
-
if (
|
|
10355
|
+
async updateInverseRelationProperties(targetRecordId, _inverseAttr, sourceRecordId, sourceObject, sourceAttribute, newProperties, oldProperties, inverseMappings, bilateral) {
|
|
10356
|
+
if (deepEqual(newProperties, oldProperties)) {
|
|
10321
10357
|
return;
|
|
10322
10358
|
}
|
|
10323
10359
|
if (!this.adapter.relationAttributes) {
|
|
@@ -10335,12 +10371,32 @@ var BilateralSyncService = class extends BaseService {
|
|
|
10335
10371
|
[{ id: targetRecordId, props: newProperties }],
|
|
10336
10372
|
this.adapter
|
|
10337
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
|
+
}
|
|
10338
10387
|
} else {
|
|
10339
10388
|
await this.adapter.relationAttributes.deleteBySource(
|
|
10340
10389
|
sourceObject,
|
|
10341
10390
|
sourceRecordId,
|
|
10342
10391
|
sourceAttribute
|
|
10343
10392
|
);
|
|
10393
|
+
if (bilateral) {
|
|
10394
|
+
await this.adapter.relationAttributes.deleteBySource(
|
|
10395
|
+
bilateral.object,
|
|
10396
|
+
targetRecordId,
|
|
10397
|
+
bilateral.attribute
|
|
10398
|
+
);
|
|
10399
|
+
}
|
|
10344
10400
|
}
|
|
10345
10401
|
}
|
|
10346
10402
|
/**
|
|
@@ -10372,6 +10428,54 @@ var BilateralSyncService = class extends BaseService {
|
|
|
10372
10428
|
});
|
|
10373
10429
|
await this.invalidateTargetRecordCaches(targetRecordId, targetRecord.objectId);
|
|
10374
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
|
+
}
|
|
10375
10479
|
/**
|
|
10376
10480
|
* Normalize a relation value to an array of IDs.
|
|
10377
10481
|
* @private
|
|
@@ -12454,7 +12558,7 @@ var RecordService = class extends BaseService {
|
|
|
12454
12558
|
}
|
|
12455
12559
|
}
|
|
12456
12560
|
}
|
|
12457
|
-
for (const [attrName, value] of Object.entries(
|
|
12561
|
+
for (const [attrName, value] of Object.entries(dataWithDefaults)) {
|
|
12458
12562
|
const attr = schema.attributes.find((a) => a.name === attrName);
|
|
12459
12563
|
if (attr?.type === "relation" && isBilateralRelation(attr)) {
|
|
12460
12564
|
await this.bilateralSyncService.syncBilateralRelation(
|
|
@@ -12666,7 +12770,7 @@ var RecordService = class extends BaseService {
|
|
|
12666
12770
|
}
|
|
12667
12771
|
}
|
|
12668
12772
|
}
|
|
12669
|
-
for (const [attrName, value] of Object.entries(
|
|
12773
|
+
for (const [attrName, value] of Object.entries(dataToUpdate)) {
|
|
12670
12774
|
const attr = schema.attributes.find((a) => a.name === attrName);
|
|
12671
12775
|
if (attr?.type === "relation" && isBilateralRelation(attr)) {
|
|
12672
12776
|
const oldValue = bilateralOldValues[attrName];
|
|
@@ -18015,6 +18119,7 @@ export {
|
|
|
18015
18119
|
RESERVED_ATTRIBUTE_NAMES,
|
|
18016
18120
|
PolicyViolationError,
|
|
18017
18121
|
FORBIDDEN_PROPERTY_TYPES,
|
|
18122
|
+
hasOptions2 as hasOptions,
|
|
18018
18123
|
SYSTEM_ATTRIBUTES,
|
|
18019
18124
|
getSystemAttributeList,
|
|
18020
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) => {
|