diff --git a/packages/solid/package.json b/packages/solid/package.json
index 4f4a767..31a268f 100644
--- a/packages/solid/package.json
+++ b/packages/solid/package.json
@@ -37,6 +37,7 @@
"typed-emitter": "^2.1.0"
},
"dependencies": {
+ "@inrupt/solid-client": "^1.30.0",
"@ldo/dataset": "^0.0.0",
"@ldo/ldo": "^0.0.0",
"@ldo/rdf-utils": "^0.0.0",
diff --git a/packages/solid/src/ResourceStore.ts b/packages/solid/src/ResourceStore.ts
index 95ba596..b3fba0f 100644
--- a/packages/solid/src/ResourceStore.ts
+++ b/packages/solid/src/ResourceStore.ts
@@ -1,6 +1,5 @@
import { Container } from "./resource/Container";
import { Leaf } from "./resource/Leaf";
-import type { Resource } from "./resource/Resource";
import type { SolidLdoDatasetContext } from "./SolidLdoDatasetContext";
import type { ContainerUri, LeafUri } from "./util/uriTypes";
import { isContainerUri } from "./util/uriTypes";
@@ -10,7 +9,7 @@ export interface ResourceGetterOptions {
}
export class ResourceStore {
- protected resourceMap: Map
;
+ protected resourceMap: Map;
protected context: SolidLdoDatasetContext;
constructor(context: SolidLdoDatasetContext) {
@@ -20,8 +19,8 @@ export class ResourceStore {
get(uri: ContainerUri, options?: ResourceGetterOptions): Container;
get(uri: LeafUri, options?: ResourceGetterOptions): Leaf;
- get(uri: string, options?: ResourceGetterOptions): Resource;
- get(uri: string, options?: ResourceGetterOptions): Resource {
+ get(uri: string, options?: ResourceGetterOptions): Leaf | Container;
+ get(uri: string, options?: ResourceGetterOptions): Leaf | Container {
// Normalize URI by removing hash
const url = new URL(uri);
url.hash = "";
diff --git a/packages/solid/src/requester/requestResults/AccessRule.ts b/packages/solid/src/requester/requestResults/AccessRule.ts
new file mode 100644
index 0000000..06290b4
--- /dev/null
+++ b/packages/solid/src/requester/requestResults/AccessRule.ts
@@ -0,0 +1,51 @@
+import type { Access } from "@inrupt/solid-client";
+import { ErrorResult } from "./ErrorResult";
+import { RequesterResult } from "./RequesterResult";
+
+export interface AccessRule {
+ public?: Access;
+ agent?: Record;
+}
+
+export class AccessRuleChangeResult
+ extends RequesterResult
+ implements AccessRule
+{
+ type = "accessRuleChange" as const;
+ readonly public?: Access;
+ readonly agent?: Record;
+
+ constructor(
+ uri: string,
+ publicRules?: Access,
+ agentRules?: Record,
+ ) {
+ super(uri);
+ this.public = publicRules;
+ this.agent = agentRules;
+ }
+}
+
+export class AccessRuleResult extends RequesterResult implements AccessRule {
+ type = "accessRule" as const;
+ readonly public: Access;
+ readonly agent: Record;
+
+ constructor(
+ uri: string,
+ publicRules: Access,
+ agentRules: Record,
+ ) {
+ super(uri);
+ this.public = publicRules;
+ this.agent = agentRules;
+ }
+}
+
+export class AccessRuleFetchError extends ErrorResult {
+ readonly errorType = "accessRuleFetch" as const;
+
+ constructor(uri: string, message?: string) {
+ super(uri, message || `Cannot get access rules for ${uri}.`);
+ }
+}
diff --git a/packages/solid/src/requester/requestResults/ErrorResult.ts b/packages/solid/src/requester/requestResults/ErrorResult.ts
index 8cc2e2e..79aa760 100644
--- a/packages/solid/src/requester/requestResults/ErrorResult.ts
+++ b/packages/solid/src/requester/requestResults/ErrorResult.ts
@@ -11,7 +11,7 @@ export abstract class ErrorResult extends Error {
export class UnexpectedError extends ErrorResult {
error: Error;
- readonly errorType = "unexpected";
+ readonly errorType = "unexpected" as const;
constructor(uri: string, error: Error) {
super(uri, error.message);
@@ -31,3 +31,34 @@ export class UnexpectedError extends ErrorResult {
}
}
}
+
+export class AggregateError extends ErrorResult {
+ readonly errorType = "aggregate" as const;
+ readonly errors: ErrorType[];
+
+ constructor(
+ uri: string,
+ errors: (ErrorType | AggregateError)[],
+ message?: string,
+ ) {
+ const allErrors: ErrorType[] = [];
+ errors.forEach((error) => {
+ if (error instanceof AggregateError) {
+ error.errors.forEach((subError) => {
+ allErrors.push(subError);
+ });
+ } else {
+ allErrors.push(error);
+ }
+ });
+ super(
+ uri,
+ message ||
+ `Encountered multiple errors:${allErrors.reduce(
+ (agg, cur) => `${agg}\n${cur}`,
+ "",
+ )}`,
+ );
+ this.errors = allErrors;
+ }
+}
diff --git a/packages/solid/src/requester/requests/checkRootContainer.ts b/packages/solid/src/requester/requests/checkRootContainer.ts
index f71fb67..0f38e3a 100644
--- a/packages/solid/src/requester/requests/checkRootContainer.ts
+++ b/packages/solid/src/requester/requests/checkRootContainer.ts
@@ -3,7 +3,7 @@ import {
type HttpErrorResultType,
} from "../requestResults/HttpErrorResult";
import { UnexpectedError } from "../requestResults/ErrorResult";
-import type { RequestParams } from "./requestParams";
+import type { SimpleRequestParams } from "./requestParams";
import { parse as parseLinkHeader } from "http-link-header";
export type CheckRootResult = boolean | CheckRootResultError;
@@ -12,7 +12,7 @@ export type CheckRootResultError = HttpErrorResultType | UnexpectedError;
export async function checkRootContainer({
uri,
fetch,
-}: Omit): Promise {
+}: SimpleRequestParams): Promise {
try {
// Fetch options to determine the document type
const response = await fetch(uri, { method: "HEAD" });
diff --git a/packages/solid/src/requester/requests/createDataResource.ts b/packages/solid/src/requester/requests/createDataResource.ts
index 8df298c..2932d8b 100644
--- a/packages/solid/src/requester/requests/createDataResource.ts
+++ b/packages/solid/src/requester/requests/createDataResource.ts
@@ -3,6 +3,7 @@ import {
getParentUri,
getSlug,
} from "../../util/rdfUtils";
+import { isContainerUri } from "../../util/uriTypes";
import type { BinaryResult } from "../requestResults/BinaryResult";
import type { TurtleFormattingError } from "../requestResults/DataResult";
import { DataResult } from "../requestResults/DataResult";
@@ -57,12 +58,17 @@ export async function createDataResource(
}
// Create the document
const parentUri = getParentUri(uri)!;
+ console.log("This is the URI", uri);
+ const headers: HeadersInit = {
+ "content-type": "text/turtle",
+ slug: getSlug(uri),
+ };
+ if (isContainerUri(uri)) {
+ headers.link = '; rel="type"';
+ }
const response = await fetch(parentUri, {
method: "post",
- headers: {
- "content-type": "text/turtle",
- slug: getSlug(uri),
- },
+ headers,
});
const httpError = HttpErrorResult.checkResponse(uri, response);
diff --git a/packages/solid/src/requester/requests/getAccessRules.ts b/packages/solid/src/requester/requests/getAccessRules.ts
new file mode 100644
index 0000000..f62ee13
--- /dev/null
+++ b/packages/solid/src/requester/requests/getAccessRules.ts
@@ -0,0 +1,21 @@
+import { universalAccess } from "@inrupt/solid-client";
+import type {
+ AccessRuleFetchError,
+ AccessRuleResult,
+} from "../requestResults/AccessRule";
+import type { SimpleRequestParams } from "./requestParams";
+
+export async function getAccessRules({
+ uri,
+ fetch,
+}: SimpleRequestParams): Promise {
+ throw new Error("Not Implemented");
+ // const [publicAccess, agentAccess] = await Promise.all([
+ // universalAccess.getPublicAccess(uri, { fetch }),
+ // universalAccess.getAgentAccessAll(uri, { fetch }),
+ // ]);
+ // if (agentAccess === null || publicAccess === null) {
+ // return new AccessRuleFetchError(uri);
+ // }
+ // return new AccessRuleResult(uri, publicAccess, agentAccess);
+}
diff --git a/packages/solid/src/requester/requests/requestParams.ts b/packages/solid/src/requester/requests/requestParams.ts
index 5c47641..33f8eda 100644
--- a/packages/solid/src/requester/requests/requestParams.ts
+++ b/packages/solid/src/requester/requests/requestParams.ts
@@ -6,3 +6,5 @@ export interface RequestParams {
fetch: typeof fetch;
transaction: TransactionalDataset;
}
+
+export type SimpleRequestParams = Omit;
diff --git a/packages/solid/src/requester/requests/setAccessRules.ts b/packages/solid/src/requester/requests/setAccessRules.ts
new file mode 100644
index 0000000..9b5baa7
--- /dev/null
+++ b/packages/solid/src/requester/requests/setAccessRules.ts
@@ -0,0 +1,80 @@
+import type { AclDataset, WithChangeLog } from "@inrupt/solid-client";
+import { getAgentAccessAll } from "@inrupt/solid-client";
+import { getPublicAccess } from "@inrupt/solid-client";
+import {
+ getSolidDatasetWithAcl,
+ hasResourceAcl,
+ hasFallbackAcl,
+ hasAccessibleAcl,
+ createAclFromFallbackAcl,
+ getResourceAcl,
+ setAgentResourceAccess,
+ saveAclFor,
+ setPublicDefaultAccess,
+ setPublicResourceAccess,
+ setAgentDefaultAccess,
+} from "@inrupt/solid-client";
+import { isContainerUri } from "../../util/uriTypes";
+import type { AccessRule } from "../requestResults/AccessRule";
+import { AccessRuleChangeResult } from "../requestResults/AccessRule";
+import { AccessRuleFetchError } from "../requestResults/AccessRule";
+import type { SimpleRequestParams } from "./requestParams";
+
+export async function setAccessRules(
+ { uri, fetch }: SimpleRequestParams,
+ newAccessRules: AccessRule,
+): Promise {
+ console.warn("Access Control is stil underdeveloped. Use with caution.");
+ const isContainer = isContainerUri(uri);
+
+ // Code Copied from https://docs.inrupt.com/developer-tools/javascript/client-libraries/tutorial/manage-wac/
+ // Fetch the SolidDataset and its associated ACLs, if available:
+ const myDatasetWithAcl = await getSolidDatasetWithAcl(uri, { fetch });
+
+ // Obtain the SolidDataset's own ACL, if available,
+ // or initialise a new one, if possible:
+ let resourceAcl;
+ if (!hasResourceAcl(myDatasetWithAcl)) {
+ if (!hasAccessibleAcl(myDatasetWithAcl)) {
+ return new AccessRuleFetchError(
+ uri,
+ "The current user does not have permission to change access rights to this Resource.",
+ );
+ }
+ if (!hasFallbackAcl(myDatasetWithAcl)) {
+ return new AccessRuleFetchError(
+ "The current user does not have permission to see who currently has access to this Resource.",
+ );
+ }
+ resourceAcl = createAclFromFallbackAcl(myDatasetWithAcl);
+ } else {
+ resourceAcl = getResourceAcl(myDatasetWithAcl);
+ }
+
+ // Give someone Control access to the given Resource:
+
+ let updatedAcl: AclDataset & WithChangeLog = resourceAcl;
+ if (newAccessRules.public) {
+ if (isContainer) {
+ updatedAcl = setPublicDefaultAccess(updatedAcl, newAccessRules.public);
+ } else {
+ updatedAcl = setPublicResourceAccess(updatedAcl, newAccessRules.public);
+ }
+ }
+ if (newAccessRules.agent) {
+ const setAgentAccess = isContainer
+ ? setAgentDefaultAccess
+ : setAgentResourceAccess;
+ Object.entries(newAccessRules.agent).forEach(([webId, rules]) => {
+ updatedAcl = setAgentAccess(updatedAcl, webId, rules);
+ });
+ }
+
+ // Now save the ACL:
+ await saveAclFor(myDatasetWithAcl, updatedAcl, { fetch });
+ return new AccessRuleChangeResult(
+ uri,
+ getPublicAccess(myDatasetWithAcl) || undefined,
+ getAgentAccessAll(myDatasetWithAcl) || undefined,
+ );
+}
diff --git a/packages/solid/src/requester/requests/uploadResource.ts b/packages/solid/src/requester/requests/uploadResource.ts
index 50fd4c3..b52ad84 100644
--- a/packages/solid/src/requester/requests/uploadResource.ts
+++ b/packages/solid/src/requester/requests/uploadResource.ts
@@ -44,13 +44,13 @@ export function uploadResource(
blob: Blob,
mimeType: string,
overwrite?: boolean,
-): Promise;
+): Promise;
export async function uploadResource(
params: RequestParams,
blob: Blob,
mimeType: string,
overwrite?: boolean,
-): Promise {
+): Promise {
const { uri, transaction, fetch } = params;
try {
if (overwrite) {
diff --git a/packages/solid/src/resource/Container.ts b/packages/solid/src/resource/Container.ts
index ab413b6..0088214 100644
--- a/packages/solid/src/resource/Container.ts
+++ b/packages/solid/src/resource/Container.ts
@@ -1,9 +1,20 @@
+import { namedNode } from "@rdfjs/data-model";
import { ContainerRequester } from "../requester/ContainerRequester";
-import { UnexpectedError } from "../requester/requestResults/ErrorResult";
+import {
+ AggregateError,
+ UnexpectedError,
+} from "../requester/requestResults/ErrorResult";
import type { CheckRootResultError } from "../requester/requests/checkRootContainer";
+import type {
+ CreateResultErrors,
+ CreateResultWithoutOverwriteErrors,
+} from "../requester/requests/createDataResource";
+import type { DeleteResultError } from "../requester/requests/deleteResource";
+import type { ReadResultError } from "../requester/requests/readResource";
import type { SolidLdoDatasetContext } from "../SolidLdoDatasetContext";
-import { getParentUri } from "../util/rdfUtils";
-import type { ContainerUri } from "../util/uriTypes";
+import { getParentUri, ldpContains } from "../util/rdfUtils";
+import type { ContainerUri, LeafUri } from "../util/uriTypes";
+import type { Leaf } from "./Leaf";
import { Resource } from "./Resource";
export class Container extends Resource {
@@ -20,11 +31,9 @@ export class Container extends Resource {
return this.rootContainer;
}
- getParentContainer(): Promise {
- throw new Error("Method not implemented.");
- }
-
- async getRootContainer(): Promise {
+ private async checkIfIsRootContainer(): Promise<
+ CheckRootResultError | undefined
+ > {
if (this.rootContainer === undefined) {
const rootContainerResult = await this.requester.isRootContainer();
if (typeof rootContainerResult !== "boolean") {
@@ -32,6 +41,27 @@ export class Container extends Resource {
}
this.rootContainer = rootContainerResult;
}
+ }
+
+ async getParentContainer(): Promise<
+ Container | CheckRootResultError | undefined
+ > {
+ const checkResult = await this.checkIfIsRootContainer();
+ if (checkResult) return checkResult;
+ if (this.rootContainer) return undefined;
+ const parentUri = getParentUri(this.uri);
+ if (!parentUri) {
+ return new UnexpectedError(
+ this.uri,
+ new Error("Resource does not have a root container"),
+ );
+ }
+ return this.context.resourceStore.get(parentUri);
+ }
+
+ async getRootContainer(): Promise {
+ const checkResult = await this.checkIfIsRootContainer();
+ if (checkResult) return checkResult;
if (this.rootContainer) {
return this;
}
@@ -42,10 +72,86 @@ export class Container extends Resource {
new Error("Resource does not have a root container"),
);
}
- return this.context.resourceStore.get(parentUri);
+ return this.context.resourceStore.get(parentUri).getRootContainer();
+ }
+
+ children(): (Leaf | Container)[] {
+ const childQuads = this.context.solidLdoDataset.match(
+ namedNode(this.uri),
+ ldpContains,
+ null,
+ namedNode(this.uri),
+ );
+ return childQuads.toArray().map((childQuad) => {
+ return this.context.resourceStore.get(childQuad.object.value);
+ });
+ }
+
+ createChildAndOverwrite(
+ slug: ContainerUri,
+ ): Promise;
+ createChildAndOverwrite(slug: LeafUri): Promise;
+ createChildAndOverwrite(slug: string): Promise;
+ createChildAndOverwrite(
+ slug: string,
+ ): Promise {
+ const resource = this.context.resourceStore.get(`${this.uri}${slug}`);
+ return resource.createAndOverwrite();
+ }
+
+ createChildIfAbsent(
+ slug: ContainerUri,
+ ): Promise;
+ createChildIfAbsent(
+ slug: LeafUri,
+ ): Promise;
+ createChildIfAbsent(
+ slug: string,
+ ): Promise;
+ createChildIfAbsent(
+ slug: string,
+ ): Promise {
+ const resource = this.context.resourceStore.get(`${this.uri}${slug}`);
+ return resource.createIfAbsent();
+ }
+
+ async clear(): Promise<
+ AggregateError | this
+ > {
+ const readResult = await this.read();
+ if (readResult.type === "error")
+ return new AggregateError(this.uri, [readResult]);
+ const errors = (
+ await Promise.all(
+ this.children().map(async (child) => {
+ const deleteError = await child.delete();
+ if (deleteError.type === "error") return deleteError;
+ }),
+ )
+ )
+ .flat()
+ .filter(
+ (
+ value,
+ ): value is
+ | DeleteResultError
+ | AggregateError => !!value,
+ );
+ if (errors.length > 0) {
+ return new AggregateError(this.uri, errors);
+ }
+ return this;
}
- getMimeType(): string {
- throw new Error("Method not implemented.");
+ async delete(): Promise<
+ | this
+ | AggregateError
+ | DeleteResultError
+ > {
+ const clearResult = await this.clear();
+ if (clearResult.type === "error") return clearResult;
+ return this.parseResult(await this.requester.delete()) as
+ | this
+ | DeleteResultError;
}
}
diff --git a/packages/solid/src/resource/Leaf.ts b/packages/solid/src/resource/Leaf.ts
index 114337e..d9c062b 100644
--- a/packages/solid/src/resource/Leaf.ts
+++ b/packages/solid/src/resource/Leaf.ts
@@ -1,7 +1,12 @@
import type { DatasetChanges } from "@ldo/rdf-utils";
import { LeafRequester } from "../requester/LeafRequester";
import type { Requester } from "../requester/Requester";
+import type { AbsentResult } from "../requester/requestResults/AbsentResult";
+import type { BinaryResult } from "../requester/requestResults/BinaryResult";
+import type { DataResult } from "../requester/requestResults/DataResult";
+import type { ErrorResult } from "../requester/requestResults/ErrorResult";
import type { CheckRootResultError } from "../requester/requests/checkRootContainer";
+import type { DeleteResultError } from "../requester/requests/deleteResource";
import type { UpdateResultError } from "../requester/requests/updateDataResource";
import type {
UploadResultError,
@@ -17,21 +22,38 @@ export class Leaf extends Resource {
protected requester: Requester;
readonly type = "leaf" as const;
+ protected binaryData: { data: Blob; mimeType: string } | undefined;
+
constructor(uri: LeafUri, context: SolidLdoDatasetContext) {
super(uri, context);
this.requester = new LeafRequester(uri, context);
}
- getParentContainer(): Promise {
- throw new Error("Method not implemented.");
+ protected parseResult(
+ result: AbsentResult | BinaryResult | DataResult | PossibleErrors,
+ ): this | PossibleErrors {
+ if (result.type === "binary") {
+ this.binaryData = {
+ data: result.blob,
+ mimeType: result.mimeType,
+ };
+ } else {
+ delete this.binaryData;
+ }
+ return super.parseResult(result);
+ }
+
+ getParentContainer(): Container {
+ const parentUri = getParentUri(this.uri)!;
+ return this.context.resourceStore.get(parentUri);
}
getRootContainer(): Promise {
const parentUri = getParentUri(this.uri)!;
const parent = this.context.resourceStore.get(parentUri);
return parent.getRootContainer();
}
- getMimeType(): string {
- throw new Error("Method not implemented.");
+ getMimeType(): string | undefined {
+ return this.binaryData?.mimeType;
}
isBinary(): boolean | undefined {
if (!this.didInitialFetch) {
@@ -50,21 +72,22 @@ export class Leaf extends Resource {
blob: Blob,
mimeType: string,
): Promise {
- return this.parseResult(await this.requester.upload(blob, mimeType)) as
- | this
- | UploadResultError;
+ return this.parseResult(await this.requester.upload(blob, mimeType, true));
}
async uploadIfAbsent(
blob: Blob,
mimeType: string,
): Promise {
- return this.parseResult(
- await this.requester.upload(blob, mimeType, true),
- ) as this | UploadResultWithoutOverwriteError;
+ return this.parseResult(await this.requester.upload(blob, mimeType));
}
update(_changes: DatasetChanges): Promise {
throw new Error("Method not implemented");
}
+
+ // Delete Method
+ async delete(): Promise {
+ return this.parseResult(await this.requester.delete());
+ }
}
diff --git a/packages/solid/src/resource/Resource.ts b/packages/solid/src/resource/Resource.ts
index 1ff8c74..9b72b1a 100644
--- a/packages/solid/src/resource/Resource.ts
+++ b/packages/solid/src/resource/Resource.ts
@@ -2,19 +2,23 @@ import type { SolidLdoDatasetContext } from "../SolidLdoDatasetContext";
import type { AbsentResult } from "../requester/requestResults/AbsentResult";
import type { BinaryResult } from "../requester/requestResults/BinaryResult";
import type { DataResult } from "../requester/requestResults/DataResult";
-import {
- UnexpectedError,
- type ErrorResult,
-} from "../requester/requestResults/ErrorResult";
+import { type ErrorResult } from "../requester/requestResults/ErrorResult";
import type {
CreateResultErrors,
CreateResultWithoutOverwriteErrors,
} from "../requester/requests/createDataResource";
-import type { DeleteResultError } from "../requester/requests/deleteResource";
import type { ReadResultError } from "../requester/requests/readResource";
import type { Container } from "./Container";
import type { Requester } from "../requester/Requester";
import type { CheckRootResultError } from "../requester/requests/checkRootContainer";
+import type {
+ AccessRule,
+ AccessRuleChangeResult,
+ AccessRuleFetchError,
+ AccessRuleResult,
+} from "../requester/requestResults/AccessRule";
+import { getAccessRules } from "../requester/requests/getAccessRules";
+import { setAccessRules } from "../requester/requests/setAccessRules";
export abstract class Resource {
// All intance variables
@@ -24,7 +28,6 @@ export abstract class Resource {
protected abstract readonly requester: Requester;
protected didInitialFetch: boolean = false;
protected absent: boolean | undefined;
- protected binaryData: { data: Blob; mimeType: string } | undefined;
constructor(uri: string, context: SolidLdoDatasetContext) {
this.uri = uri;
@@ -68,43 +71,26 @@ export abstract class Resource {
return this.absent === undefined ? undefined : !this.absent;
}
- protected parseResult(
- result: AbsentResult | BinaryResult | DataResult | ErrorResult,
- ) {
+ protected parseResult(
+ result: AbsentResult | BinaryResult | DataResult | PossibleErrors,
+ ): this | PossibleErrors {
switch (result.type) {
case "error":
return result;
case "absent":
this.didInitialFetch = true;
this.absent = true;
- delete this.binaryData;
- return this;
- case "data":
- this.didInitialFetch = true;
- this.absent = false;
- delete this.binaryData;
return this;
- case "binary":
+ default:
this.didInitialFetch = true;
this.absent = false;
- this.binaryData = {
- data: result.blob,
- mimeType: result.mimeType,
- };
return this;
- default:
- return new UnexpectedError(
- this.uri,
- new Error("Unknown request result"),
- );
}
}
// Read Methods
async read(): Promise {
- return this.parseResult(await this.requester.read()) as
- | this
- | ReadResultError;
+ return this.parseResult(await this.requester.read());
}
async readIfUnfetched(): Promise {
if (this.didInitialFetch) {
@@ -115,30 +101,26 @@ export abstract class Resource {
// Create Methods
async createAndOverwrite(): Promise {
- return this.parseResult(await this.requester.createDataResource(true)) as
- | this
- | CreateResultErrors;
+ return this.parseResult(await this.requester.createDataResource(true));
}
async createIfAbsent(): Promise {
- return this.parseResult(await this.requester.createDataResource()) as
- | this
- | CreateResultWithoutOverwriteErrors;
- }
-
- // Delete Method
- async delete(): Promise {
- return this.parseResult(await this.requester.delete()) as
- | Resource
- | DeleteResultError;
+ return this.parseResult(await this.requester.createDataResource());
}
// Parent Container Methods -- Remember to change for Container
- abstract getParentContainer(): Promise;
abstract getRootContainer(): Promise;
- // Exclusing Methods =========================================================
- // Data Methods (Data Leaf Only)
- // Binary Methods (Binary Only)
- abstract getMimeType(): string;
+ async getAccessRules(): Promise {
+ return getAccessRules({ uri: this.uri, fetch: this.context.fetch });
+ }
+
+ async setAccessRules(
+ newAccessRules: AccessRule,
+ ): Promise {
+ return setAccessRules(
+ { uri: this.uri, fetch: this.context.fetch },
+ newAccessRules,
+ );
+ }
}
diff --git a/packages/solid/src/util/rdfUtils.ts b/packages/solid/src/util/rdfUtils.ts
index 882e393..75f3cb2 100644
--- a/packages/solid/src/util/rdfUtils.ts
+++ b/packages/solid/src/util/rdfUtils.ts
@@ -6,11 +6,15 @@ import type { Dataset } from "@rdfjs/types";
import type { ContainerUri } from "./uriTypes";
import { isContainerUri } from "./uriTypes";
-const ldpContains = namedNode("http://www.w3.org/ns/ldp#contains");
-const rdfType = namedNode("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
-const ldpResource = namedNode("http://www.w3.org/ns/ldp#Resource");
-const ldpContainer = namedNode("http://www.w3.org/ns/ldp#Container");
-const ldpBasicContainer = namedNode("http://www.w3.org/ns/ldp#BasicContainer");
+export const ldpContains = namedNode("http://www.w3.org/ns/ldp#contains");
+export const rdfType = namedNode(
+ "http://www.w3.org/1999/02/22-rdf-syntax-ns#type",
+);
+export const ldpResource = namedNode("http://www.w3.org/ns/ldp#Resource");
+export const ldpContainer = namedNode("http://www.w3.org/ns/ldp#Container");
+export const ldpBasicContainer = namedNode(
+ "http://www.w3.org/ns/ldp#BasicContainer",
+);
export function getParentUri(uri: string): ContainerUri | undefined {
const urlObject = new URL(uri);
@@ -32,7 +36,7 @@ export function getParentUri(uri: string): ContainerUri | undefined {
export function getSlug(uri: string): string {
const urlObject = new URL(uri);
const pathItems = urlObject.pathname.split("/");
- return pathItems[pathItems.length - 1];
+ return pathItems[pathItems.length - 1] || pathItems[pathItems.length - 2];
}
export function deleteResourceRdfFromContainer(