@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/web.js
CHANGED
|
@@ -2415,6 +2415,41 @@ var SHACLShape = class {
|
|
|
2415
2415
|
target: `literal:string:${JSON.stringify(prop.in)}`
|
|
2416
2416
|
});
|
|
2417
2417
|
}
|
|
2418
|
+
if (prop.relationKind) {
|
|
2419
|
+
links.push({
|
|
2420
|
+
source: propShapeId,
|
|
2421
|
+
predicate: "ad4m://relationKind",
|
|
2422
|
+
target: `literal:string:${prop.relationKind}`
|
|
2423
|
+
});
|
|
2424
|
+
}
|
|
2425
|
+
if (prop.targetClassName) {
|
|
2426
|
+
links.push({
|
|
2427
|
+
source: propShapeId,
|
|
2428
|
+
predicate: "ad4m://targetClassName",
|
|
2429
|
+
target: `literal:string:${prop.targetClassName}`
|
|
2430
|
+
});
|
|
2431
|
+
}
|
|
2432
|
+
if (prop.whereFilter !== void 0 && prop.whereFilter !== null) {
|
|
2433
|
+
links.push({
|
|
2434
|
+
source: propShapeId,
|
|
2435
|
+
predicate: "ad4m://whereFilter",
|
|
2436
|
+
target: `literal:string:${JSON.stringify(prop.whereFilter)}`
|
|
2437
|
+
});
|
|
2438
|
+
}
|
|
2439
|
+
if (prop.wherePredicates && Object.keys(prop.wherePredicates).length > 0) {
|
|
2440
|
+
links.push({
|
|
2441
|
+
source: propShapeId,
|
|
2442
|
+
predicate: "ad4m://wherePredicates",
|
|
2443
|
+
target: `literal:string:${JSON.stringify(prop.wherePredicates)}`
|
|
2444
|
+
});
|
|
2445
|
+
}
|
|
2446
|
+
if (prop.filter !== void 0) {
|
|
2447
|
+
links.push({
|
|
2448
|
+
source: propShapeId,
|
|
2449
|
+
predicate: "ad4m://filter",
|
|
2450
|
+
target: `literal:${prop.filter}`
|
|
2451
|
+
});
|
|
2452
|
+
}
|
|
2418
2453
|
}
|
|
2419
2454
|
return links;
|
|
2420
2455
|
}
|
|
@@ -2563,6 +2598,40 @@ var SHACLShape = class {
|
|
|
2563
2598
|
} catch (e7) {
|
|
2564
2599
|
}
|
|
2565
2600
|
}
|
|
2601
|
+
const relationKindLink = links.find((l5) => l5.source === propShapeId && l5.predicate === "ad4m://relationKind");
|
|
2602
|
+
if (relationKindLink) {
|
|
2603
|
+
const val = relationKindLink.target.replace(/^literal:\/\/string:|^literal:string:/, "");
|
|
2604
|
+
if (val === "hasMany" || val === "hasOne" || val === "belongsToOne" || val === "belongsToMany") {
|
|
2605
|
+
prop.relationKind = val;
|
|
2606
|
+
}
|
|
2607
|
+
}
|
|
2608
|
+
const targetClassNameLink = links.find((l5) => l5.source === propShapeId && l5.predicate === "ad4m://targetClassName");
|
|
2609
|
+
if (targetClassNameLink) {
|
|
2610
|
+
prop.targetClassName = targetClassNameLink.target.replace(/^literal:\/\/string:|^literal:string:/, "");
|
|
2611
|
+
}
|
|
2612
|
+
const whereFilterLink = links.find((l5) => l5.source === propShapeId && l5.predicate === "ad4m://whereFilter");
|
|
2613
|
+
if (whereFilterLink) {
|
|
2614
|
+
try {
|
|
2615
|
+
const jsonStr = whereFilterLink.target.replace(/^literal:\/\/string:|^literal:string:/, "");
|
|
2616
|
+
prop.whereFilter = JSON.parse(jsonStr);
|
|
2617
|
+
} catch (e7) {
|
|
2618
|
+
}
|
|
2619
|
+
}
|
|
2620
|
+
const wherePredicatesLink = links.find((l5) => l5.source === propShapeId && l5.predicate === "ad4m://wherePredicates");
|
|
2621
|
+
if (wherePredicatesLink) {
|
|
2622
|
+
try {
|
|
2623
|
+
const jsonStr = wherePredicatesLink.target.replace(/^literal:\/\/string:|^literal:string:/, "");
|
|
2624
|
+
prop.wherePredicates = JSON.parse(jsonStr);
|
|
2625
|
+
} catch (e7) {
|
|
2626
|
+
}
|
|
2627
|
+
}
|
|
2628
|
+
const filterLink = links.find((l5) => l5.source === propShapeId && l5.predicate === "ad4m://filter");
|
|
2629
|
+
if (filterLink) {
|
|
2630
|
+
let val = filterLink.target.replace(/^literal:\/\/|^literal:/, "");
|
|
2631
|
+
if (val.startsWith("boolean:"))
|
|
2632
|
+
val = val.substring(8);
|
|
2633
|
+
prop.filter = val === "true";
|
|
2634
|
+
}
|
|
2566
2635
|
shape.addProperty(prop);
|
|
2567
2636
|
}
|
|
2568
2637
|
return shape;
|
|
@@ -2592,7 +2661,12 @@ var SHACLShape = class {
|
|
|
2592
2661
|
getter: p2.getter,
|
|
2593
2662
|
conformance_conditions: p2.conformanceConditions,
|
|
2594
2663
|
class: p2.class,
|
|
2595
|
-
in: p2.in
|
|
2664
|
+
in: p2.in,
|
|
2665
|
+
relation_kind: p2.relationKind,
|
|
2666
|
+
target_class_name: p2.targetClassName,
|
|
2667
|
+
where_filter: p2.whereFilter,
|
|
2668
|
+
where_predicates: p2.wherePredicates,
|
|
2669
|
+
filter: p2.filter
|
|
2596
2670
|
})),
|
|
2597
2671
|
constructor_actions: this.constructor_actions,
|
|
2598
2672
|
destructor_actions: this.destructor_actions
|
|
@@ -2621,7 +2695,12 @@ var SHACLShape = class {
|
|
|
2621
2695
|
getter: p2.getter,
|
|
2622
2696
|
conformanceConditions: p2.conformance_conditions,
|
|
2623
2697
|
class: p2.class,
|
|
2624
|
-
in: p2.in
|
|
2698
|
+
in: p2.in,
|
|
2699
|
+
relationKind: p2.relation_kind,
|
|
2700
|
+
targetClassName: p2.target_class_name,
|
|
2701
|
+
whereFilter: p2.where_filter,
|
|
2702
|
+
wherePredicates: p2.where_predicates,
|
|
2703
|
+
filter: p2.filter
|
|
2625
2704
|
});
|
|
2626
2705
|
}
|
|
2627
2706
|
if (json.constructor_actions) {
|
|
@@ -2638,114 +2717,9 @@ var SHACLShape = class {
|
|
|
2638
2717
|
return shape;
|
|
2639
2718
|
}
|
|
2640
2719
|
};
|
|
2641
|
-
function formatList(list) {
|
|
2642
|
-
if (!list?.length) {
|
|
2643
|
-
return "";
|
|
2644
|
-
}
|
|
2645
|
-
if (list.length === 1) {
|
|
2646
|
-
return list.toString();
|
|
2647
|
-
}
|
|
2648
|
-
if (list.length === 2) {
|
|
2649
|
-
return list.join(" and ");
|
|
2650
|
-
}
|
|
2651
|
-
return list.slice(0, -1).join(", ") + ", and " + list.slice(-1);
|
|
2652
|
-
}
|
|
2653
|
-
function capSentence(cap) {
|
|
2654
|
-
const can = cap.can.includes("*") ? ["READ", "WRITE", "UPDATE"] : cap.can;
|
|
2655
|
-
const domain = cap.with.domain === "*" ? "" : cap.with.domain;
|
|
2656
|
-
const pointers = cap.with.pointers.includes("*") ? ["all AD4M data"] : cap.with.pointers;
|
|
2657
|
-
return `${formatList(can)} your ${domain} actions, with access to ${formatList(pointers)}`;
|
|
2658
|
-
}
|
|
2659
|
-
function escapeQueryString(value) {
|
|
2660
|
-
return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
|
|
2661
|
-
}
|
|
2662
|
-
function buildWhereCondition(predicate, condition, opts) {
|
|
2663
|
-
const escapedPredicate = escapeQueryString(predicate);
|
|
2664
|
-
const isLiteral = !opts?.resolveLanguage || opts.resolveLanguage === "literal";
|
|
2665
|
-
const varSuffix = opts?.varIndex ?? 0;
|
|
2666
|
-
function formatValue(v2) {
|
|
2667
|
-
if (typeof v2 === "string") {
|
|
2668
|
-
return isLiteral ? `<literal:string:${escapeQueryString(v2)}>` : `<${escapeQueryString(v2)}>`;
|
|
2669
|
-
}
|
|
2670
|
-
return `<literal:string:${v2}>`;
|
|
2671
|
-
}
|
|
2672
|
-
function formatLiteralFilter(varName, v2) {
|
|
2673
|
-
const raw = escapeQueryString(String(v2));
|
|
2674
|
-
const encoded = encodeURIComponent(String(v2)).replace(/!/g, "%21").replace(/'/g, "%27").replace(/\(/g, "%28").replace(/\)/g, "%29").replace(/\*/g, "%2A");
|
|
2675
|
-
if (typeof v2 === "string") {
|
|
2676
|
-
return `FILTER(STR(${varName}) = "${raw}" || STR(${varName}) = "literal:string:${encoded}")`;
|
|
2677
|
-
} else if (typeof v2 === "number") {
|
|
2678
|
-
return `FILTER(STR(${varName}) = "${v2}" || STR(${varName}) = "literal:number:${v2}")`;
|
|
2679
|
-
} else if (typeof v2 === "boolean") {
|
|
2680
|
-
return `FILTER(STR(${varName}) = "${v2}" || STR(${varName}) = "literal:boolean:${v2}")`;
|
|
2681
|
-
}
|
|
2682
|
-
return `FILTER(STR(${varName}) = "${raw}")`;
|
|
2683
|
-
}
|
|
2684
|
-
if (Array.isArray(condition)) {
|
|
2685
|
-
if (isLiteral) {
|
|
2686
|
-
const varName = `?_wc${varSuffix}`;
|
|
2687
|
-
const inValues = condition.flatMap((v2) => {
|
|
2688
|
-
const raw = escapeQueryString(String(v2));
|
|
2689
|
-
const encoded = encodeURIComponent(String(v2)).replace(/!/g, "%21").replace(/'/g, "%27").replace(/\(/g, "%28").replace(/\)/g, "%29").replace(/\*/g, "%2A");
|
|
2690
|
-
return [`"${raw}"`, `"literal:string:${encoded}"`];
|
|
2691
|
-
}).join(", ");
|
|
2692
|
-
return `?target <${escapedPredicate}> ${varName} . FILTER(STR(${varName}) IN (${inValues}))`;
|
|
2693
|
-
}
|
|
2694
|
-
const formattedValues = condition.map(formatValue).join(", ");
|
|
2695
|
-
return `FILTER EXISTS { ?target <${escapedPredicate}> ?_val . FILTER(?_val IN (${formattedValues})) }`;
|
|
2696
|
-
} else if (typeof condition === "object" && condition !== null) {
|
|
2697
|
-
const ops = condition;
|
|
2698
|
-
const parts = [];
|
|
2699
|
-
if (ops.not !== void 0) {
|
|
2700
|
-
if (Array.isArray(ops.not)) {
|
|
2701
|
-
const formattedValues = ops.not.map((v2) => formatValue(v2)).join(", ");
|
|
2702
|
-
parts.push(`FILTER NOT EXISTS { ?target <${escapedPredicate}> ?_nval . FILTER(?_nval IN (${formattedValues})) }`);
|
|
2703
|
-
} else {
|
|
2704
|
-
parts.push(`FILTER NOT EXISTS { ?target <${escapedPredicate}> ${formatValue(ops.not)} }`);
|
|
2705
|
-
}
|
|
2706
|
-
}
|
|
2707
|
-
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;
|
|
2708
|
-
if (hasComparisonOps) {
|
|
2709
|
-
parts.push(`FILTER EXISTS { ?target <${escapedPredicate}> ?_cmp }`);
|
|
2710
|
-
}
|
|
2711
|
-
return parts.join(" ");
|
|
2712
|
-
} else {
|
|
2713
|
-
if (isLiteral) {
|
|
2714
|
-
const varName = `?_wc${varSuffix}`;
|
|
2715
|
-
return `?target <${escapedPredicate}> ${varName} . ${formatLiteralFilter(varName, condition)}`;
|
|
2716
|
-
}
|
|
2717
|
-
return `?target <${escapedPredicate}> ${formatValue(condition)} .`;
|
|
2718
|
-
}
|
|
2719
|
-
}
|
|
2720
|
-
function compileWhereClause(where, metadata) {
|
|
2721
|
-
const conditions = [];
|
|
2722
|
-
for (const [propertyName, condition] of Object.entries(where)) {
|
|
2723
|
-
if (["id", "author", "timestamp"].includes(propertyName))
|
|
2724
|
-
continue;
|
|
2725
|
-
let predicate;
|
|
2726
|
-
let resolveLanguage;
|
|
2727
|
-
if (metadata) {
|
|
2728
|
-
const propMeta = metadata.properties[propertyName];
|
|
2729
|
-
if (propMeta) {
|
|
2730
|
-
predicate = propMeta.predicate;
|
|
2731
|
-
resolveLanguage = propMeta.resolveLanguage;
|
|
2732
|
-
} else {
|
|
2733
|
-
predicate = propertyName;
|
|
2734
|
-
}
|
|
2735
|
-
} else {
|
|
2736
|
-
predicate = propertyName;
|
|
2737
|
-
}
|
|
2738
|
-
const cond = buildWhereCondition(predicate, condition, { resolveLanguage, varIndex: conditions.length });
|
|
2739
|
-
if (cond) {
|
|
2740
|
-
conditions.push(cond);
|
|
2741
|
-
}
|
|
2742
|
-
}
|
|
2743
|
-
return conditions;
|
|
2744
|
-
}
|
|
2745
2720
|
function buildSHACL(subjectName, target, properties, allRelationsMeta, conformanceFilterFn) {
|
|
2746
2721
|
const obj = target.prototype;
|
|
2747
2722
|
let namespace = "ad4m://";
|
|
2748
|
-
const relations = Object.fromEntries(Object.entries(allRelationsMeta).filter(([, r4]) => r4.kind === "hasMany" || r4.kind === "belongsToMany"));
|
|
2749
2723
|
if (Object.keys(properties).length > 0) {
|
|
2750
2724
|
const firstProp = properties[Object.keys(properties)[0]];
|
|
2751
2725
|
if (firstProp.through) {
|
|
@@ -2754,8 +2728,8 @@ function buildSHACL(subjectName, target, properties, allRelationsMeta, conforman
|
|
|
2754
2728
|
namespace = match[1];
|
|
2755
2729
|
}
|
|
2756
2730
|
}
|
|
2757
|
-
} else if (Object.keys(
|
|
2758
|
-
const firstRel =
|
|
2731
|
+
} else if (Object.keys(allRelationsMeta).length > 0) {
|
|
2732
|
+
const firstRel = allRelationsMeta[Object.keys(allRelationsMeta)[0]];
|
|
2759
2733
|
if (firstRel.predicate) {
|
|
2760
2734
|
const match = firstRel.predicate.match(/^([^:]+:\/\/)/);
|
|
2761
2735
|
if (match) {
|
|
@@ -2817,6 +2791,9 @@ function buildSHACL(subjectName, target, properties, allRelationsMeta, conforman
|
|
|
2817
2791
|
if (propMeta.resolveLanguage) {
|
|
2818
2792
|
propShape.resolveLanguage = propMeta.resolveLanguage;
|
|
2819
2793
|
}
|
|
2794
|
+
if (propMeta.getter) {
|
|
2795
|
+
propShape.getter = propMeta.getter;
|
|
2796
|
+
}
|
|
2820
2797
|
if (propMeta.prologSetter) {
|
|
2821
2798
|
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.`);
|
|
2822
2799
|
} else if (propMeta.writable && propMeta.through) {
|
|
@@ -2848,46 +2825,47 @@ function buildSHACL(subjectName, target, properties, allRelationsMeta, conforman
|
|
|
2848
2825
|
}
|
|
2849
2826
|
shape.addProperty(propShape);
|
|
2850
2827
|
}
|
|
2851
|
-
for (const relName in
|
|
2852
|
-
const relMeta =
|
|
2853
|
-
if (!relMeta.predicate)
|
|
2828
|
+
for (const relName in allRelationsMeta) {
|
|
2829
|
+
const relMeta = allRelationsMeta[relName];
|
|
2830
|
+
if (!relMeta.predicate && !relMeta.getter)
|
|
2854
2831
|
continue;
|
|
2832
|
+
const synthesizedPath = relMeta.predicate || `ad4m://getter/${subjectName}/${relName}`;
|
|
2855
2833
|
const relShape = {
|
|
2856
2834
|
name: relName,
|
|
2857
|
-
path:
|
|
2835
|
+
path: synthesizedPath
|
|
2858
2836
|
};
|
|
2859
2837
|
relShape.nodeKind = "IRI";
|
|
2838
|
+
relShape.relationKind = relMeta.kind;
|
|
2839
|
+
if (relMeta.kind === "hasOne" || relMeta.kind === "belongsToOne") {
|
|
2840
|
+
relShape.maxCount = 1;
|
|
2841
|
+
} else if (relMeta.maxCount !== void 0) {
|
|
2842
|
+
relShape.maxCount = relMeta.maxCount;
|
|
2843
|
+
}
|
|
2844
|
+
if (relMeta.filter === false) {
|
|
2845
|
+
relShape.filter = false;
|
|
2846
|
+
}
|
|
2860
2847
|
if (relMeta.local !== void 0) {
|
|
2861
2848
|
relShape.local = relMeta.local;
|
|
2862
2849
|
}
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2850
|
+
if (relMeta.predicate) {
|
|
2851
|
+
relShape.adder = [{
|
|
2852
|
+
action: "addLink",
|
|
2853
|
+
source: "this",
|
|
2854
|
+
predicate: relMeta.predicate,
|
|
2855
|
+
target: "value",
|
|
2856
|
+
...relMeta.local && { local: true }
|
|
2857
|
+
}];
|
|
2858
|
+
relShape.remover = [{
|
|
2859
|
+
action: "removeLink",
|
|
2860
|
+
source: "this",
|
|
2861
|
+
predicate: relMeta.predicate,
|
|
2862
|
+
target: "value",
|
|
2863
|
+
...relMeta.local && { local: true }
|
|
2864
|
+
}];
|
|
2865
|
+
}
|
|
2877
2866
|
if (relMeta.getter) {
|
|
2878
2867
|
relShape.getter = relMeta.getter;
|
|
2879
|
-
} else if (relMeta.
|
|
2880
|
-
try {
|
|
2881
|
-
const TargetClass = relMeta.target?.();
|
|
2882
|
-
const targetMetadata = TargetClass ? TargetClass.getModelMetadata?.() ?? null : null;
|
|
2883
|
-
const conditions = compileWhereClause(relMeta.where, targetMetadata);
|
|
2884
|
-
if (conditions.length > 0) {
|
|
2885
|
-
const escapedPredicate = escapeQueryString(relMeta.predicate);
|
|
2886
|
-
relShape.getter = `SELECT ?target WHERE { <Base> <${escapedPredicate}> ?target . ${conditions.join(" ")} }`;
|
|
2887
|
-
}
|
|
2888
|
-
} catch (e7) {
|
|
2889
|
-
}
|
|
2890
|
-
} else if (relMeta.target && relMeta.filter !== false) {
|
|
2868
|
+
} else if (relMeta.target && relMeta.filter !== false && relMeta.kind !== "belongsToOne" && relMeta.kind !== "belongsToMany") {
|
|
2891
2869
|
const targetThunk = relMeta.target;
|
|
2892
2870
|
const predicate = relMeta.predicate;
|
|
2893
2871
|
let resolved = false;
|
|
@@ -2939,6 +2917,37 @@ function buildSHACL(subjectName, target, properties, allRelationsMeta, conforman
|
|
|
2939
2917
|
if (targetSHACL?.shape?.nodeShapeUri) {
|
|
2940
2918
|
relShape.class = targetSHACL.shape.nodeShapeUri;
|
|
2941
2919
|
}
|
|
2920
|
+
if (targetSHACL?.name) {
|
|
2921
|
+
relShape.targetClassName = targetSHACL.name;
|
|
2922
|
+
} else {
|
|
2923
|
+
const targetProto = TargetClass.prototype;
|
|
2924
|
+
if (targetProto?.className) {
|
|
2925
|
+
relShape.targetClassName = targetProto.className;
|
|
2926
|
+
}
|
|
2927
|
+
}
|
|
2928
|
+
} catch (e7) {
|
|
2929
|
+
console.warn(`[shacl-gen] Failed to resolve target class for relation "${subjectName}.${relName}": ${e7 instanceof Error ? e7.message : String(e7)}`);
|
|
2930
|
+
}
|
|
2931
|
+
}
|
|
2932
|
+
if (relMeta.where) {
|
|
2933
|
+
relShape.whereFilter = relMeta.where;
|
|
2934
|
+
try {
|
|
2935
|
+
const TargetClass = relMeta.target?.();
|
|
2936
|
+
const targetMetadata = TargetClass ? TargetClass.getModelMetadata?.() ?? null : null;
|
|
2937
|
+
if (targetMetadata?.properties) {
|
|
2938
|
+
const predicates = {};
|
|
2939
|
+
for (const propName of Object.keys(relMeta.where)) {
|
|
2940
|
+
if (["id", "author", "timestamp"].includes(propName))
|
|
2941
|
+
continue;
|
|
2942
|
+
const propMeta = targetMetadata.properties[propName];
|
|
2943
|
+
if (propMeta?.predicate) {
|
|
2944
|
+
predicates[propName] = propMeta.predicate;
|
|
2945
|
+
}
|
|
2946
|
+
}
|
|
2947
|
+
if (Object.keys(predicates).length > 0) {
|
|
2948
|
+
relShape.wherePredicates = predicates;
|
|
2949
|
+
}
|
|
2950
|
+
}
|
|
2942
2951
|
} catch (e7) {
|
|
2943
2952
|
}
|
|
2944
2953
|
}
|
|
@@ -2951,6 +2960,27 @@ function buildSHACL(subjectName, target, properties, allRelationsMeta, conforman
|
|
|
2951
2960
|
name: subjectName
|
|
2952
2961
|
};
|
|
2953
2962
|
}
|
|
2963
|
+
function formatList(list) {
|
|
2964
|
+
if (!list?.length) {
|
|
2965
|
+
return "";
|
|
2966
|
+
}
|
|
2967
|
+
if (list.length === 1) {
|
|
2968
|
+
return list.toString();
|
|
2969
|
+
}
|
|
2970
|
+
if (list.length === 2) {
|
|
2971
|
+
return list.join(" and ");
|
|
2972
|
+
}
|
|
2973
|
+
return list.slice(0, -1).join(", ") + ", and " + list.slice(-1);
|
|
2974
|
+
}
|
|
2975
|
+
function capSentence(cap) {
|
|
2976
|
+
const can = cap.can.includes("*") ? ["READ", "WRITE", "UPDATE"] : cap.can;
|
|
2977
|
+
const domain = cap.with.domain === "*" ? "" : cap.with.domain;
|
|
2978
|
+
const pointers = cap.with.pointers.includes("*") ? ["all AD4M data"] : cap.with.pointers;
|
|
2979
|
+
return `${formatList(can)} your ${domain} actions, with access to ${formatList(pointers)}`;
|
|
2980
|
+
}
|
|
2981
|
+
function escapeQueryString(value) {
|
|
2982
|
+
return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
|
|
2983
|
+
}
|
|
2954
2984
|
var propertyRegistry = /* @__PURE__ */ new WeakMap();
|
|
2955
2985
|
var relationRegistry = /* @__PURE__ */ new WeakMap();
|
|
2956
2986
|
var propertiesMetadataCache = /* @__PURE__ */ new WeakMap();
|
|
@@ -3577,14 +3607,14 @@ var PerspectiveProxy = class {
|
|
|
3577
3607
|
setCachedResult(__classPrivateFieldGet$a(this, _PerspectiveProxy_handle, "f").uuid, query, result);
|
|
3578
3608
|
return result;
|
|
3579
3609
|
}
|
|
3580
|
-
async modelQuery(className, queryJson
|
|
3581
|
-
return await __classPrivateFieldGet$a(this, _PerspectiveProxy_client, "f").modelQuery(__classPrivateFieldGet$a(this, _PerspectiveProxy_handle, "f").uuid, className, queryJson
|
|
3610
|
+
async modelQuery(className, queryJson) {
|
|
3611
|
+
return await __classPrivateFieldGet$a(this, _PerspectiveProxy_client, "f").modelQuery(__classPrivateFieldGet$a(this, _PerspectiveProxy_handle, "f").uuid, className, queryJson);
|
|
3582
3612
|
}
|
|
3583
|
-
async evaluateGetters(className, instanceIds,
|
|
3584
|
-
return await __classPrivateFieldGet$a(this, _PerspectiveProxy_client, "f").evaluateGetters(__classPrivateFieldGet$a(this, _PerspectiveProxy_handle, "f").uuid, className, instanceIds,
|
|
3613
|
+
async evaluateGetters(className, instanceIds, propertyNames) {
|
|
3614
|
+
return await __classPrivateFieldGet$a(this, _PerspectiveProxy_client, "f").evaluateGetters(__classPrivateFieldGet$a(this, _PerspectiveProxy_handle, "f").uuid, className, instanceIds, propertyNames);
|
|
3585
3615
|
}
|
|
3586
|
-
async modelSubscribe(className, queryJson
|
|
3587
|
-
return await __classPrivateFieldGet$a(this, _PerspectiveProxy_client, "f").modelSubscribe(__classPrivateFieldGet$a(this, _PerspectiveProxy_handle, "f").uuid, className, queryJson
|
|
3616
|
+
async modelSubscribe(className, queryJson) {
|
|
3617
|
+
return await __classPrivateFieldGet$a(this, _PerspectiveProxy_client, "f").modelSubscribe(__classPrivateFieldGet$a(this, _PerspectiveProxy_handle, "f").uuid, className, queryJson);
|
|
3588
3618
|
}
|
|
3589
3619
|
async add(link, status = "shared", batchId) {
|
|
3590
3620
|
const result = await __classPrivateFieldGet$a(this, _PerspectiveProxy_client, "f").addLink(__classPrivateFieldGet$a(this, _PerspectiveProxy_handle, "f").uuid, link, status, batchId);
|
|
@@ -4631,22 +4661,21 @@ var PerspectiveClient = class {
|
|
|
4631
4661
|
}
|
|
4632
4662
|
return __classPrivateFieldGet$9(this, _PerspectiveClient_apiClient, "f").call("perspective.disposeQuery", { uuid, subscriptionId });
|
|
4633
4663
|
}
|
|
4634
|
-
async modelQuery(uuid, className, queryJson
|
|
4635
|
-
const resultJson = await __classPrivateFieldGet$9(this, _PerspectiveClient_apiClient, "f").call("perspective.modelQuery", { uuid, class_name: className, query_json: queryJson
|
|
4664
|
+
async modelQuery(uuid, className, queryJson) {
|
|
4665
|
+
const resultJson = await __classPrivateFieldGet$9(this, _PerspectiveClient_apiClient, "f").call("perspective.modelQuery", { uuid, class_name: className, query_json: queryJson });
|
|
4636
4666
|
return JSON.parse(resultJson);
|
|
4637
4667
|
}
|
|
4638
|
-
async evaluateGetters(uuid, className, instanceIds,
|
|
4668
|
+
async evaluateGetters(uuid, className, instanceIds, propertyNames) {
|
|
4639
4669
|
const resultJson = await __classPrivateFieldGet$9(this, _PerspectiveClient_apiClient, "f").call("perspective.evaluateGetters", {
|
|
4640
4670
|
uuid,
|
|
4641
4671
|
class_name: className,
|
|
4642
4672
|
instance_ids: instanceIds,
|
|
4643
|
-
shape_json: shapeJson,
|
|
4644
4673
|
...propertyNames && { property_names: propertyNames }
|
|
4645
4674
|
});
|
|
4646
4675
|
return JSON.parse(resultJson);
|
|
4647
4676
|
}
|
|
4648
|
-
async modelSubscribe(uuid, className, queryJson
|
|
4649
|
-
const response = await __classPrivateFieldGet$9(this, _PerspectiveClient_apiClient, "f").call("perspective.modelSubscribe", { uuid, class_name: className, query_json: queryJson
|
|
4677
|
+
async modelSubscribe(uuid, className, queryJson) {
|
|
4678
|
+
const response = await __classPrivateFieldGet$9(this, _PerspectiveClient_apiClient, "f").call("perspective.modelSubscribe", { uuid, class_name: className, query_json: queryJson });
|
|
4650
4679
|
return {
|
|
4651
4680
|
subscriptionId: response.subscription_id,
|
|
4652
4681
|
result: JSON.parse(response.result)
|
|
@@ -10170,9 +10199,6 @@ var ModelQueryBuilder = class {
|
|
|
10170
10199
|
this.modelClassName = className;
|
|
10171
10200
|
return this;
|
|
10172
10201
|
}
|
|
10173
|
-
engine(_eng) {
|
|
10174
|
-
return this;
|
|
10175
|
-
}
|
|
10176
10202
|
async get() {
|
|
10177
10203
|
return await this.executeSparqlQuery();
|
|
10178
10204
|
}
|
|
@@ -10193,8 +10219,8 @@ var ModelQueryBuilder = class {
|
|
|
10193
10219
|
async subscribe(callback) {
|
|
10194
10220
|
this.dispose();
|
|
10195
10221
|
const ctor = this.ctor;
|
|
10196
|
-
const { className, queryJson
|
|
10197
|
-
const { subscriptionId, result: initialModelResult } = await this.perspective.modelSubscribe(className, queryJson
|
|
10222
|
+
const { className, queryJson } = ctor.prepareModelQueryParams(this.queryParams, this.modelClassName);
|
|
10223
|
+
const { subscriptionId, result: initialModelResult } = await this.perspective.modelSubscribe(className, queryJson);
|
|
10198
10224
|
const parseResults = (raw) => {
|
|
10199
10225
|
return ctor.parseModelResult(this.perspective, raw, this.queryParams.include, this.queryParams.properties);
|
|
10200
10226
|
};
|
|
@@ -10291,8 +10317,8 @@ var ModelQueryBuilder = class {
|
|
|
10291
10317
|
async countSubscribe(callback) {
|
|
10292
10318
|
this.dispose();
|
|
10293
10319
|
const countParams = { ...this.queryParams, limit: 0 };
|
|
10294
|
-
const { className, queryJson
|
|
10295
|
-
const { subscriptionId, result: initialModelResult } = await this.perspective.modelSubscribe(className, queryJson
|
|
10320
|
+
const { className, queryJson } = this.ctor.prepareModelQueryParams(countParams, this.modelClassName);
|
|
10321
|
+
const { subscriptionId, result: initialModelResult } = await this.perspective.modelSubscribe(className, queryJson);
|
|
10296
10322
|
const parseCount = (raw) => {
|
|
10297
10323
|
const data = typeof raw === "string" ? JSON.parse(raw) : raw;
|
|
10298
10324
|
return data.totalCount ?? 0;
|
|
@@ -10367,8 +10393,8 @@ var ModelQueryBuilder = class {
|
|
|
10367
10393
|
const subscriptionParams = { ...this.queryParams || {} };
|
|
10368
10394
|
delete subscriptionParams.limit;
|
|
10369
10395
|
delete subscriptionParams.offset;
|
|
10370
|
-
const { className, queryJson
|
|
10371
|
-
const { subscriptionId } = await this.perspective.modelSubscribe(className, queryJson
|
|
10396
|
+
const { className, queryJson } = ctor.prepareModelQueryParams(subscriptionParams, this.modelClassName);
|
|
10397
|
+
const { subscriptionId } = await this.perspective.modelSubscribe(className, queryJson);
|
|
10372
10398
|
const paginatedQuery = {
|
|
10373
10399
|
...this.queryParams || {},
|
|
10374
10400
|
limit: pageSize,
|
|
@@ -10460,34 +10486,6 @@ function defaultFileDecode(resolved) {
|
|
|
10460
10486
|
}
|
|
10461
10487
|
return resolved;
|
|
10462
10488
|
}
|
|
10463
|
-
function enrichShapeForIncludes(metadata, include, allRelMeta) {
|
|
10464
|
-
for (const [relName, includeVal] of Object.entries(include)) {
|
|
10465
|
-
if (!includeVal)
|
|
10466
|
-
continue;
|
|
10467
|
-
const meta = allRelMeta[relName];
|
|
10468
|
-
if (!meta?.target)
|
|
10469
|
-
continue;
|
|
10470
|
-
const TargetClass = meta.target();
|
|
10471
|
-
const targetMeta = JSON.parse(JSON.stringify(TargetClass.getModelMetadata()));
|
|
10472
|
-
if (!metadata.relations[relName]) {
|
|
10473
|
-
metadata.relations[relName] = {
|
|
10474
|
-
name: relName,
|
|
10475
|
-
predicate: meta.predicate,
|
|
10476
|
-
direction: meta.kind === "belongsToMany" || meta.kind === "belongsToOne" ? "reverse" : "forward"
|
|
10477
|
-
};
|
|
10478
|
-
}
|
|
10479
|
-
const rel = metadata.relations[relName];
|
|
10480
|
-
rel.kind = meta.kind;
|
|
10481
|
-
rel.maxCount = meta.maxCount;
|
|
10482
|
-
rel.targetShape = targetMeta;
|
|
10483
|
-
rel.targetClassName = targetMeta.className;
|
|
10484
|
-
const nested = typeof includeVal === "object" && includeVal !== null ? includeVal.include : void 0;
|
|
10485
|
-
if (nested) {
|
|
10486
|
-
const targetRelMeta = getRelationsMetadata(TargetClass);
|
|
10487
|
-
enrichShapeForIncludes(targetMeta, nested, targetRelMeta);
|
|
10488
|
-
}
|
|
10489
|
-
}
|
|
10490
|
-
}
|
|
10491
10489
|
function jsonToModelInstance(ModelClass, perspective, json, include, properties) {
|
|
10492
10490
|
const instance = new ModelClass(perspective, json.id || json.baseExpression);
|
|
10493
10491
|
if (properties) {
|
|
@@ -10870,12 +10868,12 @@ var Ad4mModel = class {
|
|
|
10870
10868
|
const allRelMeta = getRelationsMetadata(this);
|
|
10871
10869
|
for (const [, proj] of Object.entries(projections)) {
|
|
10872
10870
|
const relMeta = allRelMeta[proj.from];
|
|
10873
|
-
if (!proj.
|
|
10871
|
+
if (!proj.targetClassName && relMeta?.target) {
|
|
10874
10872
|
try {
|
|
10875
10873
|
const TargetClass = relMeta.target();
|
|
10876
10874
|
const targetMeta = TargetClass.getModelMetadata?.();
|
|
10877
|
-
if (targetMeta) {
|
|
10878
|
-
proj.
|
|
10875
|
+
if (targetMeta?.className) {
|
|
10876
|
+
proj.targetClassName = targetMeta.className;
|
|
10879
10877
|
}
|
|
10880
10878
|
} catch (e7) {
|
|
10881
10879
|
console.debug(`prepareModelQueryParams: target class unavailable for projection:`, e7);
|
|
@@ -10897,56 +10895,9 @@ var Ad4mModel = class {
|
|
|
10897
10895
|
if (query.count !== void 0)
|
|
10898
10896
|
queryInput.count = query.count;
|
|
10899
10897
|
queryInput.deepQuery = query.deepQuery ?? true;
|
|
10900
|
-
if (queryInput.include) {
|
|
10901
|
-
const allRelMeta = getRelationsMetadata(this);
|
|
10902
|
-
enrichShapeForIncludes(metadata, queryInput.include, allRelMeta);
|
|
10903
|
-
}
|
|
10904
|
-
{
|
|
10905
|
-
const allRelMeta = getRelationsMetadata(this);
|
|
10906
|
-
for (const [relName, relMeta] of Object.entries(metadata.relations)) {
|
|
10907
|
-
const rel = relMeta;
|
|
10908
|
-
if (rel.getter || rel.direction === "reverse" || rel.filter === false)
|
|
10909
|
-
continue;
|
|
10910
|
-
const meta = allRelMeta[relName];
|
|
10911
|
-
if (!meta?.target)
|
|
10912
|
-
continue;
|
|
10913
|
-
try {
|
|
10914
|
-
const TargetClass = meta.target();
|
|
10915
|
-
const filter = buildConformanceFilter(meta.predicate, TargetClass);
|
|
10916
|
-
if (filter) {
|
|
10917
|
-
rel.getter = filter.getter;
|
|
10918
|
-
}
|
|
10919
|
-
if (rel.where) {
|
|
10920
|
-
try {
|
|
10921
|
-
const targetMetadata = TargetClass.getModelMetadata?.() ?? null;
|
|
10922
|
-
if (targetMetadata) {
|
|
10923
|
-
const predicates = {};
|
|
10924
|
-
for (const propName of Object.keys(rel.where)) {
|
|
10925
|
-
if (["id", "author", "timestamp"].includes(propName))
|
|
10926
|
-
continue;
|
|
10927
|
-
const propMeta = targetMetadata.properties[propName];
|
|
10928
|
-
if (propMeta?.predicate) {
|
|
10929
|
-
predicates[propName] = propMeta.predicate;
|
|
10930
|
-
}
|
|
10931
|
-
}
|
|
10932
|
-
if (Object.keys(predicates).length > 0) {
|
|
10933
|
-
rel.whereFilter = rel.where;
|
|
10934
|
-
rel.wherePredicates = predicates;
|
|
10935
|
-
}
|
|
10936
|
-
}
|
|
10937
|
-
} catch (e7) {
|
|
10938
|
-
console.debug(`prepareModelQueryParams: target metadata unavailable for relation '${relName}':`, e7);
|
|
10939
|
-
}
|
|
10940
|
-
}
|
|
10941
|
-
} catch (e7) {
|
|
10942
|
-
console.debug(`prepareModelQueryParams: target class unavailable for relation '${relName}':`, e7);
|
|
10943
|
-
}
|
|
10944
|
-
}
|
|
10945
|
-
}
|
|
10946
10898
|
return {
|
|
10947
10899
|
className,
|
|
10948
10900
|
queryJson: JSON.stringify(queryInput),
|
|
10949
|
-
shapeJson: JSON.stringify(metadata),
|
|
10950
10901
|
metadata
|
|
10951
10902
|
};
|
|
10952
10903
|
}
|
|
@@ -10989,8 +10940,8 @@ var Ad4mModel = class {
|
|
|
10989
10940
|
}));
|
|
10990
10941
|
}
|
|
10991
10942
|
static async executeModelQuery(perspective, query = {}, classNameOverride) {
|
|
10992
|
-
const { className, queryJson
|
|
10993
|
-
const result = await perspective.modelQuery(className, queryJson
|
|
10943
|
+
const { className, queryJson } = this.prepareModelQueryParams(query, classNameOverride);
|
|
10944
|
+
const result = await perspective.modelQuery(className, queryJson);
|
|
10994
10945
|
const instances = result.instances.map((json) => {
|
|
10995
10946
|
return jsonToModelInstance(this, perspective, json, query.include, query.properties);
|
|
10996
10947
|
});
|
|
@@ -11004,28 +10955,30 @@ var Ad4mModel = class {
|
|
|
11004
10955
|
totalCount: result.totalCount
|
|
11005
10956
|
};
|
|
11006
10957
|
}
|
|
11007
|
-
static async findAll(perspective, query
|
|
11008
|
-
|
|
10958
|
+
static async findAll(perspective, query) {
|
|
10959
|
+
const q = query ?? {};
|
|
10960
|
+
if (q.properties && q.properties.length === 0) {
|
|
11009
10961
|
throw new Error("properties[] must not be empty \u2014 omit the field to return all properties, or specify at least one field name");
|
|
11010
10962
|
}
|
|
11011
|
-
const { results } = await this.executeModelQuery(perspective,
|
|
10963
|
+
const { results } = await this.executeModelQuery(perspective, q);
|
|
11012
10964
|
return results;
|
|
11013
10965
|
}
|
|
11014
|
-
static async findOne(perspective, query
|
|
11015
|
-
const limitedQuery = { ...query, limit: 1 };
|
|
10966
|
+
static async findOne(perspective, query) {
|
|
10967
|
+
const limitedQuery = { ...query ?? {}, limit: 1 };
|
|
11016
10968
|
const results = await this.findAll(perspective, limitedQuery);
|
|
11017
10969
|
return results[0] ?? null;
|
|
11018
10970
|
}
|
|
11019
|
-
static async findAllAndCount(perspective, query
|
|
11020
|
-
|
|
10971
|
+
static async findAllAndCount(perspective, query) {
|
|
10972
|
+
const out = await this.executeModelQuery(perspective, query ?? {});
|
|
10973
|
+
return out;
|
|
11021
10974
|
}
|
|
11022
|
-
static async paginate(perspective, pageSize, pageNumber, query
|
|
11023
|
-
const paginationQuery = { ...query
|
|
10975
|
+
static async paginate(perspective, pageSize, pageNumber, query) {
|
|
10976
|
+
const paginationQuery = { ...query ?? {}, limit: pageSize, offset: pageSize * (pageNumber - 1), count: true };
|
|
11024
10977
|
const { results, totalCount } = await this.executeModelQuery(perspective, paginationQuery);
|
|
11025
10978
|
return { results, totalCount, pageSize, pageNumber };
|
|
11026
10979
|
}
|
|
11027
|
-
static async count(perspective, query
|
|
11028
|
-
const { totalCount } = await this.executeModelQuery(perspective, { ...query, limit: 0 });
|
|
10980
|
+
static async count(perspective, query) {
|
|
10981
|
+
const { totalCount } = await this.executeModelQuery(perspective, { ...query ?? {}, limit: 0 });
|
|
11029
10982
|
return totalCount;
|
|
11030
10983
|
}
|
|
11031
10984
|
async setProperty(key, value, batchId) {
|
|
@@ -11221,26 +11174,8 @@ var Ad4mModel = class {
|
|
|
11221
11174
|
if (instances.length === 0)
|
|
11222
11175
|
return;
|
|
11223
11176
|
const metadata = this.getModelMetadata();
|
|
11224
|
-
const allRelMeta = getRelationsMetadata(this);
|
|
11225
|
-
for (const [relName, relMeta] of Object.entries(metadata.relations)) {
|
|
11226
|
-
const rel = relMeta;
|
|
11227
|
-
if (rel.getter || rel.direction === "reverse" || rel.filter === false)
|
|
11228
|
-
continue;
|
|
11229
|
-
const meta = allRelMeta[relName];
|
|
11230
|
-
if (!meta?.target)
|
|
11231
|
-
continue;
|
|
11232
|
-
try {
|
|
11233
|
-
const TargetClass = meta.target();
|
|
11234
|
-
const filter = buildConformanceFilter(meta.predicate, TargetClass);
|
|
11235
|
-
if (filter)
|
|
11236
|
-
rel.getter = filter.getter;
|
|
11237
|
-
} catch (e7) {
|
|
11238
|
-
console.debug(`evaluateGetters: target class unavailable for relation '${relName}':`, e7);
|
|
11239
|
-
}
|
|
11240
|
-
}
|
|
11241
|
-
const shapeJson = JSON.stringify(metadata);
|
|
11242
11177
|
const instanceIds = instances.map((inst) => inst.id || inst._baseExpression);
|
|
11243
|
-
const result = await perspective.evaluateGetters(metadata.className, instanceIds,
|
|
11178
|
+
const result = await perspective.evaluateGetters(metadata.className, instanceIds, propertyNames);
|
|
11244
11179
|
const evaluatedPropertyNames = [];
|
|
11245
11180
|
for (const [propName, propMeta] of Object.entries(metadata.properties)) {
|
|
11246
11181
|
if (propMeta.getter) {
|
|
@@ -11374,7 +11309,7 @@ var Ad4mModel = class {
|
|
|
11374
11309
|
return result;
|
|
11375
11310
|
}
|
|
11376
11311
|
static query(perspective, query) {
|
|
11377
|
-
return new ModelQueryBuilder(perspective, this, query);
|
|
11312
|
+
return new ModelQueryBuilder(perspective, this, query ?? {});
|
|
11378
11313
|
}
|
|
11379
11314
|
static fromJSONSchema(schema, options) {
|
|
11380
11315
|
return buildModelFromJSONSchema(this, schema, options);
|