From 4d62c244dcd4fe2ad3d05281511d3fdace79f2d4 Mon Sep 17 00:00:00 2001 From: jaxoncreed Date: Thu, 8 Feb 2024 23:19:17 -0500 Subject: [PATCH] Added getWac --- package-lock.json | 1200 ++++++++++++++++- packages/solid/package.json | 5 +- packages/solid/src/.ldo/wac.context.ts | 45 + packages/solid/src/.ldo/wac.schema.ts | 169 +++ packages/solid/src/.ldo/wac.shapeTypes.ts | 19 + packages/solid/src/.ldo/wac.typings.ts | 73 + packages/solid/src/.shapes/wac.shex | 23 + packages/solid/src/index.ts | 2 - .../src/requester/requests/getAccessRules.ts | 13 - .../src/requester/requests/setAccessRules.ts | 88 -- .../results/error/HttpErrorResult.ts | 42 +- .../requester/results/success/AccessRule.ts | 11 - packages/solid/src/resource/Resource.ts | 84 +- packages/solid/src/resource/wac/WacRule.ts | 19 + packages/solid/src/resource/wac/getWacRule.ts | 100 ++ packages/solid/src/resource/wac/getWacUri.ts | 63 + .../resource/wac/results/GetWacRuleSuccess.ts | 7 + .../resource/wac/results/GetWacUriSuccess.ts | 6 + .../resource/wac/results/SetWacRuleSuccess.ts | 7 + packages/solid/src/resource/wac/setWacRule.ts | 0 packages/solid/src/util/rdfUtils.ts | 33 +- packages/solid/test/Integration.test.ts | 48 +- packages/solid/test/solidServer.helper.ts | 2 + 23 files changed, 1879 insertions(+), 180 deletions(-) create mode 100644 packages/solid/src/.ldo/wac.context.ts create mode 100644 packages/solid/src/.ldo/wac.schema.ts create mode 100644 packages/solid/src/.ldo/wac.shapeTypes.ts create mode 100644 packages/solid/src/.ldo/wac.typings.ts create mode 100644 packages/solid/src/.shapes/wac.shex delete mode 100644 packages/solid/src/requester/requests/getAccessRules.ts delete mode 100644 packages/solid/src/requester/requests/setAccessRules.ts delete mode 100644 packages/solid/src/requester/results/success/AccessRule.ts create mode 100644 packages/solid/src/resource/wac/WacRule.ts create mode 100644 packages/solid/src/resource/wac/getWacRule.ts create mode 100644 packages/solid/src/resource/wac/getWacUri.ts create mode 100644 packages/solid/src/resource/wac/results/GetWacRuleSuccess.ts create mode 100644 packages/solid/src/resource/wac/results/GetWacUriSuccess.ts create mode 100644 packages/solid/src/resource/wac/results/SetWacRuleSuccess.ts create mode 100644 packages/solid/src/resource/wac/setWacRule.ts diff --git a/package-lock.json b/package-lock.json index 7ff28e9..a1b9123 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3851,6 +3851,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.0.tgz", "integrity": "sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==", + "dev": true, "engines": { "node": ">=14" } @@ -4061,6 +4062,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/@inrupt/universal-fetch/-/universal-fetch-1.0.3.tgz", "integrity": "sha512-AP/nMOuuKvR2YoQkdS77ntuuq5ZYDGStI8Uirp1MCsyPSoBLyNnRjMLjlGqIlaC+5Xp7TYZJ9z/Kl2uUEpXUFw==", + "dev": true, "dependencies": { "node-fetch": "^2.6.7", "undici": "^5.19.1" @@ -4945,6 +4947,10 @@ "resolved": "packages/type-traverser", "link": true }, + "node_modules/@ldo/wac-store": { + "resolved": "packages/wac-store", + "link": true + }, "node_modules/@lerna/child-process": { "version": "7.4.2", "resolved": "https://registry.npmjs.org/@lerna/child-process/-/child-process-7.4.2.tgz", @@ -7039,7 +7045,8 @@ "node_modules/@types/parse-link-header": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/parse-link-header/-/parse-link-header-2.0.3.tgz", - "integrity": "sha512-ffLAxD6Xqcf2gSbtEJehj8yJ5R/2OZqD4liodQvQQ+hhO4kg1mk9ToEZQPMtNTm/zIQj2GNleQbsjPp9+UQm4Q==" + "integrity": "sha512-ffLAxD6Xqcf2gSbtEJehj8yJ5R/2OZqD4liodQvQQ+hhO4kg1mk9ToEZQPMtNTm/zIQj2GNleQbsjPp9+UQm4Q==", + "dev": true }, "node_modules/@types/prettier": { "version": "2.7.3", @@ -7102,6 +7109,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/rdfjs__dataset/-/rdfjs__dataset-1.0.5.tgz", "integrity": "sha512-8OBC9Kr/ZSgNoUTe5mHTDPHaPt8Xen4XbYfqcbYv56d+4WdKliHXaFmFc0L4I5vsynE5JGu21Hvg2zWgX1Az6Q==", + "dev": true, "dependencies": { "rdf-js": "^4.0.2" } @@ -16616,6 +16624,7 @@ "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, "dependencies": { "whatwg-url": "^5.0.0" }, @@ -16634,17 +16643,20 @@ "node_modules/node-fetch/node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true }, "node_modules/node-fetch/node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true }, "node_modules/node-fetch/node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -18811,6 +18823,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/rdf-js/-/rdf-js-4.0.2.tgz", "integrity": "sha512-ApvlFa/WsQh8LpPK/6hctQwG06Z9ztQQGWVtrcrf9L6+sejHNXLPOqL+w7q3hF+iL0C4sv3AX1PUtGkLNzyZ0Q==", + "dev": true, "dependencies": { "@rdfjs/types": "*" } @@ -21417,11 +21430,6 @@ "integrity": "sha512-Y6P/VJnwARiPMfxO7rvaYaz5tGQ5TQ0Wnb2cWIxMpFOioYkhsT8XaCrJX6wYPNFACa4UOrN5SPqhwpM8NolAhQ==", "dev": true }, - "node_modules/ts-mixer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.3.tgz", - "integrity": "sha512-k43M7uCG1AkTyxgnmI5MPwKoUvS/bRvLvUb7+Pgpdlmok8AoqmUaZxUUw8zKM5B1lqZrt41GjYgnvAi0fppqgQ==" - }, "node_modules/ts-node": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", @@ -21962,6 +21970,7 @@ "version": "5.28.2", "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.2.tgz", "integrity": "sha512-wh1pHJHnUeQV5Xa8/kyQhO7WFa8M34l026L5P/+2TYiakvGy5Rdc8jWZVyG7ieht/0WgJLEd3kcU5gKx+6GC8w==", + "dev": true, "dependencies": { "@fastify/busboy": "^2.0.0" }, @@ -24564,14 +24573,11 @@ "version": "0.0.1-alpha.18", "license": "MIT", "dependencies": { - "@inrupt/solid-client": "^1.30.0", "@ldo/dataset": "^0.0.1-alpha.17", "@ldo/ldo": "^0.0.1-alpha.18", "@ldo/rdf-utils": "^0.0.1-alpha.17", - "@types/parse-link-header": "^2.0.1", "cross-fetch": "^3.1.6", - "http-link-header": "^1.1.1", - "ts-mixer": "^6.0.3" + "http-link-header": "^1.1.1" }, "devDependencies": { "@inrupt/solid-client-authn-core": "^1.17.1", @@ -24580,6 +24586,7 @@ "@rdfjs/types": "^1.0.1", "@solid/community-server": "^6.0.2", "@types/jest": "^29.0.3", + "@types/parse-link-header": "^2.0.1", "dotenv": "^16.3.1", "jest-rdf": "^1.8.0", "ts-jest": "^29.0.2", @@ -25734,28 +25741,6 @@ "node": ">=12" } }, - "packages/solid/node_modules/@inrupt/solid-client": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/@inrupt/solid-client/-/solid-client-1.30.2.tgz", - "integrity": "sha512-8Lwh0ZC1d9c939O+dAsT5oheSKIBX5A0uk7fhaJ0qDBFZGKT/jnIy6TrBpvn/nYZAvCA2XSvZHgBfEX7r0FCKw==", - "dependencies": { - "@inrupt/universal-fetch": "^1.0.1", - "@rdfjs/dataset": "^1.1.0", - "@types/rdfjs__dataset": "^1.0.4", - "buffer": "^6.0.3", - "http-link-header": "^1.1.0", - "jsonld-context-parser": "^2.3.0", - "jsonld-streaming-parser": "^3.2.0", - "n3": "^1.10.0", - "uuid": "^9.0.0" - }, - "engines": { - "node": "^16.0.0 || ^18.0.0 || ^20.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - } - }, "packages/solid/node_modules/@jest/console": { "version": "29.7.0", "dev": true, @@ -28027,6 +28012,1153 @@ "bin": { "uuid": "dist/bin/uuid" } + }, + "packages/wac-store": { + "version": "0.0.1-alpha.18", + "license": "MIT", + "dependencies": { + "@ldo/dataset": "^0.0.1-alpha.17", + "@ldo/ldo": "^0.0.1-alpha.18", + "@ldo/rdf-utils": "^0.0.1-alpha.17", + "cross-fetch": "^3.1.6", + "http-link-header": "^1.1.1" + }, + "devDependencies": { + "@inrupt/solid-client-authn-core": "^1.17.1", + "@ldo/cli": "^0.0.1-alpha.18", + "@rdfjs/data-model": "^1.2.0", + "@rdfjs/types": "^1.0.1", + "@solid/community-server": "^6.0.2", + "@types/jest": "^29.0.3", + "@types/parse-link-header": "^2.0.1", + "dotenv": "^16.3.1", + "jest-rdf": "^1.8.0", + "ts-jest": "^29.0.2", + "ts-node": "^10.9.1", + "typed-emitter": "^2.1.0", + "typedoc": "^0.25.4", + "typedoc-plugin-markdown": "^3.17.1" + } + }, + "packages/wac-store/node_modules/@jest/console": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/@jest/core": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "packages/wac-store/node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/@jest/globals": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/@jest/reporters": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", + "dev": true, + "peer": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "packages/wac-store/node_modules/@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "dev": true, + "peer": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/@jest/test-result": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/@jest/test-sequencer": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "peer": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "packages/wac-store/node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "peer": true, + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "packages/wac-store/node_modules/@types/jest": { + "version": "29.5.12", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz", + "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", + "dev": true, + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "packages/wac-store/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "packages/wac-store/node_modules/babel-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "packages/wac-store/node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "dev": true, + "peer": true, + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "packages/wac-store/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/wac-store/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "peer": true + }, + "packages/wac-store/node_modules/dedent": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", + "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==", + "dev": true, + "peer": true, + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "packages/wac-store/node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "packages/wac-store/node_modules/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dev": true, + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/istanbul-lib-instrument": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz", + "integrity": "sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "packages/wac-store/node_modules/jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.7.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "packages/wac-store/node_modules/jest-changed-files": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", + "dev": true, + "peer": true, + "dependencies": { + "execa": "^5.0.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/jest-circus": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.7.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/jest-cli": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "create-jest": "^29.7.0", + "exit": "^0.1.2", + "import-local": "^3.0.2", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "packages/wac-store/node_modules/jest-config": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "packages/wac-store/node_modules/jest-docblock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", + "dev": true, + "peer": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/jest-each": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/jest-environment-node": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "packages/wac-store/node_modules/jest-leak-detector": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", + "dev": true, + "peer": true, + "dependencies": { + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "peer": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/jest-resolve": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "dev": true, + "peer": true, + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/jest-resolve-dependencies": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", + "dev": true, + "peer": true, + "dependencies": { + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/jest-runner": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/jest-runtime": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/jest-snapshot": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/jest-watcher": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.7.0", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "peer": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "packages/wac-store/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "packages/wac-store/node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "peer": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "packages/wac-store/node_modules/resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + } + }, + "packages/wac-store/node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "peer": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "packages/wac-store/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "packages/wac-store/node_modules/ts-jest": { + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.2.tgz", + "integrity": "sha512-br6GJoH/WUX4pu7FbZXuWGKGNDuU7b8Uj77g/Sp7puZV6EXzuByl6JrECvm0MzVzSTkSHWTihsXt+5XYER5b+g==", + "dev": true, + "dependencies": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^29.0.0", + "json5": "^2.2.3", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "^7.5.3", + "yargs-parser": "^21.0.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^16.10.0 || ^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/types": "^29.0.0", + "babel-jest": "^29.0.0", + "jest": "^29.0.0", + "typescript": ">=4.3 <6" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "packages/wac-store/node_modules/v8-to-istanbul": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", + "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", + "dev": true, + "peer": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "packages/wac-store/node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "peer": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "packages/wac-store/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "peer": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "packages/wac-store/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } } } } diff --git a/packages/solid/package.json b/packages/solid/package.json index 8629142..a7042bb 100644 --- a/packages/solid/package.json +++ b/packages/solid/package.json @@ -40,14 +40,11 @@ "typedoc-plugin-markdown": "^3.17.1" }, "dependencies": { - "@inrupt/solid-client": "^1.30.0", "@ldo/dataset": "^0.0.1-alpha.17", "@ldo/ldo": "^0.0.1-alpha.18", "@ldo/rdf-utils": "^0.0.1-alpha.17", - "@types/parse-link-header": "^2.0.1", "cross-fetch": "^3.1.6", - "http-link-header": "^1.1.1", - "ts-mixer": "^6.0.3" + "http-link-header": "^1.1.1" }, "files": [ "dist", diff --git a/packages/solid/src/.ldo/wac.context.ts b/packages/solid/src/.ldo/wac.context.ts new file mode 100644 index 0000000..22df8b2 --- /dev/null +++ b/packages/solid/src/.ldo/wac.context.ts @@ -0,0 +1,45 @@ +import { ContextDefinition } from "jsonld"; + +/** + * ============================================================================= + * wacContext: JSONLD Context for wac + * ============================================================================= + */ +export const wacContext: ContextDefinition = { + type: { + "@id": "@type", + }, + Authorization: "http://www.w3.org/ns/auth/acl#Authorization", + accessTo: { + "@id": "http://www.w3.org/ns/auth/acl#accessTo", + "@type": "@id", + }, + default: { + "@id": "http://www.w3.org/ns/auth/acl#default", + "@type": "@id", + }, + agent: { + "@id": "http://www.w3.org/ns/auth/acl#agent", + "@type": "@id", + "@container": "@set", + }, + agentGroup: { + "@id": "http://www.w3.org/ns/auth/acl#agentGroup", + "@type": "@id", + "@container": "@set", + }, + agentClass: { + "@id": "http://www.w3.org/ns/auth/acl#agentClass", + "@container": "@set", + }, + AuthenticatedAgent: "http://www.w3.org/ns/auth/acl#AuthenticatedAgent", + Agent: "http://xmlns.com/foaf/0.1/Agent", + mode: { + "@id": "http://www.w3.org/ns/auth/acl#mode", + "@container": "@set", + }, + Read: "http://www.w3.org/ns/auth/acl#Read", + Write: "http://www.w3.org/ns/auth/acl#Write", + Append: "http://www.w3.org/ns/auth/acl#Append", + Control: "http://www.w3.org/ns/auth/acl#Control", +}; diff --git a/packages/solid/src/.ldo/wac.schema.ts b/packages/solid/src/.ldo/wac.schema.ts new file mode 100644 index 0000000..2d54115 --- /dev/null +++ b/packages/solid/src/.ldo/wac.schema.ts @@ -0,0 +1,169 @@ +import { Schema } from "shexj"; + +/** + * ============================================================================= + * wacSchema: ShexJ Schema for wac + * ============================================================================= + */ +export const wacSchema: Schema = { + type: "Schema", + shapes: [ + { + id: "http://www.w3.org/ns/auth/acls#Authorization", + type: "ShapeDecl", + shapeExpr: { + type: "Shape", + expression: { + id: "http://www.w3.org/ns/auth/acls#AuthorizationShape", + type: "EachOf", + expressions: [ + { + type: "TripleConstraint", + predicate: "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", + valueExpr: { + type: "NodeConstraint", + values: ["http://www.w3.org/ns/auth/acl#Authorization"], + }, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: "Denotes this as an acl:Authorization", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/ns/auth/acl#accessTo", + valueExpr: { + type: "NodeConstraint", + nodeKind: "iri", + }, + min: 0, + max: 1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: "The subject of this authorization", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/ns/auth/acl#default", + valueExpr: { + type: "NodeConstraint", + nodeKind: "iri", + }, + min: 0, + max: 1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: "The container subject of this authorization", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/ns/auth/acl#agent", + valueExpr: { + type: "NodeConstraint", + nodeKind: "iri", + }, + min: 0, + max: -1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: + "An agent is a person, social entity or software identified by a URI, e.g., a WebID denotes an agent", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/ns/auth/acl#agentGroup", + valueExpr: { + type: "NodeConstraint", + nodeKind: "iri", + }, + min: 0, + max: -1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: + "Denotes a group of agents being given the access permission", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/ns/auth/acl#agentClass", + valueExpr: { + type: "NodeConstraint", + values: [ + "http://www.w3.org/ns/auth/acl#AuthenticatedAgent", + "http://xmlns.com/foaf/0.1/Agent", + ], + }, + min: 0, + max: -1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: + "An agent class is a class of persons or entities identified by a URI.", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/ns/auth/acl#mode", + valueExpr: { + type: "NodeConstraint", + values: [ + "http://www.w3.org/ns/auth/acl#Read", + "http://www.w3.org/ns/auth/acl#Write", + "http://www.w3.org/ns/auth/acl#Append", + "http://www.w3.org/ns/auth/acl#Control", + ], + }, + min: 0, + max: -1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: + "Denotes a class of operations that the agents can perform on a resource.", + }, + }, + ], + }, + ], + }, + extra: ["http://www.w3.org/1999/02/22-rdf-syntax-ns#type"], + }, + }, + ], +}; diff --git a/packages/solid/src/.ldo/wac.shapeTypes.ts b/packages/solid/src/.ldo/wac.shapeTypes.ts new file mode 100644 index 0000000..6689590 --- /dev/null +++ b/packages/solid/src/.ldo/wac.shapeTypes.ts @@ -0,0 +1,19 @@ +import { ShapeType } from "@ldo/ldo"; +import { wacSchema } from "./wac.schema"; +import { wacContext } from "./wac.context"; +import { Authorization } from "./wac.typings"; + +/** + * ============================================================================= + * LDO ShapeTypes wac + * ============================================================================= + */ + +/** + * Authorization ShapeType + */ +export const AuthorizationShapeType: ShapeType = { + schema: wacSchema, + shape: "http://www.w3.org/ns/auth/acls#Authorization", + context: wacContext, +}; diff --git a/packages/solid/src/.ldo/wac.typings.ts b/packages/solid/src/.ldo/wac.typings.ts new file mode 100644 index 0000000..456c5ed --- /dev/null +++ b/packages/solid/src/.ldo/wac.typings.ts @@ -0,0 +1,73 @@ +import { ContextDefinition } from "jsonld"; + +/** + * ============================================================================= + * Typescript Typings for wac + * ============================================================================= + */ + +/** + * Authorization Type + */ +export interface Authorization { + "@id"?: string; + "@context"?: ContextDefinition; + /** + * Denotes this as an acl:Authorization + */ + type: { + "@id": "Authorization"; + }; + /** + * The subject of this authorization + */ + accessTo?: { + "@id": string; + }; + /** + * The container subject of this authorization + */ + default?: { + "@id": string; + }; + /** + * An agent is a person, social entity or software identified by a URI, e.g., a WebID denotes an agent + */ + agent?: { + "@id": string; + }[]; + /** + * Denotes a group of agents being given the access permission + */ + agentGroup?: { + "@id": string; + }[]; + /** + * An agent class is a class of persons or entities identified by a URI. + */ + agentClass?: ( + | { + "@id": "AuthenticatedAgent"; + } + | { + "@id": "Agent"; + } + )[]; + /** + * Denotes a class of operations that the agents can perform on a resource. + */ + mode?: ( + | { + "@id": "Read"; + } + | { + "@id": "Write"; + } + | { + "@id": "Append"; + } + | { + "@id": "Control"; + } + )[]; +} diff --git a/packages/solid/src/.shapes/wac.shex b/packages/solid/src/.shapes/wac.shex new file mode 100644 index 0000000..5ff19cd --- /dev/null +++ b/packages/solid/src/.shapes/wac.shex @@ -0,0 +1,23 @@ +PREFIX acl: +PREFIX acls: +PREFIX foaf: +PREFIX rdfs: + +acls:Authorization EXTRA a { + $acls:AuthorizationShape ( + a [ acl:Authorization ] + // rdfs:comment "Denotes this as an acl:Authorization"; + acl:accessTo IRI? + // rdfs:comment "The subject of this authorization"; + acl:default IRI? + // rdfs:comment "The container subject of this authorization"; + acl:agent IRI* + // rdfs:comment "An agent is a person, social entity or software identified by a URI, e.g., a WebID denotes an agent"; + acl:agentGroup IRI* + // rdfs:comment "Denotes a group of agents being given the access permission"; + acl:agentClass [ acl:AuthenticatedAgent foaf:Agent ]* + // rdfs:comment "An agent class is a class of persons or entities identified by a URI."; + acl:mode [ acl:Read acl:Write acl:Append acl:Control ]* + // rdfs:comment "Denotes a class of operations that the agents can perform on a resource."; + ) +} diff --git a/packages/solid/src/index.ts b/packages/solid/src/index.ts index 22b3108..5711dbc 100644 --- a/packages/solid/src/index.ts +++ b/packages/solid/src/index.ts @@ -13,9 +13,7 @@ export * from "./methods"; export * from "./requester/requests/checkRootContainer"; export * from "./requester/requests/createDataResource"; export * from "./requester/requests/deleteResource"; -export * from "./requester/requests/getAccessRules"; export * from "./requester/requests/readResource"; export * from "./requester/requests/requestOptions"; -export * from "./requester/requests/setAccessRules"; export * from "./requester/requests/updateDataResource"; export * from "./requester/requests/uploadResource"; diff --git a/packages/solid/src/requester/requests/getAccessRules.ts b/packages/solid/src/requester/requests/getAccessRules.ts deleted file mode 100644 index 9ac4107..0000000 --- a/packages/solid/src/requester/requests/getAccessRules.ts +++ /dev/null @@ -1,13 +0,0 @@ -/* istanbul ignore file */ - -export async function getAccessRules(): 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/setAccessRules.ts b/packages/solid/src/requester/requests/setAccessRules.ts deleted file mode 100644 index 514a965..0000000 --- a/packages/solid/src/requester/requests/setAccessRules.ts +++ /dev/null @@ -1,88 +0,0 @@ -/* istanbul ignore file */ - -import type { AclDataset, WithChangeLog } from "@inrupt/solid-client"; -import { - getSolidDatasetWithAcl, - hasResourceAcl, - hasFallbackAcl, - hasAccessibleAcl, - createAclFromFallbackAcl, - getResourceAcl, - setAgentResourceAccess, - saveAclFor, - setPublicDefaultAccess, - setPublicResourceAccess, - setAgentDefaultAccess, -} from "@inrupt/solid-client"; -import { guaranteeFetch } from "../../util/guaranteeFetch"; -import { isContainerUri } from "../../util/uriTypes"; -import type { AccessRule } from "../results/success/AccessRule"; -import type { SetAccessRuleSuccess } from "../results/success/AccessRule"; -import { AccessRuleFetchError } from "../results/error/AccessControlError"; -import type { BasicRequestOptions } from "./requestOptions"; - -export type SetAccessRulesResult = - | SetAccessRuleSuccess - | SetAccessRulesResultError; -export type SetAccessRulesResultError = AccessRuleFetchError; - -export async function setAccessRules( - uri: string, - newAccessRules: AccessRule, - options?: BasicRequestOptions, -): Promise { - console.warn("Access Control is stil underdeveloped. Use with caution."); - const fetch = guaranteeFetch(options?.fetch); - 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 { - isError: false, - uri, - type: "setAccessRuleSuccess", - }; -} diff --git a/packages/solid/src/requester/results/error/HttpErrorResult.ts b/packages/solid/src/requester/results/error/HttpErrorResult.ts index 283bfe9..69cc821 100644 --- a/packages/solid/src/requester/results/error/HttpErrorResult.ts +++ b/packages/solid/src/requester/results/error/HttpErrorResult.ts @@ -6,7 +6,8 @@ import { ResourceError } from "./ErrorResult"; export type HttpErrorResultType = | ServerHttpError | UnexpectedHttpError - | UnauthenticatedHttpError; + | UnauthenticatedHttpError + | UnauthorizedHttpError; /** * An error caused by an HTTP request @@ -70,6 +71,9 @@ export abstract class HttpErrorResult extends ResourceError { if (UnauthenticatedHttpError.is(response)) { return new UnauthenticatedHttpError(uri, response); } + if (UnauthorizedHttpError.is(response)) { + return new UnauthorizedHttpError(uri, response); + } if (HttpErrorResult.isnt(response)) { return new UnexpectedHttpError(uri, response); } @@ -102,6 +106,42 @@ export class UnauthenticatedHttpError extends HttpErrorResult { } } +/** + * An UnauthenticatedHttpError triggers when a Solid server returns a 403 status + * indicating that the request is not authorized. + */ +export class UnauthorizedHttpError extends HttpErrorResult { + readonly type = "unauthorizedError" as const; + + /** + * Indicates if a specific response constitutes an UnauthenticatedHttpError + * @param response - The request response + * @returns true if this response constitutes an UnauthenticatedHttpError + */ + static is(response: Response) { + return response.status === 403; + } +} + +/** + * An NotFoundHttpError triggers when a Solid server returns a 404 status. This + * error is not returned in most cases as a "absent" resource is not considered + * an error, but it is thrown while trying for find a WAC rule for a resource + * that does not exist. + */ +export class NotFoundHttpError extends HttpErrorResult { + readonly type = "notFoundError" as const; + + /** + * Indicates if a specific response constitutes an NotFoundHttpError + * @param response - The request response + * @returns true if this response constitutes an NotFoundHttpError + */ + static is(response: Response) { + return response.status === 404; + } +} + /** * A ServerHttpError triggers when a Solid server returns a 5XX status, * indicating that an error happened on the server. diff --git a/packages/solid/src/requester/results/success/AccessRule.ts b/packages/solid/src/requester/results/success/AccessRule.ts deleted file mode 100644 index 975d834..0000000 --- a/packages/solid/src/requester/results/success/AccessRule.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { Access } from "@inrupt/solid-client"; -import type { ResourceSuccess } from "./SuccessResult"; - -export interface AccessRule { - public?: Access; - agent?: Record; -} - -export interface SetAccessRuleSuccess extends ResourceSuccess { - type: "setAccessRuleSuccess"; -} diff --git a/packages/solid/src/resource/Resource.ts b/packages/solid/src/resource/Resource.ts index e03f91c..82b8915 100644 --- a/packages/solid/src/resource/Resource.ts +++ b/packages/solid/src/resource/Resource.ts @@ -11,9 +11,6 @@ import type { } from "../requester/requests/readResource"; import type { BatchedRequester } from "../requester/BatchedRequester"; import type { CheckRootResultError } from "../requester/requests/checkRootContainer"; -import type { AccessRule } from "../requester/results/success/AccessRule"; -import type { SetAccessRulesResult } from "../requester/requests/setAccessRules"; -import { setAccessRules } from "../requester/requests/setAccessRules"; import type TypedEmitter from "typed-emitter"; import EventEmitter from "events"; import { getParentUri } from "../util/rdfUtils"; @@ -28,6 +25,10 @@ import type { CreateSuccess } from "../requester/results/success/CreateSuccess"; import type { ResourceResult } from "./resourceResult/ResourceResult"; import type { Container } from "./Container"; import type { Leaf } from "./Leaf"; +import type { WacRule } from "./wac/WacRule"; +import type { GetWacUriError, GetWacUriResult } from "./wac/getWacUri"; +import { getWacUri } from "./wac/getWacUri"; +import { getWacRuleWithAclUri, type GetWacRuleResult } from "./wac/getWacRule"; /** * Statuses shared between both Leaf and Container @@ -79,6 +80,18 @@ export abstract class Resource extends (EventEmitter as new () => TypedEmitter<{ */ protected absent: boolean | undefined; + /** + * @internal + * If a wac uri is fetched, it is cached here + */ + protected wacUri?: string; + + /** + * @internal + * If a wac rule was fetched, it is cached here + */ + protected wacRule?: WacRule; + /** * @param context - SolidLdoDatasetContext for the parent dataset */ @@ -510,18 +523,61 @@ export abstract class Resource extends (EventEmitter as new () => TypedEmitter<{ */ abstract getRootContainer(): Promise; - // Access Rules Methods - // async getAccessRules(): Promise { - // return getAccessRules({ uri: this.uri, fetch: this.context.fetch }); - // } - /* istanbul ignore next */ - async setAccessRules( - newAccessRules: AccessRule, - ): Promise> { - const result = await setAccessRules(this.uri, newAccessRules, { + /** + * =========================================================================== + * WEB ACCESS CONTROL METHODS + * =========================================================================== + */ + + protected async getWacUri(options?: { + ignoreCache: boolean; + }): Promise { + // Get the wacUri if not already present + if (!options?.ignoreCache && this.wacUri) { + return { + type: "getWacUriSuccess", + wacUri: this.wacUri, + isError: false, + uri: this.uri, + }; + } + + const wacUriResult = await getWacUri(this.uri, { + fetch: this.context.fetch, + }); + if (wacUriResult.isError) { + return wacUriResult; + } + this.wacUri = wacUriResult.wacUri; + return wacUriResult; + } + + async getWac(options?: { + ignoreCache: boolean; + }): Promise { + // Return the wac rule if it's already cached + if (!options?.ignoreCache && this.wacRule) { + return { + type: "getWacRuleSuccess", + uri: this.uri, + isError: false, + wacRule: this.wacRule, + }; + } + + // Get the wac uri + const wacUriResult = await this.getWacUri(options); + if (wacUriResult.isError) { + return wacUriResult; + } + + // Get the wac rule + return getWacRuleWithAclUri(wacUriResult.wacUri, { fetch: this.context.fetch, }); - if (result.isError) return result; - return { ...result, resource: this as unknown as Leaf | Container }; } + + // async setWac(wacRule: WacRule): Promise<> { + // throw new Error("Not Implemented"); + // } } diff --git a/packages/solid/src/resource/wac/WacRule.ts b/packages/solid/src/resource/wac/WacRule.ts new file mode 100644 index 0000000..b1230b0 --- /dev/null +++ b/packages/solid/src/resource/wac/WacRule.ts @@ -0,0 +1,19 @@ +export interface AccessModeList { + read: boolean; + append: boolean; + write: boolean; + control: boolean; +} + +export interface WacRule { + public: AccessModeList; + authenticated: AccessModeList; + agent: Record; +} + +// export interface SetWacRule { +// ruleFor: Resource; +// public?: AccessModeList; +// authenticated?: AccessModeList; +// agent?: Record; +// } diff --git a/packages/solid/src/resource/wac/getWacRule.ts b/packages/solid/src/resource/wac/getWacRule.ts new file mode 100644 index 0000000..1f9405c --- /dev/null +++ b/packages/solid/src/resource/wac/getWacRule.ts @@ -0,0 +1,100 @@ +import type { GetWacRuleSuccess } from "./results/GetWacRuleSuccess"; +import { guaranteeFetch } from "../../util/guaranteeFetch"; +import type { BasicRequestOptions } from "../../requester/requests/requestOptions"; +import type { HttpErrorResultType } from "../../requester/results/error/HttpErrorResult"; +import { HttpErrorResult } from "../../requester/results/error/HttpErrorResult"; +import type { NoncompliantPodError } from "../../requester/results/error/NoncompliantPodError"; +import type { UnexpectedResourceError } from "../../requester/results/error/ErrorResult"; +import { rawTurtleToDataset } from "../../util/rdfUtils"; +import { AuthorizationShapeType } from "../../.ldo/wac.shapeTypes"; +import type { AccessModeList, WacRule } from "./WacRule"; +import type { Authorization } from "../../.ldo/wac.typings"; + +export type GetWacRuleError = + | HttpErrorResultType + | NoncompliantPodError + | UnexpectedResourceError; +export type GetWacRuleResult = GetWacRuleSuccess | GetWacRuleError; + +export async function getWacRuleWithAclUri( + aclUri: string, + options?: BasicRequestOptions, +): Promise { + const fetch = guaranteeFetch(options?.fetch); + const response = await fetch(aclUri); + const errorResult = HttpErrorResult.checkResponse(aclUri, response); + if (errorResult) return errorResult; + + // Parse Turtle + const rawTurtle = await response.text(); + const rawTurtleResult = await rawTurtleToDataset(rawTurtle, aclUri); + if (rawTurtleResult.isError) return rawTurtleResult; + const dataset = rawTurtleResult.dataset; + const authorizations = dataset + .usingType(AuthorizationShapeType) + .matchSubject( + "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", + "http://www.w3.org/ns/auth/acl#Authorization", + ); + + const wacRule: WacRule = { + public: { + read: false, + write: false, + append: false, + control: false, + }, + authenticated: { + read: false, + write: false, + append: false, + control: false, + }, + agent: {}, + }; + + function applyAccessModesToList( + accessModeList: AccessModeList, + authorization: Authorization, + ): void { + authorization.mode?.forEach((mode) => { + accessModeList[mode["@id"].toLowerCase()] = true; + }); + } + + authorizations.forEach((authorization) => { + if ( + authorization.agentClass?.some( + (agentClass) => agentClass["@id"] === "Agent", + ) + ) { + applyAccessModesToList(wacRule.public, authorization); + applyAccessModesToList(wacRule.authenticated, authorization); + } + if ( + authorization.agentClass?.some( + (agentClass) => agentClass["@id"] === "AuthenticatedAgent", + ) + ) { + applyAccessModesToList(wacRule.authenticated, authorization); + } + authorization.agent?.forEach((agent) => { + if (!wacRule.agent[agent["@id"]]) { + wacRule.agent[agent["@id"]] = { + read: false, + write: false, + append: false, + control: false, + }; + } + applyAccessModesToList(wacRule.agent[agent["@id"]], authorization); + }); + }); + + return { + type: "getWacRuleSuccess", + uri: aclUri, + isError: false, + wacRule, + }; +} diff --git a/packages/solid/src/resource/wac/getWacUri.ts b/packages/solid/src/resource/wac/getWacUri.ts new file mode 100644 index 0000000..1ff3105 --- /dev/null +++ b/packages/solid/src/resource/wac/getWacUri.ts @@ -0,0 +1,63 @@ +import type { GetWacUriSuccess } from "./results/GetWacUriSuccess"; +import type { HttpErrorResultType } from "../../requester/results/error/HttpErrorResult"; +import { + HttpErrorResult, + NotFoundHttpError, +} from "../../requester/results/error/HttpErrorResult"; +import { UnexpectedResourceError } from "../../requester/results/error/ErrorResult"; +import { guaranteeFetch } from "../../util/guaranteeFetch"; +import type { BasicRequestOptions } from "../../requester/requests/requestOptions"; +import { NoncompliantPodError } from "../../requester/results/error/NoncompliantPodError"; +import { parse as parseLinkHeader } from "http-link-header"; + +export type GetWacUriError = + | HttpErrorResultType + | NotFoundHttpError + | NoncompliantPodError + | UnexpectedResourceError; +export type GetWacUriResult = GetWacUriSuccess | GetWacUriError; + +export async function getWacUri( + resourceUri: string, + options?: BasicRequestOptions, +): Promise { + try { + const fetch = guaranteeFetch(options?.fetch); + const response = await fetch(resourceUri, { + method: "head", + }); + const errorResult = HttpErrorResult.checkResponse(resourceUri, response); + if (errorResult) return errorResult; + if (NotFoundHttpError.is(response)) { + return new NotFoundHttpError( + resourceUri, + response, + "Could not get access control rules because the resource does not exist.", + ); + } + // Get the URI from the link header + const linkHeader = response.headers.get("link"); + if (!linkHeader) { + return new NoncompliantPodError( + resourceUri, + "No link header present in request.", + ); + } + const parsedLinkHeader = parseLinkHeader(linkHeader); + const aclUris = parsedLinkHeader.get("rel", "acl"); + if (aclUris.length !== 1) { + return new NoncompliantPodError( + resourceUri, + `There must be one link with a rel="acl"`, + ); + } + return { + type: "getWacUriSuccess", + isError: false, + uri: resourceUri, + wacUri: aclUris[0].uri, + }; + } catch (err: unknown) { + return UnexpectedResourceError.fromThrown(resourceUri, err); + } +} diff --git a/packages/solid/src/resource/wac/results/GetWacRuleSuccess.ts b/packages/solid/src/resource/wac/results/GetWacRuleSuccess.ts new file mode 100644 index 0000000..1b472c4 --- /dev/null +++ b/packages/solid/src/resource/wac/results/GetWacRuleSuccess.ts @@ -0,0 +1,7 @@ +import type { ResourceSuccess } from "../../../requester/results/success/SuccessResult"; +import type { WacRule } from "../WacRule"; + +export interface GetWacRuleSuccess extends ResourceSuccess { + type: "getWacRuleSuccess"; + wacRule: WacRule; +} diff --git a/packages/solid/src/resource/wac/results/GetWacUriSuccess.ts b/packages/solid/src/resource/wac/results/GetWacUriSuccess.ts new file mode 100644 index 0000000..f7c98e3 --- /dev/null +++ b/packages/solid/src/resource/wac/results/GetWacUriSuccess.ts @@ -0,0 +1,6 @@ +import type { ResourceSuccess } from "../../../requester/results/success/SuccessResult"; + +export interface GetWacUriSuccess extends ResourceSuccess { + type: "getWacUriSuccess"; + wacUri: string; +} diff --git a/packages/solid/src/resource/wac/results/SetWacRuleSuccess.ts b/packages/solid/src/resource/wac/results/SetWacRuleSuccess.ts new file mode 100644 index 0000000..303f941 --- /dev/null +++ b/packages/solid/src/resource/wac/results/SetWacRuleSuccess.ts @@ -0,0 +1,7 @@ +import type { ResourceSuccess } from "../../../requester/results/success/SuccessResult"; +import type { WacRule } from "../WacRule"; + +export interface SetWacRuleSuccess extends ResourceSuccess { + type: "setWacRuleSuccess"; + wacRule: WacRule; +} diff --git a/packages/solid/src/resource/wac/setWacRule.ts b/packages/solid/src/resource/wac/setWacRule.ts new file mode 100644 index 0000000..e69de29 diff --git a/packages/solid/src/util/rdfUtils.ts b/packages/solid/src/util/rdfUtils.ts index e458f55..a3a4268 100644 --- a/packages/solid/src/util/rdfUtils.ts +++ b/packages/solid/src/util/rdfUtils.ts @@ -1,3 +1,4 @@ +import type { LdoDataset } from "@ldo/ldo"; import { parseRdf } from "@ldo/ldo"; import { namedNode, quad as createQuad } from "@rdfjs/data-model"; import type { Dataset } from "@rdfjs/types"; @@ -115,11 +116,29 @@ export async function addRawTurtleToDataset( dataset: Dataset, baseUri: string, ): Promise { - let loadedDataset: Dataset; + const rawTurtleResult = await rawTurtleToDataset(rawTurtle, baseUri); + if (rawTurtleResult.isError) return rawTurtleResult; + const loadedDataset = rawTurtleResult.dataset; + const graphNode = namedNode(baseUri); + // Destroy all triples that were once a part of this resouce + dataset.deleteMatches(undefined, undefined, undefined, graphNode); + // Add the triples from the fetched item + dataset.addAll( + loadedDataset.map((quad) => + createQuad(quad.subject, quad.predicate, quad.object, graphNode), + ), + ); +} + +export async function rawTurtleToDataset( + rawTurtle: string, + baseUri: string, +): Promise<{ isError: false; dataset: LdoDataset } | NoncompliantPodError> { try { - loadedDataset = await parseRdf(rawTurtle, { + const loadedDataset = await parseRdf(rawTurtle, { baseIRI: baseUri, }); + return { isError: false, dataset: loadedDataset }; } catch (err) { const error = UnexpectedResourceError.fromThrown(baseUri, err); return new NoncompliantPodError( @@ -127,14 +146,4 @@ export async function addRawTurtleToDataset( `Request returned noncompliant turtle: ${error.message}`, ); } - - const graphNode = namedNode(baseUri); - // Destroy all triples that were once a part of this resouce - dataset.deleteMatches(undefined, undefined, undefined, graphNode); - // Add the triples from the fetched item - dataset.addAll( - loadedDataset.map((quad) => - createQuad(quad.subject, quad.predicate, quad.object, graphNode), - ), - ); } diff --git a/packages/solid/test/Integration.test.ts b/packages/solid/test/Integration.test.ts index f448259..1ee33e5 100644 --- a/packages/solid/test/Integration.test.ts +++ b/packages/solid/test/Integration.test.ts @@ -10,6 +10,7 @@ import type { import { changeData, commitData, createSolidLdoDataset } from "../src"; import { ROOT_CONTAINER, + WEB_ID, createApp, getAuthenticatedFetch, } from "./solidServer.helper"; @@ -45,7 +46,7 @@ import type { UnexpectedHttpError, } from "../src/requester/results/error/HttpErrorResult"; import type { NoncompliantPodError } from "../src/requester/results/error/NoncompliantPodError"; -import { wait } from "./utils.helper"; +import type { GetWacRuleSuccess } from "../src/resource/wac/results/GetWacRuleSuccess"; const TEST_CONTAINER_SLUG = "test_ldo/"; const TEST_CONTAINER_URI = @@ -92,6 +93,12 @@ const TEST_CONTAINER_TTL = `@prefix dc: . posix:size 522. posix:mtime 1697810234; posix:size 10.`; +const TEST_CONTAINER_ACL_URI = `${TEST_CONTAINER_URI}.acl`; +const TEST_CONTAINER_ACL = `<#b30e3fd1-b5a8-4763-ad9d-e95de9cf7933> a ; + <${TEST_CONTAINER_URI}>; + <${TEST_CONTAINER_URI}>; + , , , ; + <${WEB_ID}>.`; async function testRequestLoads( request: () => Promise, @@ -167,6 +174,13 @@ describe("Integration", () => { slug: TEST_CONTAINER_SLUG, }, }); + await authFetch(TEST_CONTAINER_ACL_URI, { + method: "PUT", + headers: { + "content-type": "text/turtle", + }, + body: TEST_CONTAINER_ACL, + }); await Promise.all([ authFetch(TEST_CONTAINER_URI, { method: "POST", @@ -1610,4 +1624,36 @@ describe("Integration", () => { ).toBe(true); }); }); + + /** + * =========================================================================== + * ACCESS CONTROL + * =========================================================================== + */ + describe("getWacRule", () => { + it("Fetches a wac rules for a container that has a corresponding acl", async () => { + const container = solidLdoDataset.getResource(TEST_CONTAINER_URI); + const wacResult = await container.getWac(); + expect(wacResult.isError).toBe(false); + const wacSuccess = wacResult as GetWacRuleSuccess; + expect(wacSuccess.wacRule.public).toEqual({ + read: false, + write: false, + append: false, + control: false, + }); + expect(wacSuccess.wacRule.authenticated).toEqual({ + read: false, + write: false, + append: false, + control: false, + }); + expect(wacSuccess.wacRule.agent[WEB_ID]).toEqual({ + read: true, + write: true, + append: true, + control: true, + }); + }); + }); }); diff --git a/packages/solid/test/solidServer.helper.ts b/packages/solid/test/solidServer.helper.ts index 58d8718..3447f96 100644 --- a/packages/solid/test/solidServer.helper.ts +++ b/packages/solid/test/solidServer.helper.ts @@ -23,6 +23,8 @@ const config = [ export const SERVER_DOMAIN = process.env.SERVER || "http://localhost:3001/"; export const ROOT_ROUTE = process.env.ROOT_CONTAINER || ""; export const ROOT_CONTAINER = `${SERVER_DOMAIN}${ROOT_ROUTE}`; +export const WEB_ID = + process.env.WEB_ID || `${SERVER_DOMAIN}example/profile/card#me`; // Use an increased timeout, since the CSS server takes too much setup time. jest.setTimeout(40_000);