@coasys/ad4m-connect 0.13.0-postmessage-ws-proxy.1 → 0.13.0-postmessage-ws-proxy.2
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/core.js +193 -255
- package/dist/core.js.map +2 -2
- package/dist/index.js +211 -273
- package/dist/index.js.map +3 -3
- package/dist/web.js +206 -271
- package/dist/web.js.map +3 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -130,7 +130,7 @@ var _PostMessageWebSocket = class {
|
|
|
130
130
|
this._connectTimeout = null;
|
|
131
131
|
this._targetOrigin = targetOrigin;
|
|
132
132
|
this._messageHandler = (e7) => {
|
|
133
|
-
var _a, _b, _c, _d;
|
|
133
|
+
var _a, _b, _c, _d, _e;
|
|
134
134
|
if (e7.source !== window.parent)
|
|
135
135
|
return;
|
|
136
136
|
if (e7.origin !== this._targetOrigin)
|
|
@@ -150,13 +150,16 @@ var _PostMessageWebSocket = class {
|
|
|
150
150
|
}
|
|
151
151
|
if (msg.type === "AD4M_PROXY_WS_ERROR") {
|
|
152
152
|
this._clearConnectTimeout();
|
|
153
|
+
this.readyState = _PostMessageWebSocket.CLOSED;
|
|
154
|
+
window.removeEventListener("message", this._messageHandler);
|
|
153
155
|
(_c = this.onerror) == null ? void 0 : _c.call(this, new Event("error"));
|
|
156
|
+
(_d = this.onclose) == null ? void 0 : _d.call(this, new CloseEvent("close", { code: 1006, reason: "WebSocket error", wasClean: false }));
|
|
154
157
|
return;
|
|
155
158
|
}
|
|
156
159
|
if (msg.type === "AD4M_PROXY_WS_CLOSED") {
|
|
157
160
|
this._clearConnectTimeout();
|
|
158
161
|
this.readyState = 3;
|
|
159
|
-
(
|
|
162
|
+
(_e = this.onclose) == null ? void 0 : _e.call(
|
|
160
163
|
this,
|
|
161
164
|
new CloseEvent("close", {
|
|
162
165
|
code: typeof msg.code === "number" ? msg.code : 1e3,
|
|
@@ -1194,6 +1197,41 @@ var SHACLShape = class {
|
|
|
1194
1197
|
target: `literal:string:${JSON.stringify(prop.in)}`
|
|
1195
1198
|
});
|
|
1196
1199
|
}
|
|
1200
|
+
if (prop.relationKind) {
|
|
1201
|
+
links.push({
|
|
1202
|
+
source: propShapeId,
|
|
1203
|
+
predicate: "ad4m://relationKind",
|
|
1204
|
+
target: `literal:string:${prop.relationKind}`
|
|
1205
|
+
});
|
|
1206
|
+
}
|
|
1207
|
+
if (prop.targetClassName) {
|
|
1208
|
+
links.push({
|
|
1209
|
+
source: propShapeId,
|
|
1210
|
+
predicate: "ad4m://targetClassName",
|
|
1211
|
+
target: `literal:string:${prop.targetClassName}`
|
|
1212
|
+
});
|
|
1213
|
+
}
|
|
1214
|
+
if (prop.whereFilter !== void 0 && prop.whereFilter !== null) {
|
|
1215
|
+
links.push({
|
|
1216
|
+
source: propShapeId,
|
|
1217
|
+
predicate: "ad4m://whereFilter",
|
|
1218
|
+
target: `literal:string:${JSON.stringify(prop.whereFilter)}`
|
|
1219
|
+
});
|
|
1220
|
+
}
|
|
1221
|
+
if (prop.wherePredicates && Object.keys(prop.wherePredicates).length > 0) {
|
|
1222
|
+
links.push({
|
|
1223
|
+
source: propShapeId,
|
|
1224
|
+
predicate: "ad4m://wherePredicates",
|
|
1225
|
+
target: `literal:string:${JSON.stringify(prop.wherePredicates)}`
|
|
1226
|
+
});
|
|
1227
|
+
}
|
|
1228
|
+
if (prop.filter !== void 0) {
|
|
1229
|
+
links.push({
|
|
1230
|
+
source: propShapeId,
|
|
1231
|
+
predicate: "ad4m://filter",
|
|
1232
|
+
target: `literal:${prop.filter}`
|
|
1233
|
+
});
|
|
1234
|
+
}
|
|
1197
1235
|
}
|
|
1198
1236
|
return links;
|
|
1199
1237
|
}
|
|
@@ -1342,6 +1380,40 @@ var SHACLShape = class {
|
|
|
1342
1380
|
} catch (e7) {
|
|
1343
1381
|
}
|
|
1344
1382
|
}
|
|
1383
|
+
const relationKindLink = links.find((l5) => l5.source === propShapeId && l5.predicate === "ad4m://relationKind");
|
|
1384
|
+
if (relationKindLink) {
|
|
1385
|
+
const val = relationKindLink.target.replace(/^literal:\/\/string:|^literal:string:/, "");
|
|
1386
|
+
if (val === "hasMany" || val === "hasOne" || val === "belongsToOne" || val === "belongsToMany") {
|
|
1387
|
+
prop.relationKind = val;
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
const targetClassNameLink = links.find((l5) => l5.source === propShapeId && l5.predicate === "ad4m://targetClassName");
|
|
1391
|
+
if (targetClassNameLink) {
|
|
1392
|
+
prop.targetClassName = targetClassNameLink.target.replace(/^literal:\/\/string:|^literal:string:/, "");
|
|
1393
|
+
}
|
|
1394
|
+
const whereFilterLink = links.find((l5) => l5.source === propShapeId && l5.predicate === "ad4m://whereFilter");
|
|
1395
|
+
if (whereFilterLink) {
|
|
1396
|
+
try {
|
|
1397
|
+
const jsonStr = whereFilterLink.target.replace(/^literal:\/\/string:|^literal:string:/, "");
|
|
1398
|
+
prop.whereFilter = JSON.parse(jsonStr);
|
|
1399
|
+
} catch (e7) {
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
const wherePredicatesLink = links.find((l5) => l5.source === propShapeId && l5.predicate === "ad4m://wherePredicates");
|
|
1403
|
+
if (wherePredicatesLink) {
|
|
1404
|
+
try {
|
|
1405
|
+
const jsonStr = wherePredicatesLink.target.replace(/^literal:\/\/string:|^literal:string:/, "");
|
|
1406
|
+
prop.wherePredicates = JSON.parse(jsonStr);
|
|
1407
|
+
} catch (e7) {
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
const filterLink = links.find((l5) => l5.source === propShapeId && l5.predicate === "ad4m://filter");
|
|
1411
|
+
if (filterLink) {
|
|
1412
|
+
let val = filterLink.target.replace(/^literal:\/\/|^literal:/, "");
|
|
1413
|
+
if (val.startsWith("boolean:"))
|
|
1414
|
+
val = val.substring(8);
|
|
1415
|
+
prop.filter = val === "true";
|
|
1416
|
+
}
|
|
1345
1417
|
shape.addProperty(prop);
|
|
1346
1418
|
}
|
|
1347
1419
|
return shape;
|
|
@@ -1371,7 +1443,12 @@ var SHACLShape = class {
|
|
|
1371
1443
|
getter: p2.getter,
|
|
1372
1444
|
conformance_conditions: p2.conformanceConditions,
|
|
1373
1445
|
class: p2.class,
|
|
1374
|
-
in: p2.in
|
|
1446
|
+
in: p2.in,
|
|
1447
|
+
relation_kind: p2.relationKind,
|
|
1448
|
+
target_class_name: p2.targetClassName,
|
|
1449
|
+
where_filter: p2.whereFilter,
|
|
1450
|
+
where_predicates: p2.wherePredicates,
|
|
1451
|
+
filter: p2.filter
|
|
1375
1452
|
})),
|
|
1376
1453
|
constructor_actions: this.constructor_actions,
|
|
1377
1454
|
destructor_actions: this.destructor_actions
|
|
@@ -1400,7 +1477,12 @@ var SHACLShape = class {
|
|
|
1400
1477
|
getter: p2.getter,
|
|
1401
1478
|
conformanceConditions: p2.conformance_conditions,
|
|
1402
1479
|
class: p2.class,
|
|
1403
|
-
in: p2.in
|
|
1480
|
+
in: p2.in,
|
|
1481
|
+
relationKind: p2.relation_kind,
|
|
1482
|
+
targetClassName: p2.target_class_name,
|
|
1483
|
+
whereFilter: p2.where_filter,
|
|
1484
|
+
wherePredicates: p2.where_predicates,
|
|
1485
|
+
filter: p2.filter
|
|
1404
1486
|
});
|
|
1405
1487
|
}
|
|
1406
1488
|
if (json.constructor_actions) {
|
|
@@ -1417,114 +1499,9 @@ var SHACLShape = class {
|
|
|
1417
1499
|
return shape;
|
|
1418
1500
|
}
|
|
1419
1501
|
};
|
|
1420
|
-
function formatList(list) {
|
|
1421
|
-
if (!list?.length) {
|
|
1422
|
-
return "";
|
|
1423
|
-
}
|
|
1424
|
-
if (list.length === 1) {
|
|
1425
|
-
return list.toString();
|
|
1426
|
-
}
|
|
1427
|
-
if (list.length === 2) {
|
|
1428
|
-
return list.join(" and ");
|
|
1429
|
-
}
|
|
1430
|
-
return list.slice(0, -1).join(", ") + ", and " + list.slice(-1);
|
|
1431
|
-
}
|
|
1432
|
-
function capSentence(cap) {
|
|
1433
|
-
const can = cap.can.includes("*") ? ["READ", "WRITE", "UPDATE"] : cap.can;
|
|
1434
|
-
const domain = cap.with.domain === "*" ? "" : cap.with.domain;
|
|
1435
|
-
const pointers = cap.with.pointers.includes("*") ? ["all AD4M data"] : cap.with.pointers;
|
|
1436
|
-
return `${formatList(can)} your ${domain} actions, with access to ${formatList(pointers)}`;
|
|
1437
|
-
}
|
|
1438
|
-
function escapeQueryString(value) {
|
|
1439
|
-
return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
|
|
1440
|
-
}
|
|
1441
|
-
function buildWhereCondition(predicate, condition, opts) {
|
|
1442
|
-
const escapedPredicate = escapeQueryString(predicate);
|
|
1443
|
-
const isLiteral = !opts?.resolveLanguage || opts.resolveLanguage === "literal";
|
|
1444
|
-
const varSuffix = opts?.varIndex ?? 0;
|
|
1445
|
-
function formatValue(v2) {
|
|
1446
|
-
if (typeof v2 === "string") {
|
|
1447
|
-
return isLiteral ? `<literal:string:${escapeQueryString(v2)}>` : `<${escapeQueryString(v2)}>`;
|
|
1448
|
-
}
|
|
1449
|
-
return `<literal:string:${v2}>`;
|
|
1450
|
-
}
|
|
1451
|
-
function formatLiteralFilter(varName, v2) {
|
|
1452
|
-
const raw = escapeQueryString(String(v2));
|
|
1453
|
-
const encoded = encodeURIComponent(String(v2)).replace(/!/g, "%21").replace(/'/g, "%27").replace(/\(/g, "%28").replace(/\)/g, "%29").replace(/\*/g, "%2A");
|
|
1454
|
-
if (typeof v2 === "string") {
|
|
1455
|
-
return `FILTER(STR(${varName}) = "${raw}" || STR(${varName}) = "literal:string:${encoded}")`;
|
|
1456
|
-
} else if (typeof v2 === "number") {
|
|
1457
|
-
return `FILTER(STR(${varName}) = "${v2}" || STR(${varName}) = "literal:number:${v2}")`;
|
|
1458
|
-
} else if (typeof v2 === "boolean") {
|
|
1459
|
-
return `FILTER(STR(${varName}) = "${v2}" || STR(${varName}) = "literal:boolean:${v2}")`;
|
|
1460
|
-
}
|
|
1461
|
-
return `FILTER(STR(${varName}) = "${raw}")`;
|
|
1462
|
-
}
|
|
1463
|
-
if (Array.isArray(condition)) {
|
|
1464
|
-
if (isLiteral) {
|
|
1465
|
-
const varName = `?_wc${varSuffix}`;
|
|
1466
|
-
const inValues = condition.flatMap((v2) => {
|
|
1467
|
-
const raw = escapeQueryString(String(v2));
|
|
1468
|
-
const encoded = encodeURIComponent(String(v2)).replace(/!/g, "%21").replace(/'/g, "%27").replace(/\(/g, "%28").replace(/\)/g, "%29").replace(/\*/g, "%2A");
|
|
1469
|
-
return [`"${raw}"`, `"literal:string:${encoded}"`];
|
|
1470
|
-
}).join(", ");
|
|
1471
|
-
return `?target <${escapedPredicate}> ${varName} . FILTER(STR(${varName}) IN (${inValues}))`;
|
|
1472
|
-
}
|
|
1473
|
-
const formattedValues = condition.map(formatValue).join(", ");
|
|
1474
|
-
return `FILTER EXISTS { ?target <${escapedPredicate}> ?_val . FILTER(?_val IN (${formattedValues})) }`;
|
|
1475
|
-
} else if (typeof condition === "object" && condition !== null) {
|
|
1476
|
-
const ops = condition;
|
|
1477
|
-
const parts = [];
|
|
1478
|
-
if (ops.not !== void 0) {
|
|
1479
|
-
if (Array.isArray(ops.not)) {
|
|
1480
|
-
const formattedValues = ops.not.map((v2) => formatValue(v2)).join(", ");
|
|
1481
|
-
parts.push(`FILTER NOT EXISTS { ?target <${escapedPredicate}> ?_nval . FILTER(?_nval IN (${formattedValues})) }`);
|
|
1482
|
-
} else {
|
|
1483
|
-
parts.push(`FILTER NOT EXISTS { ?target <${escapedPredicate}> ${formatValue(ops.not)} }`);
|
|
1484
|
-
}
|
|
1485
|
-
}
|
|
1486
|
-
const hasComparisonOps = ops.gt !== void 0 || ops.gte !== void 0 || ops.lt !== void 0 || ops.lte !== void 0 || ops.between !== void 0 || ops.contains !== void 0;
|
|
1487
|
-
if (hasComparisonOps) {
|
|
1488
|
-
parts.push(`FILTER EXISTS { ?target <${escapedPredicate}> ?_cmp }`);
|
|
1489
|
-
}
|
|
1490
|
-
return parts.join(" ");
|
|
1491
|
-
} else {
|
|
1492
|
-
if (isLiteral) {
|
|
1493
|
-
const varName = `?_wc${varSuffix}`;
|
|
1494
|
-
return `?target <${escapedPredicate}> ${varName} . ${formatLiteralFilter(varName, condition)}`;
|
|
1495
|
-
}
|
|
1496
|
-
return `?target <${escapedPredicate}> ${formatValue(condition)} .`;
|
|
1497
|
-
}
|
|
1498
|
-
}
|
|
1499
|
-
function compileWhereClause(where, metadata) {
|
|
1500
|
-
const conditions = [];
|
|
1501
|
-
for (const [propertyName, condition] of Object.entries(where)) {
|
|
1502
|
-
if (["id", "author", "timestamp"].includes(propertyName))
|
|
1503
|
-
continue;
|
|
1504
|
-
let predicate;
|
|
1505
|
-
let resolveLanguage;
|
|
1506
|
-
if (metadata) {
|
|
1507
|
-
const propMeta = metadata.properties[propertyName];
|
|
1508
|
-
if (propMeta) {
|
|
1509
|
-
predicate = propMeta.predicate;
|
|
1510
|
-
resolveLanguage = propMeta.resolveLanguage;
|
|
1511
|
-
} else {
|
|
1512
|
-
predicate = propertyName;
|
|
1513
|
-
}
|
|
1514
|
-
} else {
|
|
1515
|
-
predicate = propertyName;
|
|
1516
|
-
}
|
|
1517
|
-
const cond = buildWhereCondition(predicate, condition, { resolveLanguage, varIndex: conditions.length });
|
|
1518
|
-
if (cond) {
|
|
1519
|
-
conditions.push(cond);
|
|
1520
|
-
}
|
|
1521
|
-
}
|
|
1522
|
-
return conditions;
|
|
1523
|
-
}
|
|
1524
1502
|
function buildSHACL(subjectName, target, properties, allRelationsMeta, conformanceFilterFn) {
|
|
1525
1503
|
const obj = target.prototype;
|
|
1526
1504
|
let namespace = "ad4m://";
|
|
1527
|
-
const relations = Object.fromEntries(Object.entries(allRelationsMeta).filter(([, r4]) => r4.kind === "hasMany" || r4.kind === "belongsToMany"));
|
|
1528
1505
|
if (Object.keys(properties).length > 0) {
|
|
1529
1506
|
const firstProp = properties[Object.keys(properties)[0]];
|
|
1530
1507
|
if (firstProp.through) {
|
|
@@ -1533,8 +1510,8 @@ function buildSHACL(subjectName, target, properties, allRelationsMeta, conforman
|
|
|
1533
1510
|
namespace = match[1];
|
|
1534
1511
|
}
|
|
1535
1512
|
}
|
|
1536
|
-
} else if (Object.keys(
|
|
1537
|
-
const firstRel =
|
|
1513
|
+
} else if (Object.keys(allRelationsMeta).length > 0) {
|
|
1514
|
+
const firstRel = allRelationsMeta[Object.keys(allRelationsMeta)[0]];
|
|
1538
1515
|
if (firstRel.predicate) {
|
|
1539
1516
|
const match = firstRel.predicate.match(/^([^:]+:\/\/)/);
|
|
1540
1517
|
if (match) {
|
|
@@ -1596,6 +1573,9 @@ function buildSHACL(subjectName, target, properties, allRelationsMeta, conforman
|
|
|
1596
1573
|
if (propMeta.resolveLanguage) {
|
|
1597
1574
|
propShape.resolveLanguage = propMeta.resolveLanguage;
|
|
1598
1575
|
}
|
|
1576
|
+
if (propMeta.getter) {
|
|
1577
|
+
propShape.getter = propMeta.getter;
|
|
1578
|
+
}
|
|
1599
1579
|
if (propMeta.prologSetter) {
|
|
1600
1580
|
console.warn(`[SHACL Generation] Custom Prolog setter for property '${propName}' in class '${subjectName}' is not yet supported. The property will be created without setter actions. Consider using standard writable properties or provide explicit SHACL JSON.`);
|
|
1601
1581
|
} else if (propMeta.writable && propMeta.through) {
|
|
@@ -1627,46 +1607,47 @@ function buildSHACL(subjectName, target, properties, allRelationsMeta, conforman
|
|
|
1627
1607
|
}
|
|
1628
1608
|
shape.addProperty(propShape);
|
|
1629
1609
|
}
|
|
1630
|
-
for (const relName in
|
|
1631
|
-
const relMeta =
|
|
1632
|
-
if (!relMeta.predicate)
|
|
1610
|
+
for (const relName in allRelationsMeta) {
|
|
1611
|
+
const relMeta = allRelationsMeta[relName];
|
|
1612
|
+
if (!relMeta.predicate && !relMeta.getter)
|
|
1633
1613
|
continue;
|
|
1614
|
+
const synthesizedPath = relMeta.predicate || `ad4m://getter/${subjectName}/${relName}`;
|
|
1634
1615
|
const relShape = {
|
|
1635
1616
|
name: relName,
|
|
1636
|
-
path:
|
|
1617
|
+
path: synthesizedPath
|
|
1637
1618
|
};
|
|
1638
1619
|
relShape.nodeKind = "IRI";
|
|
1620
|
+
relShape.relationKind = relMeta.kind;
|
|
1621
|
+
if (relMeta.kind === "hasOne" || relMeta.kind === "belongsToOne") {
|
|
1622
|
+
relShape.maxCount = 1;
|
|
1623
|
+
} else if (relMeta.maxCount !== void 0) {
|
|
1624
|
+
relShape.maxCount = relMeta.maxCount;
|
|
1625
|
+
}
|
|
1626
|
+
if (relMeta.filter === false) {
|
|
1627
|
+
relShape.filter = false;
|
|
1628
|
+
}
|
|
1639
1629
|
if (relMeta.local !== void 0) {
|
|
1640
1630
|
relShape.local = relMeta.local;
|
|
1641
1631
|
}
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1632
|
+
if (relMeta.predicate) {
|
|
1633
|
+
relShape.adder = [{
|
|
1634
|
+
action: "addLink",
|
|
1635
|
+
source: "this",
|
|
1636
|
+
predicate: relMeta.predicate,
|
|
1637
|
+
target: "value",
|
|
1638
|
+
...relMeta.local && { local: true }
|
|
1639
|
+
}];
|
|
1640
|
+
relShape.remover = [{
|
|
1641
|
+
action: "removeLink",
|
|
1642
|
+
source: "this",
|
|
1643
|
+
predicate: relMeta.predicate,
|
|
1644
|
+
target: "value",
|
|
1645
|
+
...relMeta.local && { local: true }
|
|
1646
|
+
}];
|
|
1647
|
+
}
|
|
1656
1648
|
if (relMeta.getter) {
|
|
1657
1649
|
relShape.getter = relMeta.getter;
|
|
1658
|
-
} else if (relMeta.
|
|
1659
|
-
try {
|
|
1660
|
-
const TargetClass = relMeta.target?.();
|
|
1661
|
-
const targetMetadata = TargetClass ? TargetClass.getModelMetadata?.() ?? null : null;
|
|
1662
|
-
const conditions = compileWhereClause(relMeta.where, targetMetadata);
|
|
1663
|
-
if (conditions.length > 0) {
|
|
1664
|
-
const escapedPredicate = escapeQueryString(relMeta.predicate);
|
|
1665
|
-
relShape.getter = `SELECT ?target WHERE { <Base> <${escapedPredicate}> ?target . ${conditions.join(" ")} }`;
|
|
1666
|
-
}
|
|
1667
|
-
} catch (e7) {
|
|
1668
|
-
}
|
|
1669
|
-
} else if (relMeta.target && relMeta.filter !== false) {
|
|
1650
|
+
} else if (relMeta.target && relMeta.filter !== false && relMeta.kind !== "belongsToOne" && relMeta.kind !== "belongsToMany") {
|
|
1670
1651
|
const targetThunk = relMeta.target;
|
|
1671
1652
|
const predicate = relMeta.predicate;
|
|
1672
1653
|
let resolved = false;
|
|
@@ -1718,6 +1699,37 @@ function buildSHACL(subjectName, target, properties, allRelationsMeta, conforman
|
|
|
1718
1699
|
if (targetSHACL?.shape?.nodeShapeUri) {
|
|
1719
1700
|
relShape.class = targetSHACL.shape.nodeShapeUri;
|
|
1720
1701
|
}
|
|
1702
|
+
if (targetSHACL?.name) {
|
|
1703
|
+
relShape.targetClassName = targetSHACL.name;
|
|
1704
|
+
} else {
|
|
1705
|
+
const targetProto = TargetClass.prototype;
|
|
1706
|
+
if (targetProto?.className) {
|
|
1707
|
+
relShape.targetClassName = targetProto.className;
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1710
|
+
} catch (e7) {
|
|
1711
|
+
console.warn(`[shacl-gen] Failed to resolve target class for relation "${subjectName}.${relName}": ${e7 instanceof Error ? e7.message : String(e7)}`);
|
|
1712
|
+
}
|
|
1713
|
+
}
|
|
1714
|
+
if (relMeta.where) {
|
|
1715
|
+
relShape.whereFilter = relMeta.where;
|
|
1716
|
+
try {
|
|
1717
|
+
const TargetClass = relMeta.target?.();
|
|
1718
|
+
const targetMetadata = TargetClass ? TargetClass.getModelMetadata?.() ?? null : null;
|
|
1719
|
+
if (targetMetadata?.properties) {
|
|
1720
|
+
const predicates = {};
|
|
1721
|
+
for (const propName of Object.keys(relMeta.where)) {
|
|
1722
|
+
if (["id", "author", "timestamp"].includes(propName))
|
|
1723
|
+
continue;
|
|
1724
|
+
const propMeta = targetMetadata.properties[propName];
|
|
1725
|
+
if (propMeta?.predicate) {
|
|
1726
|
+
predicates[propName] = propMeta.predicate;
|
|
1727
|
+
}
|
|
1728
|
+
}
|
|
1729
|
+
if (Object.keys(predicates).length > 0) {
|
|
1730
|
+
relShape.wherePredicates = predicates;
|
|
1731
|
+
}
|
|
1732
|
+
}
|
|
1721
1733
|
} catch (e7) {
|
|
1722
1734
|
}
|
|
1723
1735
|
}
|
|
@@ -1730,6 +1742,27 @@ function buildSHACL(subjectName, target, properties, allRelationsMeta, conforman
|
|
|
1730
1742
|
name: subjectName
|
|
1731
1743
|
};
|
|
1732
1744
|
}
|
|
1745
|
+
function formatList(list) {
|
|
1746
|
+
if (!list?.length) {
|
|
1747
|
+
return "";
|
|
1748
|
+
}
|
|
1749
|
+
if (list.length === 1) {
|
|
1750
|
+
return list.toString();
|
|
1751
|
+
}
|
|
1752
|
+
if (list.length === 2) {
|
|
1753
|
+
return list.join(" and ");
|
|
1754
|
+
}
|
|
1755
|
+
return list.slice(0, -1).join(", ") + ", and " + list.slice(-1);
|
|
1756
|
+
}
|
|
1757
|
+
function capSentence(cap) {
|
|
1758
|
+
const can = cap.can.includes("*") ? ["READ", "WRITE", "UPDATE"] : cap.can;
|
|
1759
|
+
const domain = cap.with.domain === "*" ? "" : cap.with.domain;
|
|
1760
|
+
const pointers = cap.with.pointers.includes("*") ? ["all AD4M data"] : cap.with.pointers;
|
|
1761
|
+
return `${formatList(can)} your ${domain} actions, with access to ${formatList(pointers)}`;
|
|
1762
|
+
}
|
|
1763
|
+
function escapeQueryString(value) {
|
|
1764
|
+
return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
|
|
1765
|
+
}
|
|
1733
1766
|
var propertyRegistry = /* @__PURE__ */ new WeakMap();
|
|
1734
1767
|
var relationRegistry = /* @__PURE__ */ new WeakMap();
|
|
1735
1768
|
var propertiesMetadataCache = /* @__PURE__ */ new WeakMap();
|
|
@@ -2356,14 +2389,14 @@ var PerspectiveProxy = class {
|
|
|
2356
2389
|
setCachedResult(__classPrivateFieldGet$a(this, _PerspectiveProxy_handle, "f").uuid, query, result);
|
|
2357
2390
|
return result;
|
|
2358
2391
|
}
|
|
2359
|
-
async modelQuery(className, queryJson
|
|
2360
|
-
return await __classPrivateFieldGet$a(this, _PerspectiveProxy_client, "f").modelQuery(__classPrivateFieldGet$a(this, _PerspectiveProxy_handle, "f").uuid, className, queryJson
|
|
2392
|
+
async modelQuery(className, queryJson) {
|
|
2393
|
+
return await __classPrivateFieldGet$a(this, _PerspectiveProxy_client, "f").modelQuery(__classPrivateFieldGet$a(this, _PerspectiveProxy_handle, "f").uuid, className, queryJson);
|
|
2361
2394
|
}
|
|
2362
|
-
async evaluateGetters(className, instanceIds,
|
|
2363
|
-
return await __classPrivateFieldGet$a(this, _PerspectiveProxy_client, "f").evaluateGetters(__classPrivateFieldGet$a(this, _PerspectiveProxy_handle, "f").uuid, className, instanceIds,
|
|
2395
|
+
async evaluateGetters(className, instanceIds, propertyNames) {
|
|
2396
|
+
return await __classPrivateFieldGet$a(this, _PerspectiveProxy_client, "f").evaluateGetters(__classPrivateFieldGet$a(this, _PerspectiveProxy_handle, "f").uuid, className, instanceIds, propertyNames);
|
|
2364
2397
|
}
|
|
2365
|
-
async modelSubscribe(className, queryJson
|
|
2366
|
-
return await __classPrivateFieldGet$a(this, _PerspectiveProxy_client, "f").modelSubscribe(__classPrivateFieldGet$a(this, _PerspectiveProxy_handle, "f").uuid, className, queryJson
|
|
2398
|
+
async modelSubscribe(className, queryJson) {
|
|
2399
|
+
return await __classPrivateFieldGet$a(this, _PerspectiveProxy_client, "f").modelSubscribe(__classPrivateFieldGet$a(this, _PerspectiveProxy_handle, "f").uuid, className, queryJson);
|
|
2367
2400
|
}
|
|
2368
2401
|
async add(link, status = "shared", batchId) {
|
|
2369
2402
|
const result = await __classPrivateFieldGet$a(this, _PerspectiveProxy_client, "f").addLink(__classPrivateFieldGet$a(this, _PerspectiveProxy_handle, "f").uuid, link, status, batchId);
|
|
@@ -3410,22 +3443,21 @@ var PerspectiveClient = class {
|
|
|
3410
3443
|
}
|
|
3411
3444
|
return __classPrivateFieldGet$9(this, _PerspectiveClient_apiClient, "f").call("perspective.disposeQuery", { uuid, subscriptionId });
|
|
3412
3445
|
}
|
|
3413
|
-
async modelQuery(uuid, className, queryJson
|
|
3414
|
-
const resultJson = await __classPrivateFieldGet$9(this, _PerspectiveClient_apiClient, "f").call("perspective.modelQuery", { uuid, class_name: className, query_json: queryJson
|
|
3446
|
+
async modelQuery(uuid, className, queryJson) {
|
|
3447
|
+
const resultJson = await __classPrivateFieldGet$9(this, _PerspectiveClient_apiClient, "f").call("perspective.modelQuery", { uuid, class_name: className, query_json: queryJson });
|
|
3415
3448
|
return JSON.parse(resultJson);
|
|
3416
3449
|
}
|
|
3417
|
-
async evaluateGetters(uuid, className, instanceIds,
|
|
3450
|
+
async evaluateGetters(uuid, className, instanceIds, propertyNames) {
|
|
3418
3451
|
const resultJson = await __classPrivateFieldGet$9(this, _PerspectiveClient_apiClient, "f").call("perspective.evaluateGetters", {
|
|
3419
3452
|
uuid,
|
|
3420
3453
|
class_name: className,
|
|
3421
3454
|
instance_ids: instanceIds,
|
|
3422
|
-
shape_json: shapeJson,
|
|
3423
3455
|
...propertyNames && { property_names: propertyNames }
|
|
3424
3456
|
});
|
|
3425
3457
|
return JSON.parse(resultJson);
|
|
3426
3458
|
}
|
|
3427
|
-
async modelSubscribe(uuid, className, queryJson
|
|
3428
|
-
const response = await __classPrivateFieldGet$9(this, _PerspectiveClient_apiClient, "f").call("perspective.modelSubscribe", { uuid, class_name: className, query_json: queryJson
|
|
3459
|
+
async modelSubscribe(uuid, className, queryJson) {
|
|
3460
|
+
const response = await __classPrivateFieldGet$9(this, _PerspectiveClient_apiClient, "f").call("perspective.modelSubscribe", { uuid, class_name: className, query_json: queryJson });
|
|
3429
3461
|
return {
|
|
3430
3462
|
subscriptionId: response.subscription_id,
|
|
3431
3463
|
result: JSON.parse(response.result)
|
|
@@ -9530,9 +9562,6 @@ var ModelQueryBuilder = class {
|
|
|
9530
9562
|
this.modelClassName = className;
|
|
9531
9563
|
return this;
|
|
9532
9564
|
}
|
|
9533
|
-
engine(_eng) {
|
|
9534
|
-
return this;
|
|
9535
|
-
}
|
|
9536
9565
|
async get() {
|
|
9537
9566
|
return await this.executeSparqlQuery();
|
|
9538
9567
|
}
|
|
@@ -9553,8 +9582,8 @@ var ModelQueryBuilder = class {
|
|
|
9553
9582
|
async subscribe(callback) {
|
|
9554
9583
|
this.dispose();
|
|
9555
9584
|
const ctor = this.ctor;
|
|
9556
|
-
const { className, queryJson
|
|
9557
|
-
const { subscriptionId, result: initialModelResult } = await this.perspective.modelSubscribe(className, queryJson
|
|
9585
|
+
const { className, queryJson } = ctor.prepareModelQueryParams(this.queryParams, this.modelClassName);
|
|
9586
|
+
const { subscriptionId, result: initialModelResult } = await this.perspective.modelSubscribe(className, queryJson);
|
|
9558
9587
|
const parseResults = (raw) => {
|
|
9559
9588
|
return ctor.parseModelResult(this.perspective, raw, this.queryParams.include, this.queryParams.properties);
|
|
9560
9589
|
};
|
|
@@ -9651,8 +9680,8 @@ var ModelQueryBuilder = class {
|
|
|
9651
9680
|
async countSubscribe(callback) {
|
|
9652
9681
|
this.dispose();
|
|
9653
9682
|
const countParams = { ...this.queryParams, limit: 0 };
|
|
9654
|
-
const { className, queryJson
|
|
9655
|
-
const { subscriptionId, result: initialModelResult } = await this.perspective.modelSubscribe(className, queryJson
|
|
9683
|
+
const { className, queryJson } = this.ctor.prepareModelQueryParams(countParams, this.modelClassName);
|
|
9684
|
+
const { subscriptionId, result: initialModelResult } = await this.perspective.modelSubscribe(className, queryJson);
|
|
9656
9685
|
const parseCount = (raw) => {
|
|
9657
9686
|
const data = typeof raw === "string" ? JSON.parse(raw) : raw;
|
|
9658
9687
|
return data.totalCount ?? 0;
|
|
@@ -9727,8 +9756,8 @@ var ModelQueryBuilder = class {
|
|
|
9727
9756
|
const subscriptionParams = { ...this.queryParams || {} };
|
|
9728
9757
|
delete subscriptionParams.limit;
|
|
9729
9758
|
delete subscriptionParams.offset;
|
|
9730
|
-
const { className, queryJson
|
|
9731
|
-
const { subscriptionId } = await this.perspective.modelSubscribe(className, queryJson
|
|
9759
|
+
const { className, queryJson } = ctor.prepareModelQueryParams(subscriptionParams, this.modelClassName);
|
|
9760
|
+
const { subscriptionId } = await this.perspective.modelSubscribe(className, queryJson);
|
|
9732
9761
|
const paginatedQuery = {
|
|
9733
9762
|
...this.queryParams || {},
|
|
9734
9763
|
limit: pageSize,
|
|
@@ -9820,34 +9849,6 @@ function defaultFileDecode(resolved) {
|
|
|
9820
9849
|
}
|
|
9821
9850
|
return resolved;
|
|
9822
9851
|
}
|
|
9823
|
-
function enrichShapeForIncludes(metadata, include, allRelMeta) {
|
|
9824
|
-
for (const [relName, includeVal] of Object.entries(include)) {
|
|
9825
|
-
if (!includeVal)
|
|
9826
|
-
continue;
|
|
9827
|
-
const meta = allRelMeta[relName];
|
|
9828
|
-
if (!meta?.target)
|
|
9829
|
-
continue;
|
|
9830
|
-
const TargetClass = meta.target();
|
|
9831
|
-
const targetMeta = JSON.parse(JSON.stringify(TargetClass.getModelMetadata()));
|
|
9832
|
-
if (!metadata.relations[relName]) {
|
|
9833
|
-
metadata.relations[relName] = {
|
|
9834
|
-
name: relName,
|
|
9835
|
-
predicate: meta.predicate,
|
|
9836
|
-
direction: meta.kind === "belongsToMany" || meta.kind === "belongsToOne" ? "reverse" : "forward"
|
|
9837
|
-
};
|
|
9838
|
-
}
|
|
9839
|
-
const rel = metadata.relations[relName];
|
|
9840
|
-
rel.kind = meta.kind;
|
|
9841
|
-
rel.maxCount = meta.maxCount;
|
|
9842
|
-
rel.targetShape = targetMeta;
|
|
9843
|
-
rel.targetClassName = targetMeta.className;
|
|
9844
|
-
const nested = typeof includeVal === "object" && includeVal !== null ? includeVal.include : void 0;
|
|
9845
|
-
if (nested) {
|
|
9846
|
-
const targetRelMeta = getRelationsMetadata(TargetClass);
|
|
9847
|
-
enrichShapeForIncludes(targetMeta, nested, targetRelMeta);
|
|
9848
|
-
}
|
|
9849
|
-
}
|
|
9850
|
-
}
|
|
9851
9852
|
function jsonToModelInstance(ModelClass, perspective, json, include, properties) {
|
|
9852
9853
|
const instance = new ModelClass(perspective, json.id || json.baseExpression);
|
|
9853
9854
|
if (properties) {
|
|
@@ -10230,12 +10231,12 @@ var Ad4mModel = class {
|
|
|
10230
10231
|
const allRelMeta = getRelationsMetadata(this);
|
|
10231
10232
|
for (const [, proj] of Object.entries(projections)) {
|
|
10232
10233
|
const relMeta = allRelMeta[proj.from];
|
|
10233
|
-
if (!proj.
|
|
10234
|
+
if (!proj.targetClassName && relMeta?.target) {
|
|
10234
10235
|
try {
|
|
10235
10236
|
const TargetClass = relMeta.target();
|
|
10236
10237
|
const targetMeta = TargetClass.getModelMetadata?.();
|
|
10237
|
-
if (targetMeta) {
|
|
10238
|
-
proj.
|
|
10238
|
+
if (targetMeta?.className) {
|
|
10239
|
+
proj.targetClassName = targetMeta.className;
|
|
10239
10240
|
}
|
|
10240
10241
|
} catch (e7) {
|
|
10241
10242
|
console.debug(`prepareModelQueryParams: target class unavailable for projection:`, e7);
|
|
@@ -10257,56 +10258,9 @@ var Ad4mModel = class {
|
|
|
10257
10258
|
if (query.count !== void 0)
|
|
10258
10259
|
queryInput.count = query.count;
|
|
10259
10260
|
queryInput.deepQuery = query.deepQuery ?? true;
|
|
10260
|
-
if (queryInput.include) {
|
|
10261
|
-
const allRelMeta = getRelationsMetadata(this);
|
|
10262
|
-
enrichShapeForIncludes(metadata, queryInput.include, allRelMeta);
|
|
10263
|
-
}
|
|
10264
|
-
{
|
|
10265
|
-
const allRelMeta = getRelationsMetadata(this);
|
|
10266
|
-
for (const [relName, relMeta] of Object.entries(metadata.relations)) {
|
|
10267
|
-
const rel = relMeta;
|
|
10268
|
-
if (rel.getter || rel.direction === "reverse" || rel.filter === false)
|
|
10269
|
-
continue;
|
|
10270
|
-
const meta = allRelMeta[relName];
|
|
10271
|
-
if (!meta?.target)
|
|
10272
|
-
continue;
|
|
10273
|
-
try {
|
|
10274
|
-
const TargetClass = meta.target();
|
|
10275
|
-
const filter = buildConformanceFilter(meta.predicate, TargetClass);
|
|
10276
|
-
if (filter) {
|
|
10277
|
-
rel.getter = filter.getter;
|
|
10278
|
-
}
|
|
10279
|
-
if (rel.where) {
|
|
10280
|
-
try {
|
|
10281
|
-
const targetMetadata = TargetClass.getModelMetadata?.() ?? null;
|
|
10282
|
-
if (targetMetadata) {
|
|
10283
|
-
const predicates = {};
|
|
10284
|
-
for (const propName of Object.keys(rel.where)) {
|
|
10285
|
-
if (["id", "author", "timestamp"].includes(propName))
|
|
10286
|
-
continue;
|
|
10287
|
-
const propMeta = targetMetadata.properties[propName];
|
|
10288
|
-
if (propMeta?.predicate) {
|
|
10289
|
-
predicates[propName] = propMeta.predicate;
|
|
10290
|
-
}
|
|
10291
|
-
}
|
|
10292
|
-
if (Object.keys(predicates).length > 0) {
|
|
10293
|
-
rel.whereFilter = rel.where;
|
|
10294
|
-
rel.wherePredicates = predicates;
|
|
10295
|
-
}
|
|
10296
|
-
}
|
|
10297
|
-
} catch (e7) {
|
|
10298
|
-
console.debug(`prepareModelQueryParams: target metadata unavailable for relation '${relName}':`, e7);
|
|
10299
|
-
}
|
|
10300
|
-
}
|
|
10301
|
-
} catch (e7) {
|
|
10302
|
-
console.debug(`prepareModelQueryParams: target class unavailable for relation '${relName}':`, e7);
|
|
10303
|
-
}
|
|
10304
|
-
}
|
|
10305
|
-
}
|
|
10306
10261
|
return {
|
|
10307
10262
|
className,
|
|
10308
10263
|
queryJson: JSON.stringify(queryInput),
|
|
10309
|
-
shapeJson: JSON.stringify(metadata),
|
|
10310
10264
|
metadata
|
|
10311
10265
|
};
|
|
10312
10266
|
}
|
|
@@ -10349,8 +10303,8 @@ var Ad4mModel = class {
|
|
|
10349
10303
|
}));
|
|
10350
10304
|
}
|
|
10351
10305
|
static async executeModelQuery(perspective, query = {}, classNameOverride) {
|
|
10352
|
-
const { className, queryJson
|
|
10353
|
-
const result = await perspective.modelQuery(className, queryJson
|
|
10306
|
+
const { className, queryJson } = this.prepareModelQueryParams(query, classNameOverride);
|
|
10307
|
+
const result = await perspective.modelQuery(className, queryJson);
|
|
10354
10308
|
const instances = result.instances.map((json) => {
|
|
10355
10309
|
return jsonToModelInstance(this, perspective, json, query.include, query.properties);
|
|
10356
10310
|
});
|
|
@@ -10364,28 +10318,30 @@ var Ad4mModel = class {
|
|
|
10364
10318
|
totalCount: result.totalCount
|
|
10365
10319
|
};
|
|
10366
10320
|
}
|
|
10367
|
-
static async findAll(perspective, query
|
|
10368
|
-
|
|
10321
|
+
static async findAll(perspective, query) {
|
|
10322
|
+
const q = query ?? {};
|
|
10323
|
+
if (q.properties && q.properties.length === 0) {
|
|
10369
10324
|
throw new Error("properties[] must not be empty \u2014 omit the field to return all properties, or specify at least one field name");
|
|
10370
10325
|
}
|
|
10371
|
-
const { results } = await this.executeModelQuery(perspective,
|
|
10326
|
+
const { results } = await this.executeModelQuery(perspective, q);
|
|
10372
10327
|
return results;
|
|
10373
10328
|
}
|
|
10374
|
-
static async findOne(perspective, query
|
|
10375
|
-
const limitedQuery = { ...query, limit: 1 };
|
|
10329
|
+
static async findOne(perspective, query) {
|
|
10330
|
+
const limitedQuery = { ...query ?? {}, limit: 1 };
|
|
10376
10331
|
const results = await this.findAll(perspective, limitedQuery);
|
|
10377
10332
|
return results[0] ?? null;
|
|
10378
10333
|
}
|
|
10379
|
-
static async findAllAndCount(perspective, query
|
|
10380
|
-
|
|
10334
|
+
static async findAllAndCount(perspective, query) {
|
|
10335
|
+
const out = await this.executeModelQuery(perspective, query ?? {});
|
|
10336
|
+
return out;
|
|
10381
10337
|
}
|
|
10382
|
-
static async paginate(perspective, pageSize, pageNumber, query
|
|
10383
|
-
const paginationQuery = { ...query
|
|
10338
|
+
static async paginate(perspective, pageSize, pageNumber, query) {
|
|
10339
|
+
const paginationQuery = { ...query ?? {}, limit: pageSize, offset: pageSize * (pageNumber - 1), count: true };
|
|
10384
10340
|
const { results, totalCount } = await this.executeModelQuery(perspective, paginationQuery);
|
|
10385
10341
|
return { results, totalCount, pageSize, pageNumber };
|
|
10386
10342
|
}
|
|
10387
|
-
static async count(perspective, query
|
|
10388
|
-
const { totalCount } = await this.executeModelQuery(perspective, { ...query, limit: 0 });
|
|
10343
|
+
static async count(perspective, query) {
|
|
10344
|
+
const { totalCount } = await this.executeModelQuery(perspective, { ...query ?? {}, limit: 0 });
|
|
10389
10345
|
return totalCount;
|
|
10390
10346
|
}
|
|
10391
10347
|
async setProperty(key, value, batchId) {
|
|
@@ -10581,26 +10537,8 @@ var Ad4mModel = class {
|
|
|
10581
10537
|
if (instances.length === 0)
|
|
10582
10538
|
return;
|
|
10583
10539
|
const metadata = this.getModelMetadata();
|
|
10584
|
-
const allRelMeta = getRelationsMetadata(this);
|
|
10585
|
-
for (const [relName, relMeta] of Object.entries(metadata.relations)) {
|
|
10586
|
-
const rel = relMeta;
|
|
10587
|
-
if (rel.getter || rel.direction === "reverse" || rel.filter === false)
|
|
10588
|
-
continue;
|
|
10589
|
-
const meta = allRelMeta[relName];
|
|
10590
|
-
if (!meta?.target)
|
|
10591
|
-
continue;
|
|
10592
|
-
try {
|
|
10593
|
-
const TargetClass = meta.target();
|
|
10594
|
-
const filter = buildConformanceFilter(meta.predicate, TargetClass);
|
|
10595
|
-
if (filter)
|
|
10596
|
-
rel.getter = filter.getter;
|
|
10597
|
-
} catch (e7) {
|
|
10598
|
-
console.debug(`evaluateGetters: target class unavailable for relation '${relName}':`, e7);
|
|
10599
|
-
}
|
|
10600
|
-
}
|
|
10601
|
-
const shapeJson = JSON.stringify(metadata);
|
|
10602
10540
|
const instanceIds = instances.map((inst) => inst.id || inst._baseExpression);
|
|
10603
|
-
const result = await perspective.evaluateGetters(metadata.className, instanceIds,
|
|
10541
|
+
const result = await perspective.evaluateGetters(metadata.className, instanceIds, propertyNames);
|
|
10604
10542
|
const evaluatedPropertyNames = [];
|
|
10605
10543
|
for (const [propName, propMeta] of Object.entries(metadata.properties)) {
|
|
10606
10544
|
if (propMeta.getter) {
|
|
@@ -10734,7 +10672,7 @@ var Ad4mModel = class {
|
|
|
10734
10672
|
return result;
|
|
10735
10673
|
}
|
|
10736
10674
|
static query(perspective, query) {
|
|
10737
|
-
return new ModelQueryBuilder(perspective, this, query);
|
|
10675
|
+
return new ModelQueryBuilder(perspective, this, query ?? {});
|
|
10738
10676
|
}
|
|
10739
10677
|
static fromJSONSchema(schema, options) {
|
|
10740
10678
|
return buildModelFromJSONSchema(this, schema, options);
|