diff --git a/app/lib/class/ContainerDataset.ts b/app/lib/class/ContainerDataset.ts index 854ca4f..63bfb21 100644 --- a/app/lib/class/ContainerDataset.ts +++ b/app/lib/class/ContainerDataset.ts @@ -1,13 +1,21 @@ -import { DatasetWrapper } from "@rdfjs/wrapper" -import { Container } from "@/app/lib/class/Container" -import { LDP } from "@/app/lib/class/Vocabulary" +import { DatasetWrapper } from "@rdfjs/wrapper"; +import { Container } from "@/app/lib/class/Container"; +import { LDP } from "@/app/lib/class/Vocabulary"; 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(LDP.contains, Container)) { - return s; - } + get container(): Container | undefined { + // Non-empty containers advertise children via ldp:contains. + for (const s of this.subjectsOf(LDP.contains, Container)) { + return s; } + + // Empty containers have no ldp:contains; resolve via rdf:type instead. + for (const s of this.instancesOf(LDP.Container, Container)) { + return s; + } + + for (const s of this.instancesOf(LDP.BasicContainer, Container)) { + return s; + } + } } diff --git a/app/lib/class/Vocabulary.ts b/app/lib/class/Vocabulary.ts index 9e2df10..d4182c5 100644 --- a/app/lib/class/Vocabulary.ts +++ b/app/lib/class/Vocabulary.ts @@ -29,6 +29,8 @@ export const FOAF = { export const LDP = { contains: "http://www.w3.org/ns/ldp#contains", + Container: "http://www.w3.org/ns/ldp#Container", + BasicContainer: "http://www.w3.org/ns/ldp#BasicContainer", } as const export const PIM = { diff --git a/app/lib/hooks/useBrowseStorage.ts b/app/lib/hooks/useBrowseStorage.ts index f507317..7ae40ac 100644 --- a/app/lib/hooks/useBrowseStorage.ts +++ b/app/lib/hooks/useBrowseStorage.ts @@ -58,7 +58,7 @@ export function useBrowseStorage(containerUrl: string | null, refreshKey?: numbe .container if (container === undefined) { - throw new Error() // TODO: Handle properly + throw new Error("Could not identify the storage container in the listing response") } const fileItems: FileItemData[] = []; diff --git a/package-lock.json b/package-lock.json index 2ac325a..9cf56db 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,7 @@ "react": "19.2.1", "react-dom": "19.2.1", "react-hot-toast": "^2.6.0", - "solid-react-component": "^0.2.1" + "solid-react-component": "^0.2.2" }, "devDependencies": { "@solid/community-server": "^8.0.0-alpha.1", @@ -80,6 +80,7 @@ "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", @@ -8773,6 +8774,7 @@ "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -8949,6 +8951,7 @@ "integrity": "sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.56.1", "@typescript-eslint/types": "8.56.1", @@ -9522,6 +9525,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -9994,6 +9998,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -10663,7 +10668,8 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/damerau-levenshtein": { "version": "1.0.8", @@ -11255,6 +11261,7 @@ "integrity": "sha512-VmQ+sifHUbI/IcSopBCF/HO3YiHQx/AVd3UVyYL6weuwW+HvON9VYn5l6Zl1WZzPWXPNZrSQpxwkkZ/VuvJZzg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -11440,6 +11447,7 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -13663,6 +13671,7 @@ "integrity": "sha512-2LOQnFKu3m0VxpE+5sb5+BRTSKrXmNxGgxVRiKwD9s5KQB1zID/FRXhtzeV7RT1L2GVpdEEAfVuclFOMGl1ikA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "accepts": "^1.3.8", "content-disposition": "~1.0.1", @@ -13706,6 +13715,7 @@ "resolved": "https://registry.npmjs.org/ky/-/ky-0.25.1.tgz", "integrity": "sha512-PjpCEWlIU7VpiMVrTwssahkYXX1by6NCT0fhTUX34F3DTinARlgMpriuroolugFPcMgpPWrOW4mTb984Qm1RXA==", "license": "MIT", + "peer": true, "engines": { "node": ">=10" }, @@ -15873,6 +15883,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.1.tgz", "integrity": "sha512-DGrYcCWK7tvYMnWh79yrPHt+vdx9tY+1gPZa7nJQtO/p8bLTDaHp4dzwEhQB7pZ4Xe3ok4XKuEPrVuc+wlpkmw==", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -15882,6 +15893,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.1.tgz", "integrity": "sha512-ibrK8llX2a4eOskq1mXKu/TGZj9qzomO+sNfO98M6d9zIPOEhlBkMkBUBLd1vgS0gQsLDBzA+8jJBVXDnfHmJg==", "license": "MIT", + "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -16670,9 +16682,10 @@ } }, "node_modules/solid-react-component": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/solid-react-component/-/solid-react-component-0.2.1.tgz", - "integrity": "sha512-gENFQeJLeXqPo51UD+PRP8YTbflSsxwceiFAbv0c4DQM3fvbq6OtiHejWZsZoGrqHwd+Sh5h8SR4wGhN976rcg==", + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/solid-react-component/-/solid-react-component-0.2.8.tgz", + "integrity": "sha512-Tn3oA1ctUsmOKH1TLNzyRpRt/w8URZpG5W+8rS9AdLsBQOY1/7pJ/zoJXnrRxWIXSplgk/F/4rRQffzFE5230g==", + "deprecated": "Moved to @solid/react-component", "license": "MIT", "peerDependencies": { "@ldo/solid-react": ">=1.0.0-alpha.33", @@ -17287,6 +17300,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -17554,6 +17568,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -18114,6 +18129,7 @@ "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", "dev": true, "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" }