diff --git a/app/lib/class/AccessControl.ts b/app/lib/class/AccessControl.ts index d6aca37..3a74ff2 100644 --- a/app/lib/class/AccessControl.ts +++ b/app/lib/class/AccessControl.ts @@ -1,10 +1,10 @@ -import { TermWrapper } from "rdfjs-wrapper" +import { ObjectMapping } from "rdfjs-wrapper" import { Policy } from "@/app/lib/class/Policy" import { ACP } from "@/app/lib/class/Vocabulary" import { Typed } from "@/app/lib/class/Typed"; export class AccessControl extends Typed { get apply(): Set { - return this.objects(ACP.apply, TermWrapper.as(Policy), TermWrapper.as(Policy)) + return this.objects(ACP.apply, ObjectMapping.as(Policy), ObjectMapping.as(Policy)) } } diff --git a/app/lib/class/AccessControlResource.ts b/app/lib/class/AccessControlResource.ts index 5846007..21cf49d 100644 --- a/app/lib/class/AccessControlResource.ts +++ b/app/lib/class/AccessControlResource.ts @@ -1,18 +1,18 @@ -import { ValueMappings, TermMappings, TermWrapper } from "rdfjs-wrapper" +import { ValueMapping, TermMapping, ObjectMapping } from "rdfjs-wrapper" import { AccessControl } from "@/app/lib/class/AccessControl" import { ACP } from "@/app/lib/class/Vocabulary" import { Typed } from "@/app/lib/class/Typed" export class AccessControlResource extends Typed { get accessControl(): Set { - return this.objects(ACP.accessControl, TermWrapper.as(AccessControl), TermWrapper.as(AccessControl)) + return this.objects(ACP.accessControl, ObjectMapping.as(AccessControl), ObjectMapping.as(AccessControl)) } get resource(): string | undefined { - return this.singularNullable(ACP.resource, ValueMappings.iriToString) + return this.singularNullable(ACP.resource, ValueMapping.iriToString) } set resource(v: string) { - this.overwriteNullable(ACP.resource, v, TermMappings.stringToIri) + this.overwriteNullable(ACP.resource, v, TermMapping.stringToIri) } } diff --git a/app/lib/class/AcrDataset.ts b/app/lib/class/AcrDataset.ts index c61e100..a527d8f 100644 --- a/app/lib/class/AcrDataset.ts +++ b/app/lib/class/AcrDataset.ts @@ -5,10 +5,10 @@ import { ACP } from "@/app/lib/class/Vocabulary" export class AcrDataset extends DatasetWrapper { get acr(): AccessControlResource | undefined { const subjects = new Set([ - ...this.instancesOf(AccessControlResource, ACP.AccessControlResource), - ...this.subjectsOf(AccessControlResource, ACP.resource), - ...this.subjectsOf(AccessControlResource, ACP.accessControl), - ...this.subjectsOf(AccessControlResource, ACP.memberAccessControl) + ...this.instancesOf(ACP.AccessControlResource, AccessControlResource), + ...this.subjectsOf(ACP.resource, AccessControlResource), + ...this.subjectsOf(ACP.accessControl, AccessControlResource), + ...this.subjectsOf(ACP.memberAccessControl, AccessControlResource) ]) for (const subject of subjects) { diff --git a/app/lib/class/Agent.ts b/app/lib/class/Agent.ts index 9ee7ebb..844825c 100644 --- a/app/lib/class/Agent.ts +++ b/app/lib/class/Agent.ts @@ -1,25 +1,25 @@ -import { TermMappings, ValueMappings, TermWrapper } from "rdfjs-wrapper" +import { TermMapping, ValueMapping, TermWrapper, ObjectMapping } from "rdfjs-wrapper" import { FOAF, PIM, SOLID, VCARD } from "@/app/lib/class/Vocabulary" export class Agent extends TermWrapper { get vcardFn(): string | undefined { - return this.singularNullable(VCARD.fn, ValueMappings.literalToString) + return this.singularNullable(VCARD.fn, ValueMapping.literalToString) } get vcardHasUrl(): string | undefined { - return this.singularNullable(VCARD.hasUrl, ValueMappings.iriToString) + return this.singularNullable(VCARD.hasUrl, ValueMapping.iriToString) } get organization(): string | null { - return this.singularNullable(VCARD.organizationName, ValueMappings.iriToString) ?? null + return this.singularNullable(VCARD.organizationName, ValueMapping.iriToString) ?? null } get role(): string | null { - return this.singularNullable(VCARD.role, ValueMappings.iriToString) ?? null + return this.singularNullable(VCARD.role, ValueMapping.iriToString) ?? null } get title(): string | null { - return this.singularNullable(VCARD.title, ValueMappings.literalToString) ?? null + return this.singularNullable(VCARD.title, ValueMapping.literalToString) ?? null } get phone(): string | null { @@ -27,11 +27,11 @@ export class Agent extends TermWrapper { } get hasTelephone(): HasValue | undefined { - return this.singularNullable(VCARD.hasTelephone, TermWrapper.as(HasValue)) + return this.singularNullable(VCARD.hasTelephone, ObjectMapping.as(HasValue)) } get foafName(): string | undefined { - return this.singularNullable(FOAF.fname, ValueMappings.literalToString) + return this.singularNullable(FOAF.fname, ValueMapping.literalToString) } get name(): string | null { @@ -44,7 +44,7 @@ export class Agent extends TermWrapper { } get foafHomepage(): string | undefined { - return this.singularNullable(FOAF.homepage, ValueMappings.literalToString) + return this.singularNullable(FOAF.homepage, ValueMapping.literalToString) } get website(): string | null { @@ -52,15 +52,15 @@ export class Agent extends TermWrapper { } get photoUrl(): string | null { - return this.singularNullable(VCARD.hasPhoto, ValueMappings.literalToString) ?? null + return this.singularNullable(VCARD.hasPhoto, ValueMapping.literalToString) ?? null } get pimStorage(): Set { - return this.objects(PIM.storage, ValueMappings.iriToString, TermMappings.stringToIri) + return this.objects(PIM.storage, ValueMapping.iriToString, TermMapping.stringToIri) } get solidStorage(): Set { - return this.objects(SOLID.storage, ValueMappings.iriToString, TermMappings.stringToIri) + return this.objects(SOLID.storage, ValueMapping.iriToString, TermMapping.stringToIri) } get email(): string | null { @@ -68,11 +68,11 @@ export class Agent extends TermWrapper { } get hasEmail(): HasValue | undefined { - return this.singularNullable(VCARD.hasEmail, TermWrapper.as(HasValue)) + return this.singularNullable(VCARD.hasEmail, ObjectMapping.as(HasValue)) } get knows(): Set { - return this.objects(FOAF.knows, ValueMappings.iriToString, TermMappings.stringToIri) + return this.objects(FOAF.knows, ValueMapping.iriToString, TermMapping.stringToIri) } } @@ -82,6 +82,6 @@ class HasValue extends TermWrapper { } get hasValue(): string | undefined { - return this.singularNullable(VCARD.hasValue, ValueMappings.iriToString) + return this.singularNullable(VCARD.hasValue, ValueMapping.iriToString) } } diff --git a/app/lib/class/Container.ts b/app/lib/class/Container.ts index bca17a8..3931926 100644 --- a/app/lib/class/Container.ts +++ b/app/lib/class/Container.ts @@ -1,9 +1,9 @@ -import { TermWrapper } from "rdfjs-wrapper" +import { ObjectMapping } from "rdfjs-wrapper" import { Resource } from "@/app/lib/class/Resource" import { LDP } from "@/app/lib/class/Vocabulary" export class Container extends Resource { public get contains(): Set { - return this.objects(LDP.contains, TermWrapper.as(Resource), TermWrapper.as(Resource)) + return this.objects(LDP.contains, ObjectMapping.as(Resource), ObjectMapping.as(Resource)) } } diff --git a/app/lib/class/ContainerDataset.ts b/app/lib/class/ContainerDataset.ts index 94777e9..da3c2b3 100644 --- a/app/lib/class/ContainerDataset.ts +++ b/app/lib/class/ContainerDataset.ts @@ -6,7 +6,7 @@ export class ContainerDataset extends DatasetWrapper { // TODO: Consider that this might be undefined if there are no contained resources. We might need different matching. get container(): Container | undefined { // Return the first container in the dataset - for (const s of this.subjectsOf(Container, LDP.contains)) { + for (const s of this.subjectsOf(LDP.contains, Container)) { return s; } } diff --git a/app/lib/class/Matcher.ts b/app/lib/class/Matcher.ts index 4246dd3..a76a4ba 100644 --- a/app/lib/class/Matcher.ts +++ b/app/lib/class/Matcher.ts @@ -1,9 +1,9 @@ -import { TermMappings, ValueMappings } from "rdfjs-wrapper" +import { TermMapping, ValueMapping } from "rdfjs-wrapper" import { ACP } from "@/app/lib/class/Vocabulary" import { Typed } from "@/app/lib/class/Typed" export class Matcher extends Typed { get agent(): Set { - return this.objects(ACP.agent, ValueMappings.iriToString, TermMappings.stringToIri) + return this.objects(ACP.agent, ValueMapping.iriToString, TermMapping.stringToIri) } } diff --git a/app/lib/class/Policy.ts b/app/lib/class/Policy.ts index 29c84a3..5efdf0d 100644 --- a/app/lib/class/Policy.ts +++ b/app/lib/class/Policy.ts @@ -1,14 +1,14 @@ -import { TermMappings, ValueMappings, TermWrapper } from "rdfjs-wrapper" +import { TermMapping, ValueMapping, ObjectMapping } from "rdfjs-wrapper" import { Matcher } from "@/app/lib/class/Matcher" import { ACP } from "@/app/lib/class/Vocabulary" import { Typed } from "@/app/lib/class/Typed" export class Policy extends Typed { get allow(): Set { - return this.objects(ACP.allow, ValueMappings.iriToString, TermMappings.stringToIri) + return this.objects(ACP.allow, ValueMapping.iriToString, TermMapping.stringToIri) } get anyOf(): Set { - return this.objects(ACP.anyOf, TermWrapper.as(Matcher), TermWrapper.as(Matcher)) + return this.objects(ACP.anyOf, ObjectMapping.as(Matcher), ObjectMapping.as(Matcher)) } } diff --git a/app/lib/class/Resource.ts b/app/lib/class/Resource.ts index 6040d7e..a24e9ed 100644 --- a/app/lib/class/Resource.ts +++ b/app/lib/class/Resource.ts @@ -1,4 +1,4 @@ -import { TermMappings, ValueMappings, TermWrapper } from "rdfjs-wrapper" +import { TermMapping, ValueMapping, TermWrapper } from "rdfjs-wrapper" import { DC, POSIX, RDF, RDFS } from "@/app/lib/class/Vocabulary" import { extractNameFromUrl, FileType } from "@/app/lib/helpers" @@ -18,11 +18,11 @@ export class Resource extends TermWrapper { } get title(): string | undefined { - return this.singularNullable(DC.title, ValueMappings.literalToString) + return this.singularNullable(DC.title, ValueMapping.literalToString) } get label(): string | undefined { - return this.singularNullable(RDFS.label, ValueMappings.literalToString) + return this.singularNullable(RDFS.label, ValueMapping.literalToString) } get name(): string { @@ -30,11 +30,11 @@ export class Resource extends TermWrapper { } get modified(): Date | undefined { - return this.singularNullable(DC.modified, ValueMappings.literalToDate) + return this.singularNullable(DC.modified, ValueMapping.literalToDate) } get mtime(): Date | undefined { - return this.singularNullable(POSIX.mtime, ValueMappings.literalToDate) + return this.singularNullable(POSIX.mtime, ValueMapping.literalToDate) } get lastModified(): Date | undefined { @@ -42,11 +42,11 @@ export class Resource extends TermWrapper { } get size(): number | undefined { - return this.singularNullable(POSIX.size, ValueMappings.literalToNumber) + return this.singularNullable(POSIX.size, ValueMapping.literalToNumber) } get type(): Set { - return this.objects(RDF.type, ValueMappings.iriToString, TermMappings.stringToIri) + return this.objects(RDF.type, ValueMapping.iriToString, TermMapping.stringToIri) } get mimeType(): string | undefined { diff --git a/app/lib/class/Typed.ts b/app/lib/class/Typed.ts index 7bfc391..bb96736 100644 --- a/app/lib/class/Typed.ts +++ b/app/lib/class/Typed.ts @@ -1,8 +1,8 @@ -import { TermMappings, ValueMappings, TermWrapper } from "rdfjs-wrapper" +import { TermMapping, ValueMapping, TermWrapper } from "rdfjs-wrapper" import { RDF } from "@/app/lib/class/Vocabulary" export class Typed extends TermWrapper { get type(): Set { - return this.objects(RDF.type, ValueMappings.iriToString, TermMappings.stringToIri) + return this.objects(RDF.type, ValueMapping.iriToString, TermMapping.stringToIri) } } diff --git a/app/lib/class/Vocabulary.ts b/app/lib/class/Vocabulary.ts index 7ff59f8..9e2df10 100644 --- a/app/lib/class/Vocabulary.ts +++ b/app/lib/class/Vocabulary.ts @@ -1,68 +1,66 @@ -import { DataFactory } from "n3" +export const ACP = { + resource: "http://www.w3.org/ns/solid/acp#resource", + accessControl: "http://www.w3.org/ns/solid/acp#accessControl", + memberAccessControl: "http://www.w3.org/ns/solid/acp#memberAccessControl", + AccessControlResource: "http://www.w3.org/ns/solid/acp#AccessControlResource", + apply: "http://www.w3.org/ns/solid/acp#apply", + anyOf: "http://www.w3.org/ns/solid/acp#anyOf", + agent: "http://www.w3.org/ns/solid/acp#agent", + Matcher: "http://www.w3.org/ns/solid/acp#Matcher", + Policy: "http://www.w3.org/ns/solid/acp#Policy", + allow: "http://www.w3.org/ns/solid/acp#allow", + mode: "http://www.w3.org/ns/solid/acp#mode", + AccessControl: "http://www.w3.org/ns/solid/acp#AccessControl", +} as const -export class ACP { - static resource = DataFactory.namedNode("http://www.w3.org/ns/solid/acp#resource") - static accessControl = DataFactory.namedNode("http://www.w3.org/ns/solid/acp#accessControl") - static memberAccessControl = DataFactory.namedNode("http://www.w3.org/ns/solid/acp#memberAccessControl") - static AccessControlResource = DataFactory.namedNode("http://www.w3.org/ns/solid/acp#AccessControlResource") - static apply = DataFactory.namedNode("http://www.w3.org/ns/solid/acp#apply") - static anyOf = DataFactory.namedNode("http://www.w3.org/ns/solid/acp#anyOf") - static agent = DataFactory.namedNode("http://www.w3.org/ns/solid/acp#agent") - static Matcher = DataFactory.namedNode("http://www.w3.org/ns/solid/acp#Matcher") - static Policy = DataFactory.namedNode("http://www.w3.org/ns/solid/acp#Policy") - static allow = DataFactory.namedNode("http://www.w3.org/ns/solid/acp#allow") - static mode = DataFactory.namedNode("http://www.w3.org/ns/solid/acp#mode") - static AccessControl = DataFactory.namedNode("http://www.w3.org/ns/solid/acp#AccessControl") -} +export const DC = { + modified: "http://purl.org/dc/terms/modified", + title: "http://purl.org/dc/terms/title", +} as const -export class DC { - static modified = DataFactory.namedNode("http://purl.org/dc/terms/modified") - static title = DataFactory.namedNode("http://purl.org/dc/terms/title") -} +export const FOAF = { + isPrimaryTopicOf: "http://xmlns.com/foaf/0.1/isPrimaryTopicOf", + primaryTopic: "http://xmlns.com/foaf/0.1/primaryTopic", + fname: "http://xmlns.com/foaf/0.1/name", + email: "http://xmlns.com/foaf/0.1/email", + homepage: "http://xmlns.com/foaf/0.1/homepage", + knows: "http://xmlns.com/foaf/0.1/knows", +} as const -export class FOAF { - static isPrimaryTopicOf = DataFactory.namedNode("http://xmlns.com/foaf/0.1/isPrimaryTopicOf") - static primaryTopic = DataFactory.namedNode("http://xmlns.com/foaf/0.1/primaryTopic") - static fname = DataFactory.namedNode("http://xmlns.com/foaf/0.1/name") - static email = DataFactory.namedNode("http://xmlns.com/foaf/0.1/email") - static homepage = DataFactory.namedNode("http://xmlns.com/foaf/0.1/homepage") - static knows = DataFactory.namedNode("http://xmlns.com/foaf/0.1/knows") -} +export const LDP = { + contains: "http://www.w3.org/ns/ldp#contains", +} as const -export class LDP { - static contains = DataFactory.namedNode("http://www.w3.org/ns/ldp#contains") -} +export const PIM = { + storage: "http://www.w3.org/ns/pim/space#storage", +} as const -export class PIM { - static storage = DataFactory.namedNode("http://www.w3.org/ns/pim/space#storage") -} +export const POSIX = { + size: "http://www.w3.org/ns/posix/stat#size", + mtime: "http://www.w3.org/ns/posix/stat#mtime", +} as const -export class POSIX { - static size = DataFactory.namedNode("http://www.w3.org/ns/posix/stat#size") - static mtime = DataFactory.namedNode("http://www.w3.org/ns/posix/stat#mtime") -} +export const RDF = { + type: "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", +} as const -export class RDF { - static type = DataFactory.namedNode("http://www.w3.org/1999/02/22-rdf-syntax-ns#type") -} +export const RDFS = { + label: "http://www.w3.org/2000/01/rdf-schema#label", +} as const -export class RDFS { - static label = DataFactory.namedNode("http://www.w3.org/2000/01/rdf-schema#label") -} +export const SOLID = { + oidcIssuer: "http://www.w3.org/ns/solid/terms#oidcIssuer", + storage: "http://www.w3.org/ns/solid/terms#storage", +} as const -export class SOLID { - static oidcIssuer = DataFactory.namedNode("http://www.w3.org/ns/solid/terms#oidcIssuer") - static storage = DataFactory.namedNode("http://www.w3.org/ns/solid/terms#storage") -} - -export class VCARD { - static fn = DataFactory.namedNode("http://www.w3.org/2006/vcard/ns#fn") - static hasEmail = DataFactory.namedNode("http://www.w3.org/2006/vcard/ns#hasEmail") - static hasValue = DataFactory.namedNode("http://www.w3.org/2006/vcard/ns#hasValue") - static hasPhoto = DataFactory.namedNode("http://www.w3.org/2006/vcard/ns#hasPhoto") - static hasTelephone = DataFactory.namedNode("http://www.w3.org/2006/vcard/ns#hasTelephone") - static title = DataFactory.namedNode("http://www.w3.org/2006/vcard/ns#title") - static hasUrl = DataFactory.namedNode("http://www.w3.org/2006/vcard/ns#hasUrl") - static organizationName = DataFactory.namedNode("http://www.w3.org/2006/vcard/ns#organization-name") - static role = DataFactory.namedNode("http://www.w3.org/2006/vcard/ns#organization-name") -} +export const VCARD = { + fn: "http://www.w3.org/2006/vcard/ns#fn", + hasEmail: "http://www.w3.org/2006/vcard/ns#hasEmail", + hasValue: "http://www.w3.org/2006/vcard/ns#hasValue", + hasPhoto: "http://www.w3.org/2006/vcard/ns#hasPhoto", + hasTelephone: "http://www.w3.org/2006/vcard/ns#hasTelephone", + title: "http://www.w3.org/2006/vcard/ns#title", + hasUrl: "http://www.w3.org/2006/vcard/ns#hasUrl", + organizationName: "http://www.w3.org/2006/vcard/ns#organization-name", + role: "http://www.w3.org/2006/vcard/ns#organization-name", +} as const diff --git a/app/lib/class/WebIdDataset.ts b/app/lib/class/WebIdDataset.ts index a39d91a..fa60439 100644 --- a/app/lib/class/WebIdDataset.ts +++ b/app/lib/class/WebIdDataset.ts @@ -2,12 +2,12 @@ import { DatasetWrapper } from "rdfjs-wrapper" import { Agent } from "@/app/lib/class/Agent" import { SOLID } from "@/app/lib/class/Vocabulary" -export class WebIdDataset extends DatasetWrapper{ +export class WebIdDataset extends DatasetWrapper { get mainSubject(): Agent | undefined { // TODO: Fix with FOAF: Primary topic either via Inrupt or spec because this does not work with Inrupt WebID // TODO: do the isPrimaryTopicOf route and the primaryTopic (maybe) // Or not because all WebIDs will have an issuer (otherwise also needs to restrict to the document URL as subject or object to realise the benefit) - for (const s of this.subjectsOf(Agent, SOLID.oidcIssuer)) { + for (const s of this.subjectsOf(SOLID.oidcIssuer, Agent)) { return s; } } diff --git a/app/lib/helpers/acpUtils.ts b/app/lib/helpers/acpUtils.ts index 9298356..1cff865 100644 --- a/app/lib/helpers/acpUtils.ts +++ b/app/lib/helpers/acpUtils.ts @@ -180,7 +180,7 @@ async function createAcr( const acr = new AccessControlResource(namedNode(acrUrl), ds, DataFactory) // Add ACR type and resource - acr.type.add(ACP.AccessControlResource.id) + acr.type.add(ACP.AccessControlResource) acr.resource = resourceUrl; // Create Access Controls for each WebID and access mode @@ -194,16 +194,16 @@ async function createAcr( const accessControl = new AccessControl(blankNode(), ds, DataFactory) // Matcher: type and agent - matcher.type.add(ACP.Matcher.id) + matcher.type.add(ACP.Matcher) matcher.agent.add(webId) // Policy: type, allow, and anyOf (matcher) - policy.type.add(ACP.Policy.id) - policy.allow.add(ACP.mode.id) // TODO: MODE + policy.type.add(ACP.Policy) + policy.allow.add(ACP.mode) // TODO: MODE policy.anyOf.add(matcher) // AccessControl: type and apply (policy) - accessControl.type.add(ACP.AccessControl.id) + accessControl.type.add(ACP.AccessControl) accessControl.apply.add(policy) // Link AccessControl to ACR @@ -283,14 +283,14 @@ async function updateAcr( const policy = new Policy(blankNode(), ds, DataFactory) const accessControl = new AccessControl(blankNode(), ds, DataFactory) - matcher.type.add(ACP.Matcher.id) + matcher.type.add(ACP.Matcher) matcher.agent.add(webId) - policy.type.add(ACP.Policy.id) - policy.allow.add(ACP.mode.id) // TODO: MODE + policy.type.add(ACP.Policy) + policy.allow.add(ACP.mode) // TODO: MODE policy.anyOf.add(matcher) - accessControl.type.add(ACP.AccessControl.id) + accessControl.type.add(ACP.AccessControl) accessControl.apply.add(policy) acr.accessControl.add(accessControl) diff --git a/package-lock.json b/package-lock.json index 154e3d6..9045e30 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,7 @@ "jszip": "^3.10.1", "n3": "^2.0.1", "next": "16.0.7", - "rdfjs-wrapper": "^0.14.0", + "rdfjs-wrapper": "^0.28.0", "react": "19.2.1", "react-dom": "19.2.1", "react-hot-toast": "^2.6.0" @@ -16780,9 +16780,9 @@ } }, "node_modules/rdfjs-wrapper": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/rdfjs-wrapper/-/rdfjs-wrapper-0.14.0.tgz", - "integrity": "sha512-6Jt/tUa6xS37i7+ILDrmJOlzMUWhq4Z6AsA9hbgziXVnRwfWDsx2x8XaZxZXVI7Z7kI2/d2dVz1dtpWNeF3h7g==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/rdfjs-wrapper/-/rdfjs-wrapper-0.28.0.tgz", + "integrity": "sha512-i9aY2RsAO3v+ojW/w2bIL1iFIr/FK5W4NCZQtZvhwDehplz4uyt6i53opdnhk0guZdSGCIrWAmsYIAQ+Etj3iA==", "license": "MIT", "engines": { "node": ">=24.0.0" diff --git a/package.json b/package.json index 2edc854..71a269f 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "jszip": "^3.10.1", "n3": "^2.0.1", "next": "16.0.7", - "rdfjs-wrapper": "^0.14.0", + "rdfjs-wrapper": "^0.28.0", "react": "19.2.1", "react-dom": "19.2.1", "react-hot-toast": "^2.6.0"