Updated the rest of the code to fit the new ContextUtil

main
Jackson Morgan 2 years ago
parent 9b3632e177
commit 4b477559e2
  1. 37
      packages/jsonld-dataset-proxy/src/ContextUtil.ts
  2. 13
      packages/jsonld-dataset-proxy/src/ProxyContext.ts
  3. 12
      packages/jsonld-dataset-proxy/src/arrayProxy/modifyArray.ts
  4. 5
      packages/jsonld-dataset-proxy/src/graphOf.ts
  5. 7
      packages/jsonld-dataset-proxy/src/language/languagesOf.ts
  6. 7
      packages/jsonld-dataset-proxy/src/subjectProxy/createSubjectHandler.ts
  7. 4
      packages/jsonld-dataset-proxy/src/subjectProxy/deleteFromDataset.ts
  8. 13
      packages/jsonld-dataset-proxy/src/subjectProxy/getValueForKey.ts
  9. 14
      packages/jsonld-dataset-proxy/src/util/addObjectToDataset.ts
  10. 8
      packages/jsonld-dataset-proxy/src/util/getNodeFromRaw.ts
  11. 10
      packages/jsonld-dataset-proxy/test/ContextUtil.test.ts

@ -3,6 +3,7 @@ import type {
LdoJsonldContext,
LdoJsonldContextExpandedTermDefinition,
} from "./LdoJsonldContext";
import type { NamedNode } from "@rdfjs/types";
// Create JSONLD Shorthands
const shorthandToIriMap: Record<string, string> = {
@ -64,15 +65,18 @@ export class ContextUtil {
*/
private getRelevantContext(
key: string,
typeName?: string,
typeNames?: NamedNode[],
): ContextDefinition | LdoJsonldContext {
if (
typeName &&
typeof this.context[typeName] === "object" &&
this.context[typeName]?.["@context"] &&
this.context[typeName]?.["@context"][key]
) {
return this.context[typeName]?.["@context"];
if (!typeNames) return this.context;
for (const typeNameNode of typeNames) {
const typeName = this.iriToKey((typeNameNode as NamedNode).value, []);
if (
typeof this.context[typeName] === "object" &&
this.context[typeName]?.["@context"] &&
this.context[typeName]?.["@context"][key]
) {
return this.context[typeName]?.["@context"];
}
}
return this.context;
}
@ -91,7 +95,7 @@ export class ContextUtil {
/**
* Converts a given JsonLd key into an RDF IRI
*/
public keyToIri(key: string, typeName: string): string {
public keyToIri(key: string, typeName: NamedNode[]): string {
const relevantContext = this.getRelevantContext(key, typeName);
if (!relevantContext[key]) {
return key;
@ -108,9 +112,12 @@ export class ContextUtil {
/**
* Converts a given RDF IRI into the JsonLd key
*/
public iriToKey(iri: string, typeName: string): string {
const relevantMap =
this.typeNameToIriToKeyMap[typeName] || this.iriToKeyMap;
public iriToKey(iri: string, typeNames: NamedNode[]): string {
let relevantMap = this.iriToKeyMap;
for (const typeNameNode of typeNames) {
const typeName = this.iriToKey((typeNameNode as NamedNode).value, []);
relevantMap = this.typeNameToIriToKeyMap[typeName] || this.iriToKeyMap;
}
if (relevantMap[iri]) {
return relevantMap[iri];
}
@ -120,7 +127,7 @@ export class ContextUtil {
/**
* Returns the IRI of a datatype of a specific object
*/
public getDataType(key: string, typeName: string): string {
public getDataType(key: string, typeName: NamedNode[]): string {
const relevantContext = this.getRelevantContext(key, typeName);
if (
typeof relevantContext[key] === "object" &&
@ -136,7 +143,7 @@ export class ContextUtil {
/**
* Returns true if the object is a collection
*/
public isArray(key: string, typeName: string): boolean {
public isArray(key: string, typeName: NamedNode[]): boolean {
const relevantContext = this.getRelevantContext(key, typeName);
return !!(
relevantContext[key] &&
@ -153,7 +160,7 @@ export class ContextUtil {
/**
* Returns true if the object is a language string
*/
public isLangString(key: string, typeName: string): boolean {
public isLangString(key: string, typeName: NamedNode[]): boolean {
const relevantContext = this.getRelevantContext(key, typeName);
return !!(
relevantContext[key] &&

@ -1,4 +1,4 @@
import type { GraphNode, QuadMatch } from "@ldo/rdf-utils";
import type { GraphNode, QuadMatch, SubjectNode } from "@ldo/rdf-utils";
import type { BlankNode, Dataset, NamedNode } from "@rdfjs/types";
import type { ArrayProxyTarget } from "./arrayProxy/createArrayHandler";
import { createArrayHandler } from "./arrayProxy/createArrayHandler";
@ -8,6 +8,7 @@ import type { ArrayProxy } from "./arrayProxy/ArrayProxy";
import { _getUnderlyingArrayTarget } from "./types";
import type { ContextUtil } from "./ContextUtil";
import type { LanguageOrdering } from "./language/languageTypes";
import { namedNode } from "@rdfjs/data-model";
export interface ProxyContextOptions {
dataset: Dataset;
@ -18,6 +19,8 @@ export interface ProxyContextOptions {
state?: Record<string, unknown>;
}
const rdfType = namedNode("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
/**
* This file keeps track of the target objects used in the proxies.
* The reason is so that JSON.stringify does not recurse inifinitely
@ -107,4 +110,12 @@ export class ProxyContext {
};
return new ProxyContext(fullOptions);
}
public getRdfType(subjectNode: SubjectNode): NamedNode[] {
return this.dataset
.match(subjectNode, rdfType)
.toArray()
.map((quad) => quad.object)
.filter((object): object is NamedNode => object.termType === "NamedNode");
}
}

@ -114,7 +114,10 @@ export function modifyArray<ReturnType>(
addObjectToDataset(
{
"@id": target[0][0],
[contextUtil.iriToKey(target[0][1].value)]: added,
[contextUtil.iriToKey(
target[0][1].value,
proxyContext.getRdfType(target[0][0]),
)]: added,
} as RawObject,
false,
proxyContext,
@ -123,7 +126,12 @@ export function modifyArray<ReturnType>(
const addedNodes = added
? (added
.map((addedValue) => {
return getNodeFromRawValue(key, addedValue, proxyContext);
return getNodeFromRawValue(
key,
addedValue,
target[0][0] ? proxyContext.getRdfType(target[0][0]) : [],
proxyContext,
);
})
.filter((val) => val != undefined) as ObjectNode[])
: [];

@ -31,7 +31,10 @@ export function graphOf<Subject extends ObjectLike, Key extends keyof Subject>(
const proxyContext = subjectProxy[_proxyContext];
const subjectNode = subjectProxy[_getUnderlyingNode];
const predicateNode = namedNode(
proxyContext.contextUtil.keyToIri(predicate as string),
proxyContext.contextUtil.keyToIri(
predicate as string,
proxyContext.getRdfType(subjectNode),
),
);
let objectNode: ObjectNode | null;
if (object == null) {

@ -51,11 +51,14 @@ export function languagesOf<
const proxy = getSubjectProxyFromObject(subjectObject);
const proxyContext = proxy[_proxyContext];
const subject = proxy[_getUnderlyingNode];
const predicate = namedNode(proxyContext.contextUtil.keyToIri(key as string));
const rdfTypes = proxyContext.getRdfType(subject);
const predicate = namedNode(
proxyContext.contextUtil.keyToIri(key as string, rdfTypes),
);
return createLanguageMapProxy<LanguageMap>(
subject,
predicate,
proxyContext,
proxyContext.contextUtil.isArray(key as string),
proxyContext.contextUtil.isArray(key as string, rdfTypes),
) as LanguageOfConditionalReturn<SubjectObject, Key>;
}

@ -48,7 +48,12 @@ export function createSubjectHandler(
const tripleDataset = proxyContext.dataset.match(subject);
const keys: Set<string> = new Set(["@id"]);
tripleDataset.toArray().forEach((quad) => {
keys.add(proxyContext.contextUtil.iriToKey(quad.predicate.value));
keys.add(
proxyContext.contextUtil.iriToKey(
quad.predicate.value,
proxyContext.getRdfType(subject),
),
);
});
return Array.from(keys);
},

@ -19,7 +19,9 @@ export function deleteValueFromDataset(
return true;
}
const subject = target["@id"];
const predicate = namedNode(proxyContext.contextUtil.keyToIri(key));
const predicate = namedNode(
proxyContext.contextUtil.keyToIri(key, proxyContext.getRdfType(subject)),
);
if (key === "@id") {
nodesToRemove.push(target["@id"]);
} else {

@ -19,7 +19,9 @@ export function getValueForKey(
if (target["@id"].termType === "BlankNode") {
return undefined;
}
return contextUtil.iriToKey(target["@id"].value);
// Purposly don't provide a typeName because we don't want to use the nested
// context
return contextUtil.iriToKey(target["@id"].value, []);
}
if (key === "toString" || key === Symbol.toStringTag) {
// TODO: this toString method right now returns [object Object],
@ -31,18 +33,19 @@ export function getValueForKey(
return;
}
const subject = target["@id"];
const predicate = namedNode(contextUtil.keyToIri(key));
if (contextUtil.isArray(key)) {
const rdfType = proxyContext.getRdfType(subject);
const predicate = namedNode(contextUtil.keyToIri(key, rdfType));
if (contextUtil.isArray(key, rdfType)) {
const arrayProxy = proxyContext.createArrayProxy(
[subject, predicate, null, null],
false,
undefined,
contextUtil.isLangString(key),
contextUtil.isLangString(key, rdfType),
);
return arrayProxy;
}
let objectDataset = dataset.match(subject, predicate);
if (contextUtil.isLangString(key)) {
if (contextUtil.isLangString(key, rdfType)) {
objectDataset = filterQuadsByLanguageOrdering(
objectDataset,
proxyContext.languageOrdering,

@ -22,15 +22,16 @@ export function addRawValueToDatasetRecursive(
proxyContext: ProxyContext,
): void {
const { dataset, contextUtil } = proxyContext;
const predicate = namedNode(contextUtil.keyToIri(key));
const rdfType = proxyContext.getRdfType(subject);
const predicate = namedNode(contextUtil.keyToIri(key, rdfType));
// Get the Object Node
const object = getNodeFromRawValue(key, value, proxyContext);
const object = getNodeFromRawValue(key, value, rdfType, proxyContext);
if (object == undefined) {
dataset.deleteMatches(subject, predicate);
} else if (object.termType === "Literal") {
let languageAppliedObject = object;
// Handle language use case
if (contextUtil.isLangString(key)) {
if (contextUtil.isLangString(key, rdfType)) {
const languageKey = getLanguageKeyForWriteOperation(
proxyContext.languageOrdering,
);
@ -81,6 +82,7 @@ export function addRawObjectToDatasetRecursive(
}
const { dataset } = proxyContext;
const subject = getNodeFromRawObject(item, proxyContext.contextUtil);
const rdfType = proxyContext.getRdfType(subject);
if (visitedObjects.has(subject)) {
return proxyContext.createSubjectProxy(subject);
}
@ -89,9 +91,11 @@ export function addRawObjectToDatasetRecursive(
if (key === "@id") {
return;
}
const predicate = namedNode(proxyContext.contextUtil.keyToIri(key));
const predicate = namedNode(
proxyContext.contextUtil.keyToIri(key, rdfType),
);
if (shouldDeleteOldTriples) {
if (proxyContext.contextUtil.isLangString(key)) {
if (proxyContext.contextUtil.isLangString(key, rdfType)) {
const languageKey = getLanguageKeyForWriteOperation(
proxyContext.languageOrdering,
);

@ -14,7 +14,9 @@ export function getNodeFromRawObject(
} else if (!item["@id"]) {
return blankNode();
} else if (typeof item["@id"] === "string") {
return namedNode(contextUtil.keyToIri(item["@id"]));
// Purposly do not include typeName because we don't want to reference
// nested context
return namedNode(contextUtil.keyToIri(item["@id"], []));
} else {
return item["@id"];
}
@ -23,6 +25,7 @@ export function getNodeFromRawObject(
export function getNodeFromRawValue(
key: string,
value: RawValue,
rdfTypes: NamedNode[],
proxyContext: ProxyContext,
): BlankNode | NamedNode | Literal | undefined {
// Get the Object Node
@ -33,7 +36,8 @@ export function getNodeFromRawValue(
typeof value === "boolean" ||
typeof value === "number"
) {
const datatype = proxyContext.contextUtil.getType(key);
// PICKUP: figure out how to handle looking for the RDF Types of a raw value
const datatype = proxyContext.contextUtil.getDataType(key, rdfTypes);
if (datatype === "@id") {
return namedNode(value.toString());
} else {

@ -7,13 +7,13 @@ describe("ContextUtil", () => {
name: "http://hl7.org/fhir/name",
};
const contextUtil = new ContextUtil(fakeContext);
expect(contextUtil.keyToIri("name")).toBe("http://hl7.org/fhir/name");
expect(contextUtil.keyToIri("name", [])).toBe("http://hl7.org/fhir/name");
});
it("returns the given key if it is not in the context", () => {
const contextUtil = new ContextUtil({});
expect(contextUtil.keyToIri("name")).toBe("name");
expect(contextUtil.iriToKey("http://hl7.org/fhir/name")).toBe(
expect(contextUtil.keyToIri("name", [])).toBe("name");
expect(contextUtil.iriToKey("http://hl7.org/fhir/name", [])).toBe(
"http://hl7.org/fhir/name",
);
});
@ -22,7 +22,7 @@ describe("ContextUtil", () => {
const contextUtil = new ContextUtil({
name: { "@type": "http://www.w3.org/2001/XMLSchema#string" },
});
expect(contextUtil.keyToIri("name")).toBe("name");
expect(contextUtil.keyToIri("name", [])).toBe("name");
});
});
@ -31,7 +31,7 @@ describe("ContextUtil", () => {
const contextUtil = new ContextUtil({
name: { "@id": "http://hl7.org/fhir/name" },
});
expect(contextUtil.getType("name")).toBe(
expect(contextUtil.getDataType("name", [])).toBe(
"http://www.w3.org/2001/XMLSchema#string",
);
});

Loading…
Cancel
Save