diff --git a/CITATION.bib b/CITATION.bib index f6033e2..7eaf9ba 100644 --- a/CITATION.bib +++ b/CITATION.bib @@ -2,7 +2,7 @@ @misc{solidcockpit_2026 author = {Crum, Elias}, title = {{Solid Cockpit}}, year = {2026}, - version = {1.0.0}, + version = {1.3.0}, publisher = {GitHub}, howpublished = {\\url{https://github.com/KNowledgeOnWebScale/solid-cockpit}}, note = {Software. Web app: \\url{https://knowledgeonwebscale.github.io/solid-cockpit}.} diff --git a/CITATION.cff b/CITATION.cff index eda3b99..b52c533 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -2,8 +2,8 @@ cff-version: 1.2.0 message: "If you use Solid Cockpit in academic work, please cite it using the metadata below." title: "Solid Cockpit" type: software -version: "1.0.0" -date-released: 2026-03-04 +version: "1.3.0" +date-released: 2026-06-04 license: "MIT" authors: - family-names: "Crum" diff --git a/README.md b/README.md index 8c365d8..4c1d95e 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,7 @@ ![Solid Cockpit Header Logo](./src/assets/full-sc-logo.png "SC Logo") # Solid Cockpit - -![Version](https://img.shields.io/badge/version-1.2.0-blue) +![Version](https://img.shields.io/badge/version-1.3.0-blue) ![Vue](https://img.shields.io/badge/vue-3.2.13-42b883) ![Vite](https://img.shields.io/badge/vite-6.2.3-646cff) ![License](https://img.shields.io/badge/license-MIT-green) @@ -74,7 +73,7 @@ Then upload `void.ttl` to the pod root using the app's `Data Upload` page. If you use this tool in an academic publication, you can cite: -`Crum, E. (2026). Solid Cockpit (Version 1.0.0) [Software]. GitHub. https://github.com/KNowledgeOnWebScale/solid-cockpit` +`Crum, E. (2026). Solid Cockpit (Version 1.3.0) [Software]. GitHub. https://github.com/KNowledgeOnWebScale/solid-cockpit` BibTeX: @@ -83,7 +82,7 @@ BibTeX: author = {Crum, Elias}, title = {{Solid Cockpit}}, year = {2026}, - version = {1.0.0}, + version = {1.3.0}, publisher = {GitHub}, howpublished = {\url{https://github.com/KNowledgeOnWebScale/solid-cockpit}}, note = {Software. Web app: \url{https://knowledgeonwebscale.github.io/solid-cockpit}. Accessed: 2026-03-04} @@ -264,13 +263,13 @@ CI compliance check: Current app version: -- `package.json` version: `1.0.0` -- web-app release tag convention: `web-app-v` -- current computed web-app tag: `web-app-v1.0.0` +- `package.json` version: `1.3.0` +- release tag convention: `v` +- current computed release tag: `v1.3.0` In-app visibility: -- Footer displays semantic version (`vX.Y.Z`) and computed release tag (`web-app-vX.Y.Z`) +- Footer displays semantic version (`vX.Y.Z`). - Values are injected at build time from `package.json` via Vite defines Recommended release workflow: @@ -278,7 +277,7 @@ Recommended release workflow: 1. Update version: ```bash -npm version X.Y.Z +npm run version:bump -- X.Y.Z ``` 2. Build and validate: @@ -292,8 +291,7 @@ npm run build:highmem ```bash git tag vX.Y.Z -git tag web-app-vX.Y.Z -git push origin vX.Y.Z web-app-vX.Y.Z +git push origin vX.Y.Z ``` ### Deployment diff --git a/package-lock.json b/package-lock.json index 822dfbb..b5b6e03 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "solid-cockpit", - "version": "1.2.0", + "version": "1.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "solid-cockpit", - "version": "1.2.0", + "version": "1.3.0", "license": "MIT", "dependencies": { "@comunica/context-entries": "^5.2.0", @@ -25,7 +25,10 @@ "actor-query-process-remote-cache": "^0.1.0", "core-js": "^3.8.3", "fs": "^0.0.1-security", + "jsonld": "^9.0.0", "material-icons": "^1.13.14", + "n3": "^2.0.3", + "papaparse": "^5.5.3", "pinia": "^2.3.1", "query-sparql-remote-cache": "^0.0.9", "sparqljs": "^3.7.3", @@ -16833,6 +16836,18 @@ "jsonld-context-parse": "bin/jsonld-context-parse.js" } }, + "node_modules/@comunica/actor-rdf-parse-n3/node_modules/n3": { + "version": "1.26.0", + "resolved": "https://registry.npmjs.org/n3/-/n3-1.26.0.tgz", + "integrity": "sha512-SQknS0ua90rN+3RHuk8BeIqeYyqIH/+ecViZxX08jR4j6MugqWRjtONl3uANG/crWXnOM2WIqBJtjIhVYFha+w==", + "dependencies": { + "buffer": "^6.0.3", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">=12.0" + } + }, "node_modules/@comunica/actor-rdf-parse-n3/node_modules/rdf-data-factory": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/rdf-data-factory/-/rdf-data-factory-2.0.2.tgz", @@ -17268,6 +17283,18 @@ "n3": "^1.17.0" } }, + "node_modules/@comunica/actor-rdf-serialize-n3/node_modules/n3": { + "version": "1.26.0", + "resolved": "https://registry.npmjs.org/n3/-/n3-1.26.0.tgz", + "integrity": "sha512-SQknS0ua90rN+3RHuk8BeIqeYyqIH/+ecViZxX08jR4j6MugqWRjtONl3uANG/crWXnOM2WIqBJtjIhVYFha+w==", + "dependencies": { + "buffer": "^6.0.3", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">=12.0" + } + }, "node_modules/@comunica/actor-rdf-serialize-shaclc": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-serialize-shaclc/-/actor-rdf-serialize-shaclc-4.2.0.tgz", @@ -24645,18 +24672,6 @@ "entities": "^4.5.0" } }, - "node_modules/@comunica/query-sparql-link-traversal-solid/node_modules/n3": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/n3/-/n3-2.0.3.tgz", - "integrity": "sha512-um/toGVENTarHBYIK2TdH6ByBhW75WpdKpv8iTYt9wF2QfBk8s8a16iaWZFUAAC1BKfGdb99kfgx6pltdDwfKA==", - "dependencies": { - "buffer": "^6.0.3", - "readable-stream": "^4.0.0" - }, - "engines": { - "node": ">=12.0" - } - }, "node_modules/@comunica/query-sparql-link-traversal-solid/node_modules/rdf-data-factory": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/rdf-data-factory/-/rdf-data-factory-2.0.2.tgz", @@ -29354,18 +29369,6 @@ "entities": "^4.5.0" } }, - "node_modules/@comunica/query-sparql-solid/node_modules/n3": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/n3/-/n3-2.0.3.tgz", - "integrity": "sha512-um/toGVENTarHBYIK2TdH6ByBhW75WpdKpv8iTYt9wF2QfBk8s8a16iaWZFUAAC1BKfGdb99kfgx6pltdDwfKA==", - "dependencies": { - "buffer": "^6.0.3", - "readable-stream": "^4.0.0" - }, - "engines": { - "node": ">=12.0" - } - }, "node_modules/@comunica/query-sparql-solid/node_modules/rdf-data-factory": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/rdf-data-factory/-/rdf-data-factory-2.0.2.tgz", @@ -33780,18 +33783,6 @@ "entities": "^4.5.0" } }, - "node_modules/@comunica/query-sparql/node_modules/n3": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/n3/-/n3-2.0.3.tgz", - "integrity": "sha512-um/toGVENTarHBYIK2TdH6ByBhW75WpdKpv8iTYt9wF2QfBk8s8a16iaWZFUAAC1BKfGdb99kfgx6pltdDwfKA==", - "dependencies": { - "buffer": "^6.0.3", - "readable-stream": "^4.0.0" - }, - "engines": { - "node": ">=12.0" - } - }, "node_modules/@comunica/query-sparql/node_modules/rdf-data-factory": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/rdf-data-factory/-/rdf-data-factory-2.0.2.tgz", @@ -34623,6 +34614,26 @@ "kuler": "^2.0.0" } }, + "node_modules/@digitalbazaar/http-client": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@digitalbazaar/http-client/-/http-client-4.3.0.tgz", + "integrity": "sha512-6lMpxpt9BOmqHKGs9Xm6DP4LlZTBFer/ZjHvP3FcW3IaUWYIWC7dw5RFZnvw4fP57kAVcm1dp3IF+Y50qhBvAw==", + "dependencies": { + "ky": "^1.14.2", + "undici": "^6.23.0" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@digitalbazaar/http-client/node_modules/undici": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.26.0.tgz", + "integrity": "sha512-4yqz8a3n5HmGTlsbADNtr/dJlhkh/55Rq798G6ibiULcXbDtaLpTl1pvdqcbFfeoj3iSi52lePFM7h9H21cw/A==", + "engines": { + "node": ">=18.17" + } + }, "node_modules/@esbuild/darwin-arm64": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.9.tgz", @@ -34925,6 +34936,18 @@ "url": "https://github.com/sponsors/rubensworks/" } }, + "node_modules/@inrupt/solid-client/node_modules/n3": { + "version": "1.26.0", + "resolved": "https://registry.npmjs.org/n3/-/n3-1.26.0.tgz", + "integrity": "sha512-SQknS0ua90rN+3RHuk8BeIqeYyqIH/+ecViZxX08jR4j6MugqWRjtONl3uANG/crWXnOM2WIqBJtjIhVYFha+w==", + "dependencies": { + "buffer": "^6.0.3", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">=12.0" + } + }, "node_modules/@inrupt/solid-client/node_modules/rdf-data-factory": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/rdf-data-factory/-/rdf-data-factory-2.0.2.tgz", @@ -35966,6 +35989,18 @@ "@triply/yasgui": "4.x" } }, + "node_modules/@triply/yasr/node_modules/n3": { + "version": "1.26.0", + "resolved": "https://registry.npmjs.org/n3/-/n3-1.26.0.tgz", + "integrity": "sha512-SQknS0ua90rN+3RHuk8BeIqeYyqIH/+ecViZxX08jR4j6MugqWRjtONl3uANG/crWXnOM2WIqBJtjIhVYFha+w==", + "dependencies": { + "buffer": "^6.0.3", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">=12.0" + } + }, "node_modules/@tsconfig/node22": { "version": "22.0.5", "resolved": "https://registry.npmjs.org/@tsconfig/node22/-/node22-22.0.5.tgz", @@ -38476,6 +38511,18 @@ "fetch-sparql-endpoint": "bin/fetch-sparql-endpoint.js" } }, + "node_modules/fetch-sparql-endpoint/node_modules/n3": { + "version": "1.26.0", + "resolved": "https://registry.npmjs.org/n3/-/n3-1.26.0.tgz", + "integrity": "sha512-SQknS0ua90rN+3RHuk8BeIqeYyqIH/+ecViZxX08jR4j6MugqWRjtONl3uANG/crWXnOM2WIqBJtjIhVYFha+w==", + "dependencies": { + "buffer": "^6.0.3", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">=12.0" + } + }, "node_modules/fetch-sparql-endpoint/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -39599,6 +39646,20 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jsonld": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/jsonld/-/jsonld-9.0.0.tgz", + "integrity": "sha512-pjMIdkXfC1T2wrX9B9i2uXhGdyCmgec3qgMht+TDj+S0qX3bjWMQUfL7NeqEhuRTi8G5ESzmL9uGlST7nzSEWg==", + "dependencies": { + "@digitalbazaar/http-client": "^4.2.0", + "canonicalize": "^2.1.0", + "lru-cache": "^6.0.0", + "rdf-canonize": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/jsonld-context-parser": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsonld-context-parser/-/jsonld-context-parser-3.1.0.tgz", @@ -39671,6 +39732,25 @@ "url": "https://github.com/sponsors/rubensworks/" } }, + "node_modules/jsonld/node_modules/canonicalize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/canonicalize/-/canonicalize-2.1.0.tgz", + "integrity": "sha512-F705O3xrsUtgt98j7leetNhTWPe+5S72rlL5O4jA1pKqBVQ/dT1O1D6PFxmSXvc0SUOinWS57DKx0I3CHrXJHQ==", + "bin": { + "canonicalize": "bin/canonicalize.js" + } + }, + "node_modules/jsonld/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/jsonparse": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", @@ -39712,6 +39792,17 @@ "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==", "license": "MIT" }, + "node_modules/ky": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/ky/-/ky-1.14.3.tgz", + "integrity": "sha512-9zy9lkjac+TR1c2tG+mkNSVlyOpInnWdSMiue4F+kq8TwJSgv6o8jhLRg8Ho6SnZ9wOYUq/yozts9qQCfk7bIw==", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sindresorhus/ky?sponsor=1" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -39985,10 +40076,9 @@ "license": "MIT" }, "node_modules/n3": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/n3/-/n3-1.26.0.tgz", - "integrity": "sha512-SQknS0ua90rN+3RHuk8BeIqeYyqIH/+ecViZxX08jR4j6MugqWRjtONl3uANG/crWXnOM2WIqBJtjIhVYFha+w==", - "license": "MIT", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/n3/-/n3-2.0.3.tgz", + "integrity": "sha512-um/toGVENTarHBYIK2TdH6ByBhW75WpdKpv8iTYt9wF2QfBk8s8a16iaWZFUAAC1BKfGdb99kfgx6pltdDwfKA==", "dependencies": { "buffer": "^6.0.3", "readable-stream": "^4.0.0" @@ -40321,8 +40411,7 @@ "node_modules/papaparse": { "version": "5.5.3", "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.5.3.tgz", - "integrity": "sha512-5QvjGxYVjxO59MGU2lHVYpRWBBtKHnlIAcSe1uNFCkkptUh63NFRj0FJQm7nR67puEruUci/ZkjmEFrjCAyP4A==", - "license": "MIT" + "integrity": "sha512-5QvjGxYVjxO59MGU2lHVYpRWBBtKHnlIAcSe1uNFCkkptUh63NFRj0FJQm7nR67puEruUci/ZkjmEFrjCAyP4A==" }, "node_modules/parent-module": { "version": "1.0.1", @@ -41160,6 +41249,17 @@ "safe-buffer": "^5.1.0" } }, + "node_modules/rdf-canonize": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/rdf-canonize/-/rdf-canonize-5.0.0.tgz", + "integrity": "sha512-g8OUrgMXAR9ys/ZuJVfBr05sPPoMA7nHIVs8VEvg9QwM5W4GR2qSFEEHjsyHF1eWlBaf8Ev40WNjQFQ+nJTO3w==", + "dependencies": { + "setimmediate": "^1.0.5" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/rdf-data-factory": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/rdf-data-factory/-/rdf-data-factory-1.1.3.tgz", @@ -41868,6 +41968,18 @@ "readable-stream": "^4.0.0" } }, + "node_modules/rdf-parse/node_modules/n3": { + "version": "1.26.0", + "resolved": "https://registry.npmjs.org/n3/-/n3-1.26.0.tgz", + "integrity": "sha512-SQknS0ua90rN+3RHuk8BeIqeYyqIH/+ecViZxX08jR4j6MugqWRjtONl3uANG/crWXnOM2WIqBJtjIhVYFha+w==", + "dependencies": { + "buffer": "^6.0.3", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">=12.0" + } + }, "node_modules/rdf-parse/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -41974,6 +42086,18 @@ "readable-stream": "^4.3.0" } }, + "node_modules/rdf-streaming-store/node_modules/n3": { + "version": "1.26.0", + "resolved": "https://registry.npmjs.org/n3/-/n3-1.26.0.tgz", + "integrity": "sha512-SQknS0ua90rN+3RHuk8BeIqeYyqIH/+ecViZxX08jR4j6MugqWRjtONl3uANG/crWXnOM2WIqBJtjIhVYFha+w==", + "dependencies": { + "buffer": "^6.0.3", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">=12.0" + } + }, "node_modules/rdf-streaming-store/node_modules/rdf-data-factory": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/rdf-data-factory/-/rdf-data-factory-2.0.2.tgz", @@ -42387,6 +42511,11 @@ "randombytes": "^2.1.0" } }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + }, "node_modules/shaclc-parse": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/shaclc-parse/-/shaclc-parse-1.4.3.tgz", @@ -42397,6 +42526,18 @@ "n3": "^1.16.3" } }, + "node_modules/shaclc-parse/node_modules/n3": { + "version": "1.26.0", + "resolved": "https://registry.npmjs.org/n3/-/n3-1.26.0.tgz", + "integrity": "sha512-SQknS0ua90rN+3RHuk8BeIqeYyqIH/+ecViZxX08jR4j6MugqWRjtONl3uANG/crWXnOM2WIqBJtjIhVYFha+w==", + "dependencies": { + "buffer": "^6.0.3", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">=12.0" + } + }, "node_modules/shaclc-write": { "version": "1.6.3", "resolved": "https://registry.npmjs.org/shaclc-write/-/shaclc-write-1.6.3.tgz", @@ -42407,18 +42548,6 @@ "rdf-string-ttl": "^2.0.1" } }, - "node_modules/shaclc-write/node_modules/n3": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/n3/-/n3-2.0.3.tgz", - "integrity": "sha512-um/toGVENTarHBYIK2TdH6ByBhW75WpdKpv8iTYt9wF2QfBk8s8a16iaWZFUAAC1BKfGdb99kfgx6pltdDwfKA==", - "dependencies": { - "buffer": "^6.0.3", - "readable-stream": "^4.0.0" - }, - "engines": { - "node": ">=12.0" - } - }, "node_modules/shaclc-write/node_modules/rdf-data-factory": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/rdf-data-factory/-/rdf-data-factory-2.0.2.tgz", diff --git a/package.json b/package.json index c88b7e4..4ba5bb1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "solid-cockpit", - "version": "1.2.1", + "version": "1.3.0", "description": "The Solid Cockpit application for Solid Pod utilization", "main": "~/src/App.vue", "homepage": "https://knowledgeonwebscale.github.io/solid-cockpit", @@ -15,6 +15,7 @@ }, "scripts": { "dev": "vite", + "version:bump": "node ./scripts/bump-version.mjs", "build": "vite build", "build:highmem": "NODE_OPTIONS=--max-old-space-size=8192 vite build", "serve": "vite preview", @@ -52,7 +53,10 @@ "actor-query-process-remote-cache": "^0.1.0", "core-js": "^3.8.3", "fs": "^0.0.1-security", + "jsonld": "^9.0.0", "material-icons": "^1.13.14", + "n3": "^2.0.3", + "papaparse": "^5.5.3", "pinia": "^2.3.1", "query-sparql-remote-cache": "^0.0.9", "sparqljs": "^3.7.3", diff --git a/scripts/bump-version.mjs b/scripts/bump-version.mjs new file mode 100644 index 0000000..f14326c --- /dev/null +++ b/scripts/bump-version.mjs @@ -0,0 +1,150 @@ +import { readFileSync, writeFileSync } from "node:fs"; +import { dirname, resolve } from "node:path"; +import { fileURLToPath } from "node:url"; +import { spawnSync } from "node:child_process"; + +const VERSION_RE = /^\d+\.\d+\.\d+$/; + +export function resolveNextVersion(currentVersion, requestedVersion) { + if (!requestedVersion) { + throw new Error("Provide a version like 1.2.3 or a bump keyword: patch, minor, major."); + } + + if (VERSION_RE.test(requestedVersion)) { + return requestedVersion; + } + + const parts = currentVersion.split(".").map((part) => Number(part)); + if (parts.length !== 3 || parts.some((part) => !Number.isInteger(part))) { + throw new Error(`Current package version is not valid semver: ${currentVersion}`); + } + + const [major, minor, patch] = parts; + switch (requestedVersion) { + case "patch": + return `${major}.${minor}.${patch + 1}`; + case "minor": + return `${major}.${minor + 1}.0`; + case "major": + return `${major + 1}.0.0`; + default: + throw new Error( + `Unsupported bump target "${requestedVersion}". Use major, minor, patch, or an explicit X.Y.Z version.` + ); + } +} + +export function updateReadmeVersionReferences(content, version) { + const releaseTag = `v${version}`; + return content + .replace( + /!\[Version\]\(https:\/\/img\.shields\.io\/badge\/version-[^)]+-blue\)/, + `![Version](https://img.shields.io/badge/version-${version}-blue)` + ) + .replace( + /!\[Web App Tag\]\(https:\/\/img\.shields\.io\/badge\/web--app--tag-[^)]+-0a7ea4\)/, + `![Web App Tag](https://img.shields.io/badge/web--app--tag-${releaseTag}-0a7ea4)` + ) + .replace( + /`Crum, E\. \(2026\)\. Solid Cockpit \(Version [^)]+\) \[Software\]\. GitHub\. https:\/\/github\.com\/KNowledgeOnWebScale\/solid-cockpit`/, + `\`Crum, E. (2026). Solid Cockpit (Version ${version}) [Software]. GitHub. https://github.com/KNowledgeOnWebScale/solid-cockpit\`` + ) + .replace(/version\s+=\s+\{[^}]+\},/, `version = {${version}},`) + .replace(/- `package\.json` version: `[^`]+`/, `- \`package.json\` version: \`${version}\``) + .replace(/- web-app release tag convention: `[^`]+`/, `- release tag convention: \`v\``) + .replace(/- current computed web-app tag: `[^`]+`/, `- current computed release tag: \`${releaseTag}\``) + .replace(/- Footer displays semantic version \(`vX\.Y\.Z`\) and computed release tag \(`[^`]+`\)/, "- Footer displays semantic version (`vX.Y.Z`).") + .replace(/npm version X\.Y\.Z/, "npm run version:bump -- X.Y.Z") + .replace(/git tag web-app-vX\.Y\.Z\ngit push origin vX\.Y\.Z web-app-vX\.Y\.Z/, "git push origin vX.Y.Z"); +} + +export function updateCitationCff(content, version, releaseDate) { + return content + .replace(/version:\s+"[^"]+"/, `version: "${version}"`) + .replace(/date-released:\s+\d{4}-\d{2}-\d{2}/, `date-released: ${releaseDate}`); +} + +export function updateCitationBib(content, version) { + return content.replace(/version\s+=\s+\{[^}]+\},/, `version = {${version}},`); +} + +function runVersionCommand(rootDir, nextVersion) { + const result = spawnSync( + "npm", + ["version", nextVersion, "--no-git-tag-version", "--allow-same-version"], + { + cwd: rootDir, + stdio: "inherit", + shell: process.platform === "win32", + } + ); + + if (result.status !== 0) { + throw new Error(`npm version failed with exit code ${result.status ?? "unknown"}`); + } +} + +function syncStaticVersionReferences(rootDir, version, releaseDate) { + const readmePath = resolve(rootDir, "README.md"); + const citationCffPath = resolve(rootDir, "CITATION.cff"); + const citationBibPath = resolve(rootDir, "CITATION.bib"); + + writeFileSync( + readmePath, + updateReadmeVersionReferences(readFileSync(readmePath, "utf8"), version), + "utf8" + ); + writeFileSync( + citationCffPath, + updateCitationCff(readFileSync(citationCffPath, "utf8"), version, releaseDate), + "utf8" + ); + writeFileSync( + citationBibPath, + updateCitationBib(readFileSync(citationBibPath, "utf8"), version), + "utf8" + ); +} + +export function runBumpVersion(rootDir, requestedVersion, releaseDate = new Date().toISOString().slice(0, 10)) { + const packageJsonPath = resolve(rootDir, "package.json"); + const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8")); + const currentVersion = packageJson.version ?? "0.0.0"; + const nextVersion = resolveNextVersion(currentVersion, requestedVersion); + + runVersionCommand(rootDir, nextVersion); + syncStaticVersionReferences(rootDir, nextVersion, releaseDate); + + return { + currentVersion, + nextVersion, + releaseTag: `v${nextVersion}`, + releaseDate, + }; +} + +const isMainModule = + process.argv[1] && + fileURLToPath(import.meta.url) === resolve(process.argv[1]); + +if (isMainModule) { + const rootDir = resolve(dirname(fileURLToPath(import.meta.url)), ".."); + + try { + const { currentVersion, nextVersion, releaseTag, releaseDate } = runBumpVersion( + rootDir, + process.argv[2] + ); + + console.log( + [ + `Updated version ${currentVersion} -> ${nextVersion}`, + `Release tag: ${releaseTag}`, + `Release date: ${releaseDate}`, + ].join("\n") + ); + } catch (error) { + console.error(error instanceof Error ? error.message : String(error)); + process.exitCode = 1; + } +} diff --git a/src/components/Guides/LandingGuide.vue b/src/components/Guides/LandingGuide.vue index 605a3ec..039e45e 100644 --- a/src/components/Guides/LandingGuide.vue +++ b/src/components/Guides/LandingGuide.vue @@ -97,7 +97,8 @@
  • Home authenticates with a Solid identity provider, shows session state, lets you choose a registered - pod, and provides copy controls for current identifiers. + pod, provides copy controls for current identifiers, and lets you + manually register a pod URL when a provider did not add it to your WebID automatically.
  • Data Upload accepts a typed @@ -122,6 +123,29 @@ +
    +

    When you need to register a pod manually

    +
      +
    • + Some Solid providers create a new pod without updating the + storage link on an already existing WebID. +
    • +
    • + In that case, the new pod will not appear automatically in the pod selector on + Home. +
    • +
    • + Use Register new pod or + Add Pod URL, paste the new pod container URL, and + click Register Pod. +
    • +
    • + After registration, switch to that pod from the selector if you want to start working + in it immediately. +
    • +
    +
    + diff --git a/src/components/Guides/PodBrowserGuide.vue b/src/components/Guides/PodBrowserGuide.vue index 3500bc0..6f943dd 100644 --- a/src/components/Guides/PodBrowserGuide.vue +++ b/src/components/Guides/PodBrowserGuide.vue @@ -86,6 +86,12 @@
  • Containers include direct child-item counts.
  • +
  • + Container Direct size is calculated only + when you open that container’s details. It sums the files directly inside + the container, caches the result for the session, and recomputes after + browser actions like move, rename, delete, or create container. +
  • diff --git a/src/components/PodBrowser.vue b/src/components/PodBrowser.vue index 4b1911d..e437ada 100644 --- a/src/components/PodBrowser.vue +++ b/src/components/PodBrowser.vue @@ -18,6 +18,13 @@ +
    + {{ createContainerSuccessMessage }} + +
    +
    @@ -59,6 +66,10 @@

    +
    +
    +
    + Create empty container + + Add a new child container inside the currently selected container. + +
    +
    + + + Create Container + +
    +

    + {{ createContainerFeedback }} +

    +
    +
    @@ -126,7 +166,7 @@ containerCheck(url) ? "folder" : "description" }}
    - {{ url }} + {{ getItemName(url) }}
    @@ -204,17 +244,13 @@
    {{ - itemDetails.itemType === "Container" ? "folder_copy" : "save" + itemDetails.itemType === "Container" ? "save" : "save" }}
    {{ - itemDetails.itemType === "Container" ? "Direct items" : "File size" - }} - {{ - itemDetails.itemType === "Container" - ? (itemDetails.directChildren ?? "Not available") - : (itemDetails.sizeLabel || "Not available") + itemDetails.itemType === "Container" ? "Direct size" : "Size" }} + {{ itemDetails.sizeLabel || "Not available" }}
    @@ -269,6 +305,18 @@ {{ itemDetails.contentType || "Unknown" }} +
    + + folder_copy + Direct items + + {{ + itemDetails.directChildren ?? "Not available" + }} +