diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml deleted file mode 100644 index efcaea13..00000000 --- a/.github/workflows/push.yml +++ /dev/null @@ -1,34 +0,0 @@ - -name: Push - -on: [ push ] - -jobs: - - build: - - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - node-version: - - 20.x # Maintenance - - 22.x # Active - - 23.x # Current - - steps: - - - name: Checkout main branch - uses: actions/checkout@v4 - - - name: Enable Node.js Corepack - run: corepack enable - - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} - - - name: Yarn install - run: yarn install diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..0e4f4078 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,57 @@ + +name: Test + +on: + push: + +concurrency: + group: ${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + + build: + + runs-on: ${{ matrix.operating-system }} + + strategy: + fail-fast: false + matrix: + operating-system: + - ubuntu-latest + # logtalk-actions/setup-swi-prolog@master does not work with windows, so a different solution would be required + # - windows-latest + node-version: + - 20.x + - 22.x + - 24.x + + steps: + + - name: Install prolog + uses: logtalk-actions/setup-swi-prolog@master + + - name: Clone EYE repo + uses: actions/checkout@v4 + with: + repository: eyereasoner/eye + + - name: Build EYE + run: bash install.sh --prefix=$HOME/.local # This folder is available on $PATH already + + - name: Checkout main branch + uses: actions/checkout@v4 + + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + + - name: Enable Node.js Corepack + run: corepack enable + + - name: Yarn install + run: yarn install + + - name: Test + run: yarn test diff --git a/demo/flow-test.ts b/demo/flow-test.ts index 53ed6e5c..c33689d5 100644 --- a/demo/flow-test.ts +++ b/demo/flow-test.ts @@ -5,17 +5,6 @@ import { Parser, Writer, Store } from 'n3'; import { randomUUID } from 'crypto'; import chalk from 'chalk' -// import * as jsonld from 'jsonld'; - -// import vc from '@digitalcredentials/vc'; - -// // Required to set up a suite instance with private key -// import {Ed25519VerificationKey2020} from -// '@digitalcredentials/ed25519-verification-key-2020'; -// import {Ed25519Signature2020} from '@digitalcredentials/ed25519-signature-2020'; - - - const parser = new Parser(); const writer = new Writer(); diff --git a/demo/flow.ts b/demo/flow.ts index b88bca26..da379a4c 100644 --- a/demo/flow.ts +++ b/demo/flow.ts @@ -5,15 +5,6 @@ import { Parser, Writer, Store } from 'n3'; import { randomUUID } from 'crypto'; import chalk from 'chalk' -import * as jsonld from 'jsonld'; - -import vc from '@digitalcredentials/vc'; - -// Required to set up a suite instance with private key -import {Ed25519VerificationKey2020} from - '@digitalcredentials/ed25519-verification-key-2020'; -import {Ed25519Signature2020} from '@digitalcredentials/ed25519-signature-2020'; - const parser = new Parser(); diff --git a/demo/seed.json b/demo/seed.json new file mode 100644 index 00000000..37c598c6 --- /dev/null +++ b/demo/seed.json @@ -0,0 +1,18 @@ +[ + { + "email": "ruben@example.org", + "password": "abc123", + "pods": [{ + "name": "ruben" + }] + }, + { + "email": "demo@example.org", + "password": "abc123", + "pods": [ + { + "name": "demo" + } + ] + } +] diff --git a/docs/policy-management.md b/docs/policy-management.md new file mode 100644 index 00000000..d776db32 --- /dev/null +++ b/docs/policy-management.md @@ -0,0 +1,216 @@ +# Policy Management +In this document we describe the *policy adminstration endpoint*. +It contains the methods to describe how to create, read, update and delete policies. + + + +## Supported endpoints +The current implementation supports the following requests: +- [`GET`](#reading-policies) to both `uma/policies` and `uma/policies/` +- [`POST`](#creating-policies) to `uma/policies` +- [`PATCH`](#updating-policies) to `uma/policies/` +- [`PUT`](#updating-policies) to `uma/policies/` +- [`DELETE`](#deleting-policies) to `uma/policies/` + + +These requests comply with some restrictions: +- When the URL contains a policy ID, it must be [URI encoded](#uri-encoding-decision). +- The request must have its `'Authorization'` header set to the clients webID. More on that [later](#authorizationauthentication-decisions). + + +### Creating policies +Create a policy/multiple policies through a POST request to `/uma/policies`. +Apart from its Authorization header, the `'Content-Type'` must be set to the RDF serialization format in which the body is written. +The accepted formats are those accepted by the [N3 Parser](https://github.com/rdfjs/N3.js/?tab=readme-ov-file#parsing), represented by the following content types: +- `text/turtle` +- `application/trig` +- `application/n-triples` +- `application/n-quads` +- `text/n3` + +The body is expected to represent a valid ODRL policy, although some [sanitization](#sanitization-decisions) is applied to ensure minimal validity. It is possible to POST multiple policies at once, but they have to remain in scope of the client. +Upon success, the server responds with **status code 201**. +Bad requests, possibly due to an improper policy definition, will respond with **status code 400**. +When the policy has been validated, but adding it to the storage fails, the response will have **status code 500**. + +#### Example Request +This example creates a policy `http://example.org/usagePolicy` for client `https://pod.example.com/profile/card#me:` +```curl +curl --location 'http://localhost:4000/uma/policies' \ +--header 'Authorization: https://pod.example.com/profile/card#me' \ +--header 'Content-Type: text/turtle' \ +--data-raw '@prefix ex: . +@prefix odrl: . +@prefix dct: . + +ex:usagePolicy a odrl:Agreement . +ex:usagePolicy odrl:permission ex:permission . +ex:permission a odrl:Permission . +ex:permission odrl:action odrl:read . +ex:permission odrl:target . +ex:permission odrl:assignee . +ex:permission odrl:assigner .' +``` + + + +### Reading policies +To read policies, two endpoints are implemented: +- GET `/uma/policies`: get policy information you are authorized to see, for every policy. +- GET `/uma/policies/`: get policy information you are authorized to see, for the policy with the specified [URI encoded](#uri-encoding-decision) ID. + +#### GET one policy +The algorithm to GET a single policy will use a procedure to separate the policy into different parts: +1. Policy Quads + - Some quads in the policy define rules. Their general form looks like ` .`. These quads are split into rules owned by the client **(1)**, and those owned by another client **(2)**. + - Other quads define other parts about the policy. These quads are set into a group of `policy definitions` **(3)**. +2. Rule Quads + - Owned rule quads are those where the client as an assigner **(4)**. + - Other rule quads are owned by other clients **(5)**. + +The procedure returns an object containing these five groups. Note that the information is discovered through a **depth 1** algorithm, which can not handle `Duty` constructions. +The same procedure is also used in other endpoints, in cases where it is also important what groups **(2)** and **(5)** contain, which is why we also return these. + +The GET endpoint for one policy will call this procedure, processes groups **(1)**, **(3)** and **(4)**. +If group **(1)** is not empty, it will respond with **status code 200** and returns the information in the body with `Content-type: text/turtle`. +If group **(1)** is empty, it will respond with **status code 204** and an empty body. + +An example request to get policy `http://example.org/usagePolicy` for the client with webID `https://pod.example.com/profile/card#me` looks like this: + +```curl +curl --location 'http://localhost:4000/uma/policies/http%3A%2F%2Fexample.org%2FusagePolicy' \ +--header 'Authorization: https://pod.example.com/profile/card#me' +``` + +If the client has viable information about this policy, the server would respond with the information about the policy: +``` + a ; + . + a ; + ; + ; + ; + . + +``` + +#### GET all polices +The current implementation iterates over every quad in the policy that defines a rule, performing a lookup to see if the client is the assigner. +Only then, additional information about the policy AND the rule will be collected, once again only with **depth 1**. The information about the policy will be filtered, because you shouldn't be in able to see the rule definitions of another client. + +This is not done with the procedure from the GET One Policy endpoint, because using it over every policy would be quite exhaustive. + +An example request would look like this: +```curl +curl --location 'http://localhost:4000/uma/policies' \ +--header 'Authorization: https://pod.aexample.com/profile/card#me' +``` + +The response is similar to the GET One Policy response, but for every policy *owned* by the client. + + + +### Updating policies +Updating a policy can be done through a PUT or a PATCH request to `/uma/policies/`, each with different semantics. + +#### PUT +A PUT completely replaces the policy within the scope of the client. +The PUT works as a combination of DELETE and POST. It requires a body with the same content type as the [POST request](#creating-policies). This body will be interpreted as the requested policy with some rules. + +The PUT process: +1. Find information about the policy. If it does not exist, return with a **status code 404** to indicate that you cannot rewrite a nonexistent policy. +2. Parse and validate the body, with the same procedure used in the POST endpoint. First, we perform the basic sanitization checks. Upon success, extra checks are performed to see if the new definition stays within the scope of the client: + - Check that the newly defined policy does not define other policies + - Check that the new policy does not contain any rules that do not belong to the client + - Check that no unrelated quads to the policy and its rules are added. + + Failed checks will result in a response with **status code 400** and a dedicated message. +3. Delete the old policy, but keep a copy for a possible rollback. The deletion uses the procedure used in the [DELETE](#deleting-policies) endpoint. +4. Add the new policy. On success, the server will respond with **status code 200** and a body containing the new policy and its rules (within scope of the client). When this does not succeed, a rollback will be set up: + - The server will try to reset the state of the policy by adding the old quads. If this succeeds, an internal server error with **status code 500** will indicate that nothing has been rewritten, and the old version is restored. + - When the rollback fails, we basically deleted the policy information within our reach. An internal server error with **status code 500** will indicate this. + +Note that this endpoint uses the POST and DELETE functionality to implement the PUT. + +#### PATCH +A PATCH request will update the specified policy. The request expects a body with content type [`application/sparql-query`](https://www.w3.org/TR/rdf-sparql-query/). The INSERT and DELETE properties can be used to modify the requested policy. These modifications can only be applied to parts of the policy within the client's scope. + +The PATCH process: +1. Collect all information about the existing policy with the procedure explained in the [GET One Policy endpoint](#get-one-policy). If the policy does not exist, the server responds with **status code 400**. In the current implementation, we have chosen that the client cannot PATCH a policy in which it has no rules. Doing so will also result in a response with **status code 400**. +2. The content type of the body gets validated. The content-type must be set to `application/sparql-query`. Any other type will result in a response with **status code 400**. +3. We use the policy information to create a store which only contains groups **(1)**, **(3)** and **(4)** as explained [above](#get-one-policy). This will serve as an isolated store, on which we can execute the update query. This implementation has its advantages: + - We do not need to validate the sparql query, since we execute it on an isolated store. + - Performing DELETE queries on rules out of your scope will simply not work, since they are not part of the isolated store. + - We can easily see exactly when the query goes out of scope by testing the resulting store, separating it in the 5 groups and performing the following checks: + 1. If the resulting store has rules out of the clients' scope (indicated by groups **(2)** and **(5)**), we can abort the update and respond with **status code 400**. + 2. We can analyze the size of the resulting store. Substracting the amount of quads within reach should result in 0, since no other rules may be added. This test will fail when the client inserts/deletes any unrelated quads to its own policy. Upon failure, the server responds with **status code 400**. +4. The old definition will be replaced with the updated version. Since no real update function for our storage exists, we delete the old policy and add the resulting store from the query, together with the quads out of scope as collected in step 1. + +Note that any quads in the original policy that could not be collected by the procedure defined in [GET One Policy](#get-one-policy), will not be part of the newly defined policy. + +### Deleting policies +To delete a policy, send a DELETE request to `/uma/policies/` with the URI encoded ID of the policy. + +The DELETE process: +1. Find the rules defined in the policy. +2. Filter the rules that are assigned by the client, and delete them. +3. Find out if there are rules not assigned by the client. + * If there are other rules, we cannot delete the policy information as well. We delete the rule and its definition triple in the policy. + * If there are no other rules, we can delete the entire policy. + +This method used to have one rather significant issue, as discussed [later](#delete-fix). + + +## Implementation details + +#### Authorization/Authentication decisions +The current implementation has insufficient authentication restrictions. Currently, the only requirement is that the 'Authorization' header is to be set to the webID of the "logged on" client. Proper procedures to authenticate this client are still to be implemented. + +#### Sanitization decisions +Some endpoints allow new policies to be created, or existing policies to be modified. This introduces the possibility of invalid syntactic or semantic policies, hence a sanitization strategy is required. In the current implementation, only POST, PUT and PATCH could introduce such problems. We provided the following basic checks: +- Every defined rule must have a unique ID. +- Every rule must have exactly one assigner. +- Every assigner must match the authenticated client. + +Sanitization Limitations +- There are currently no checks to verify whether a client is sufficiently authorized to create or modify a policy/rule for a specific target. + * A client should not be in able to alter rights about a target it does not have access to. + + This issue is currently being solved in [a dedicated PR](https://github.com/SolidLabResearch/user-managed-access/pull/50) +- There are plenty of other sanitization checks to be considered. + +#### URI encoding decision +Some operations require the client to specify a policy ID in the URL. Since policy ID's might contain reserved characters (e.g. `/`, `:`, ...), we have chosen to encode them with the builtin [`encodeURIComponent()` function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent). Using this method, reserved characters will be converted to their respective UTF-8 encodings. + +## Testing +The current implementation is tested only by the script in `scripts\test-uma-ODRL-policy.ts`. This script tests every implemented endpoint with a designated flow. Since the script initiates with an empty storage, and there is no endpoint or other way to seed it, the first requests must test the POST endpoint. These tests are designed to ensure that the storage is filled. After the POST tests, the access endpoints can be tested. Every endpoint gets tested in this script, which makes sure that the added data is removed. The current testing will be replaced with proper unit tests and integration tests in the near future. + +## TODO +- The current [sanitization limitations](#sanitization-decisions) are to be considered. +- Fix CORS handling: the project configuration must be extended to the `/policies` endpoint. +- Implement Unit Tests +- ... + + +### Solved Problems + +#### DELETE fix + +##### Problem +When you have a policy with multiple rules that have different assigners, DELETE on every rule of one assigner will succesfully delete the rule itself, but not the definition of the rule within the policy. This is due to the fact that you can currently only DELETE based on the ID of the rule/policy you want to delete, and you cannot delete the entire policy since other assigners depend on it. Currently, the only problem with this is filling space, since the quads defining deleted rules will not be returned in GET requests. + +##### Fix +We created a new RulesStorage function, made specifically to fix our problem entirely. The function is implemented to delete the rule AND its definition in the policy. This solution is still a bit experimental. + + +#### PATCH fix +PATCH used to contain a safety hazard. When client A has a certain policy/rule, or even just a certain quad, this could be discovered by an intrusive client B. Client B could simply PATCH an INSERT of a random quad that does NOT belong to its own rules/policies, which can have one of three outcomes: +1. The PATCH resolves in an error saying that you cannot change rules that do not belong to you. This means that the quad belongs to some other client, since it has been detected as a quad owned by someone else. +2. The PATCH resolves in an error saying that you cannot change rules that belong to nobody. This means that the quad is not affiliated with any client. +3. The PATCH completes with code 200. Since the inserted quad does NOT belong to you, there must be another client that owns the quad. In this way, any policy can be discovered (exhaustively). +An extra constraint, disabling clients to PATCH policies it has no rules in, would still enable the client to exploit policies that it has rules in. + +This problem was solved by splitting the policy into the parts where the client has access to, and the parts where it does not. By executing the query only on the parts that the client has access to, it would be easier to analyse the resulting store of the query. If this store has rules that the client does not have access to, they must have been added by the client and the operation gets cancelled. This method is also protected from deleting rules out of our reach. + +#### POST checks +It is now impossible to POST an already existing policy or already existing rules. This means that a policy can only be POSTED once. If a client wishes to be a part of a policy, it has to do it through a PUT request. If a client is already part of the policy, it can PATCH modifications. \ No newline at end of file diff --git a/package.json b/package.json index b199b457..01bd25a2 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ } ], "private": true, - "packageManager": "yarn@4.1.0", + "packageManager": "yarn@4.9.2", "engines": { "node": ">=20.0", "yarn": ">=4.0" @@ -54,18 +54,20 @@ "postinstall": "yarn run sync:list && yarn build", "clean": "shx rm -rf ./**/node_modules", "build": "yarn workspaces foreach --include 'packages/*' -A -pi -j unlimited -t run build", - "test": "yarn workspaces foreach --include 'packages/*' -A -pi -j unlimited run test", + "test": "vitest run", "start": "yarn workspaces foreach --include 'packages/*' -A -pi -j unlimited run start", "start:odrl": "yarn workspace @solidlab/uma run start:odrl & yarn workspace @solidlab/uma-css run start", "start:demo": "yarn workspaces foreach --include 'packages/*' -A -pi -j unlimited run demo", "script:demo": "yarn exec tsx ./demo/flow.ts", "script:demo-test": "yarn exec tsx ./demo/flow-test.ts", - "script:public": "yarn exec ts-node ./scripts/test-public.ts", - "script:private": "yarn exec ts-node ./scripts/test-private.ts", - "script:registration": "yarn exec ts-node ./scripts/test-registration.ts", - "script:uma-ucp": "yarn exec ts-node ./scripts/test-uma-ucp.ts", - "script:uma-odrl": "yarn exec ts-node ./scripts/test-uma-ODRL.ts", - "script:uma-odrl-policy": "yarn exec ts-node ./scripts/test-uma-ODRL-policy.ts", + "script:demo-uma-policy": "yarn exec tsx ./scripts/demo-uma-policy.ts", + "script:public": "yarn exec tsx ./scripts/test-public.ts", + "script:private": "yarn exec tsx ./scripts/test-private.ts", + "script:registration": "yarn exec tsx ./scripts/test-registration.ts", + "script:seed": "yarn exec tsx ./scripts/seed-uma-ODRL-policy.ts", + "script:uma-ucp": "yarn exec tsx ./scripts/test-uma-ucp.ts", + "script:uma-odrl": "yarn exec tsx ./scripts/test-uma-ODRL.ts", + "script:uma-odrl-policy": "yarn exec tsx ./scripts/test-uma-ODRL-policy.ts", "script:flow": "yarn run script:public && yarn run script:private && yarn run script:uma-ucp && yarn run script:registration", "sync:list": "syncpack list-mismatches", "sync:fix": "syncpack fix-mismatches" @@ -73,34 +75,27 @@ "devDependencies": { "@commitlint/cli": "^16.1.0", "@commitlint/config-conventional": "^16.0.0", - "@solidlab/ucp": "workspace:^", "@types/jest": "^29.5.12", - "@types/node": "^20.11.25", + "@types/node": "^20.19.1", "@typescript-eslint/eslint-plugin": "^5.12.1", "@typescript-eslint/parser": "^5.12.1", + "chalk": "^5.4.1", "componentsjs-generator": "^3.1.2", - "concurrently": "^8.2.2", "eslint": "^8.10.0", - "jest": "^29.7.0", "jest-rdf": "^1.8.1", - "koreografeye": "^0.4.8", "shx": "^0.3.4", "syncpack": "^13.0.2", - "ts-jest": "^29.1.2", - "ts-node": "^10.9.2", - "typescript": "^5.3.3" + "tsx": "^4.19.2", + "typescript": "^5.8.3", + "vite": "^6.3.5", + "vitest": "^3.2.3" }, "resolutions": { - "@types/node": "^20.11.25" + "@types/node": "^20.19.1" }, "workspaces": [ "packages/*" ], - "jest": { - "projects": [ - "./packages/*/package.json" - ] - }, "eslintConfig": { "env": { "browser": true, @@ -155,19 +150,5 @@ ] ] } - }, - "dependencies": { - "@digitalbazaar/ed25519-signature-2020": "^5.4.0", - "@digitalbazaar/ed25519-verification-key-2020": "^4.2.0", - "@digitalbazaar/vc": "^7.1.0", - "@digitalcredentials/ed25519-signature-2020": "^6.0.0", - "@digitalcredentials/ed25519-verification-key-2020": "^4.0.0", - "@digitalcredentials/vc": "^9.0.1", - "@digitalcredentials/vc-data-model": "^2.0.0", - "@inrupt/solid-client": "^2.0.1", - "@inrupt/solid-client-authn-core": "^2.1.0", - "chalk": "^5.4.1", - "jsonld": "^8.3.3", - "tsx": "^4.19.2" } } \ No newline at end of file diff --git a/packages/css/config/default.json b/packages/css/config/default.json index 4b6d6bec..d137948d 100644 --- a/packages/css/config/default.json +++ b/packages/css/config/default.json @@ -28,7 +28,7 @@ "css:config/storage/key-value/resource-store.json", "css:config/storage/location/pod.json", "css:config/storage/middleware/default.json", - "css:config/util/auxiliary/acl.json", + "css:config/util/auxiliary/empty.json", "css:config/util/identifiers/suffix.json", "css:config/util/index/default.json", "css:config/util/logging/winston.json", diff --git a/packages/css/config/demo.json b/packages/css/config/demo.json index 55a30e82..711a8cf8 100644 --- a/packages/css/config/demo.json +++ b/packages/css/config/demo.json @@ -5,7 +5,6 @@ ], "import": [ "uma-css:config/default.json", - "uma-css:config/derived.json", "css:config/storage/backend/data-accessors/file.json" ], "@graph": [ diff --git a/packages/css/config/derived.json b/packages/css/config/derived.json deleted file mode 100644 index 5ca653eb..00000000 --- a/packages/css/config/derived.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "@context": [ - "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", - "https://linkedsoftwaredependencies.org/bundles/npm/@solidlab/derived-resources-component/^1.0.0/components/context.jsonld" - ], - "@graph": [ - { - "comment": "We need to disable the index store as it might accidentally return derived template resources.", - "@id": "urn:solid-server:default:ResourceStore_Index", - "@type": "IndexRepresentationStore", - "mediaRange": "" - }, - { - "comment": "A second converting store", - "@id": "urn:solid-server:derived:RepresentationConvertingStore", - "@type": "RepresentationConvertingStore", - "metadataStrategy": { "@id": "urn:solid-server:default:MetadataStrategy" }, - "options_inConverter": { "@id": "urn:solid-server:default:RepresentationConverter" }, - "options_outConverter": { "@id": "urn:solid-server:default:UiEnabledConverter" }, - "source": { "@id": "urn:solid-server:derived:DerivedResourceStore" } - }, - { - "comment": "The store responsible for generating derived resources.", - "@id": "urn:solid-server:derived:DerivedResourceStore", - "@type": "DerivedResourceStore", - "manager": { - "@id": "urn:solid-server:derived:DerivationManager", - "@type": "MetadataDerivationManager", - "identifierStrategy": { "@id": "urn:solid-server:default:IdentifierStrategy" }, - "store": { "@id": "urn:solid-server:default:ResourceStore_Patching" }, - "derivationMatcher": { - "@type": "PresetDerivationMatcher", - "source": { "@type": "TemplateDerivationMatcher" } - }, - "selectorHandler": { - "@id": "urn:solid-server:default:SelectorHandler", - "@type": "GlobSelectorHandler", - "store": { "@id": "urn:solid-server:default:ResourceStore_Patching" } - }, - "filterHandler": { - "@id": "urn:solid-server:default:FilterHandler", - "@type": "SparqlFilterHandler", - "store": { "@id": "urn:solid-server:default:ResourceStore_Patching" } - } - }, - "source": { "@id": "urn:solid-server:default:ResourceStore_Patching" } - }, - { - "comment": "Insert our new stores in front of the original converting store.", - "@id": "urn:solid-server:derived:PatchOverride", - "@type": "Override", - "overrideInstance": { "@id": "urn:solid-server:default:ResourceStore_Locking" }, - "overrideParameters": { - "@type": "PatchingStore", - "source": { "@id": "urn:solid-server:derived:RepresentationConvertingStore" } - } - }, - { - "comment": [ - "Keep query parameters in identifiers.", - "This makes it so that any query parameters can cause issues with normal resources so we might want a more robust solution." - ], - "@id": "urn:solid-server:derived:TargetExtractorOverride", - "@type": "Override", - "overrideInstance": { "@id": "urn:solid-server:default:TargetExtractor" }, - "overrideParameters": { - "@type": "OriginalUrlExtractor", - "includeQueryString": true - } - } - ] -} diff --git a/packages/css/config/ldp/authorization/readers/uma.json b/packages/css/config/ldp/authorization/readers/uma.json index d22f1f95..ff1b6cd0 100644 --- a/packages/css/config/ldp/authorization/readers/uma.json +++ b/packages/css/config/ldp/authorization/readers/uma.json @@ -13,30 +13,24 @@ "requestedModes" ], "source": { - "comment": "Requests permissions on subject resources for auxiliary resources.", - "@type": "AuxiliaryReader", - "auxiliaryStrategy": { - "@id": "urn:solid-server:default:AuxiliaryStrategy" - }, - "reader": { - "@type": "UnionPermissionReader", - "readers": [ - { - "comment": "This PermissionReader will be used to prevent external access to containers used for internal storage.", - "@id": "urn:solid-server:default:PathBasedReader", - "@type": "PathBasedReader", - "baseUrl": { - "@id": "urn:solid-server:default:variable:baseUrl" - } - }, - { - "comment": "The main reader, checks permissions from UMA token.", - "@id": "urn:solid-server:default:UmaPermissionReader", - "@type": "UmaPermissionReader" + "@id": "urn:uma:default:UnionPermissionReader", + "@type": "UnionPermissionReader", + "readers": [ + { + "comment": "This PermissionReader will be used to prevent external access to containers used for internal storage.", + "@id": "urn:solid-server:default:PathBasedReader", + "@type": "PathBasedReader", + "baseUrl": { + "@id": "urn:solid-server:default:variable:baseUrl" } - ] - } + }, + { + "comment": "The main reader, checks permissions from UMA token.", + "@id": "urn:solid-server:default:UmaPermissionReader", + "@type": "UmaPermissionReader" + } + ] } } ] -} \ No newline at end of file +} diff --git a/packages/css/config/seed.json b/packages/css/config/seed.json index 515cc295..efda127c 100644 --- a/packages/css/config/seed.json +++ b/packages/css/config/seed.json @@ -2,46 +2,25 @@ { "email": "alice@example.org", "password": "abc123", - "authz": { - "server": "http://localhost:4000/uma" - }, - "pods": [{ - "name": "alice", - "settings": { - "name": "Alice", - "umaServer": "http://localhost:4000/uma" - } + "pods": [{ + "name": "alice" }] }, { "email": "bob@example.org", "password": "abc123", - "authz": { - "server": "http://localhost:4000/uma" - }, "pods": [ { - "name": "bob", - "settings": { - "name": "Bob", - "umaServer": "http://localhost:4000/uma" - } + "name": "bob" } ] }, { "email": "demo@example.org", "password": "abc123", - "authz": { - "server": "http://localhost:4000/uma" - }, "pods": [ { - "name": "demo", - "settings": { - "name": "Demo", - "umaServer": "http://localhost:4000/uma" - } + "name": "demo" } ] } diff --git a/packages/css/config/uma/default.json b/packages/css/config/uma/default.json index 61ddfd5f..94050854 100644 --- a/packages/css/config/uma/default.json +++ b/packages/css/config/uma/default.json @@ -8,6 +8,7 @@ "uma-css:config/uma/overrides/authorization-handler.json", "uma-css:config/uma/overrides/authorizer.json", "uma-css:config/uma/overrides/jwks.json", + "uma-css:config/uma/overrides/modes.json", "uma-css:config/uma/overrides/token-extractor.json", "uma-css:config/uma/overrides/www-auth.json", diff --git a/packages/css/config/uma/overrides/modes.json b/packages/css/config/uma/overrides/modes.json new file mode 100644 index 00000000..d85e4df8 --- /dev/null +++ b/packages/css/config/uma/overrides/modes.json @@ -0,0 +1,31 @@ +{ + "@context": [ + "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "https://linkedsoftwaredependencies.org/bundles/npm/@solidlab/uma-css/^0.0.0/components/context.jsonld" + ], + "@graph": [ + { + "comment": "Replace the account seeder with the UMA version so the AS is taken into account.", + "@id": "urn:solid-server:override:ModesExtractor", + "@type": "Override", + "overrideInstance": { + "@id": "urn:solid-server:default:ModesExtractor" + }, + "overrideParameters": { + "@type": "CachedHandler", + "source": { + "@id": "urn:uma:default:AuxiliaryModesExtractor", + "@type": "AuxiliaryModesExtractor", + "source": { + "comment": "Checks if an operation on a resource requires permissions on intermediate resources (such as newly created parent containers).", + "@type": "IntermediateCreateExtractor", + "resourceSet": { "@id": "urn:solid-server:default:CachedResourceSet" }, + "strategy": { "@id": "urn:solid-server:default:IdentifierStrategy" }, + "source": { "@id": "urn:solid-server:default:HttpModesExtractor" } + }, + "auxiliaryStrategy": { "@id": "urn:solid-server:default:AuxiliaryStrategy" } + } + } + } + ] +} diff --git a/packages/css/package.json b/packages/css/package.json index 77fbab42..b6213d3f 100644 --- a/packages/css/package.json +++ b/packages/css/package.json @@ -36,7 +36,7 @@ } ], "private": true, - "packageManager": "yarn@4.0.2", + "packageManager": "yarn@4.9.2", "engines": { "node": ">=20.0", "yarn": ">=4.0" @@ -59,7 +59,6 @@ "build": "yarn build:ts && yarn build:components", "build:ts": "yarn run -T tsc", "build:components": "yarn run -T componentsjs-generator -r uma-css -s src/ -c dist/components -i .componentsignore --lenient", - "test": "yarn run -T jest --coverage", "start:unseeded": "yarn run community-solid-server -m . -c ./config/default.json -a http://localhost:4000/", "start": "yarn run community-solid-server -m . -c ./config/default.json --seedConfig ./config/seed.json -a http://localhost:4000/", "demo": "yarn run demo:setup && yarn run demo:start", @@ -68,7 +67,6 @@ }, "dependencies": { "@solid/community-server": "^7.1.7", - "@solidlab/derived-resources-component": "^1.0.2", "@solidlab/uma": "workspace:^", "@types/n3": "^1.16.4", "componentsjs": "^5.5.1", @@ -77,11 +75,6 @@ "jose": "^5.2.2", "n3": "^1.17.2" }, - "jest": { - "preset": "ts-jest", - "testEnvironment": "node", - "testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts)$" - }, "lsd:module": "https://linkedsoftwaredependencies.org/bundles/npm/@solidlab/uma-css", "lsd:components": "dist/components/components.jsonld", "lsd:contexts": { diff --git a/packages/css/src/authorization/AuxiliaryModesExtractor.ts b/packages/css/src/authorization/AuxiliaryModesExtractor.ts new file mode 100644 index 00000000..57ebadfc --- /dev/null +++ b/packages/css/src/authorization/AuxiliaryModesExtractor.ts @@ -0,0 +1,48 @@ +import { AccessMap, AuxiliaryStrategy, ModesExtractor, Operation } from '@solid/community-server'; + +/** + * When targeting an auxiliary resource, + * this class will set the subject resource as the target instead. + * + * Below is some context on why this class is needed, compared to how permissions are done in the CSS. + * There are 2 major components for permissions: a `ModesExtractor`, + * which determines which permissions are needed to perform a certain operation on a resource, + * and a `PermissionReader`, which determines which permissions are allowed (based on credentials) on that resource. + * The `Authorizer` then checks if these match. + * The Solid protocol defines that if you have access to a resource, you have access to its auxiliary resources. + * The default CSS implementation handles this by extracting modes with the auxiliary resource as target, + * and having a permission reader that is smart enough + * to know it has to check the subject resource for the actual permissions. + * + * The above cannot work with the UMA setup, or at least not with how the other related components are implemented. + * With UMA, the Resource Server extracts the modes, and then sends the result to the Authorization Server. + * In the case of auxiliary resources, this means it sends the identifier of the auxiliary resource. + * The Authorization server does not know that the permissions of the subject resource should be used, + * so this would require having policies for auxiliary resources as well, + * which is not ideal. + * In case you do want to have separate policies for those, this class should be removed from the configuration. + */ +export class AuxiliaryModesExtractor extends ModesExtractor { + public constructor( + protected readonly source: ModesExtractor, + protected readonly auxiliaryStrategy: AuxiliaryStrategy, + ) { + super(); + } + + public async canHandle(input: Operation): Promise { + return this.source.canHandle(input); + } + + public async handle(input: Operation): Promise { + const result = await this.source.handle(input); + const keys = [ ...result.distinctKeys() ]; + for (const key of keys) { + if (this.auxiliaryStrategy.isAuxiliaryIdentifier(key) && !this.auxiliaryStrategy.usesOwnAuthorization(key)) { + result.set(this.auxiliaryStrategy.getSubjectIdentifier(key), result.get(key)!); + result.delete(key); + } + } + return result; + } +} diff --git a/packages/css/src/index.ts b/packages/css/src/index.ts index 22113daf..86784098 100644 --- a/packages/css/src/index.ts +++ b/packages/css/src/index.ts @@ -1,5 +1,6 @@ export * from './authentication/UmaTokenExtractor'; +export * from './authorization/AuxiliaryModesExtractor'; export * from './authorization/UmaAuthorizer'; export * from './authorization/UmaPermissionReader'; diff --git a/packages/css/src/util/OwnerUtil.ts b/packages/css/src/util/OwnerUtil.ts index d192c59d..baa0d943 100644 --- a/packages/css/src/util/OwnerUtil.ts +++ b/packages/css/src/util/OwnerUtil.ts @@ -51,9 +51,6 @@ export class OwnerUtil { this.logger.debug(`Looking up owners of pod ${pod.id}`); - const as = await this.accountStore.getSetting(pod.accountId, ACCOUNT_SETTINGS_AUTHZ_SERVER); - this.logger.warn(`REAL AS is ${JSON.stringify(as)}`); - const owners = await this.podStore.getOwners(pod.id); if (!owners) throw new Error(`Unable to find owners for pod ${storage.path}`); diff --git a/packages/ucp/jest.config.js b/packages/ucp/jest.config.js deleted file mode 100644 index 2561ff18..00000000 --- a/packages/ucp/jest.config.js +++ /dev/null @@ -1,20 +0,0 @@ -module.exports = { - clearMocks: true, - moduleFileExtensions: ['ts', 'js'], - roots: ['/test/'], - testEnvironment: 'node', - transform: { - '^.+\\.ts?$': 'ts-jest', - }, - collectCoverage: true, - coverageReporters: ['text', 'lcov'], - coveragePathIgnorePatterns: [ - '/dist/', - '/node_modules/', - ], - moduleNameMapper: { - '^jose/(.*)$': '/node_modules/jose/dist/node/cjs/$1', - }, - testTimeout: 60000, - setupFilesAfterEnv: ["jest-rdf"] -} \ No newline at end of file diff --git a/packages/ucp/jest.coverage.config.js b/packages/ucp/jest.coverage.config.js deleted file mode 100644 index 4e0062d7..00000000 --- a/packages/ucp/jest.coverage.config.js +++ /dev/null @@ -1,13 +0,0 @@ -const jestConfig = require('./jest.config'); - -module.exports = { - ...jestConfig, - coverageThreshold: { - './src': { - branches: 100, - functions: 100, - lines: 100, - statements: 100, - }, - }, -}; \ No newline at end of file diff --git a/packages/ucp/package.json b/packages/ucp/package.json index c2726fe4..18995280 100644 --- a/packages/ucp/package.json +++ b/packages/ucp/package.json @@ -31,7 +31,7 @@ } ], "private": true, - "packageManager": "yarn@4.0.2", + "packageManager": "yarn@4.9.2", "engines": { "node": ">=20.0", "yarn": ">=4.0" @@ -53,14 +53,7 @@ "scripts": { "build": "yarn build:ts && yarn build:components", "build:ts": "yarn run -T tsc", - "build:components": "yarn run -T componentsjs-generator -r ucp -s src -c dist/components -i .componentsignore --lenient", - "test": "yarn run test:unit && yarn run test:integration", - "test:unit": "jest test/unit", - "test:integration": "yarn run test:engines && yarn exec ts-node test/integration/ContainerRulesStorage.ts", - "test:engines": "yarn run test:log-engine && yarn run test:crud-engine && yarn run test:crud-temporal-engine", - "test:log-engine": "yarn exec ts-node test/integration/LogEngine.ts", - "test:crud-engine": "yarn exec ts-node test/integration/CrudEngine.ts", - "test:crud-temporal-engine": "yarn exec ts-node test/integration/CrudEngineTemporal.ts" + "build:components": "yarn run -T componentsjs-generator -r ucp -s src -c dist/components -i .componentsignore --lenient" }, "dependencies": { "@smessie/readable-web-to-node-stream": "^3.0.3", diff --git a/packages/ucp/src/storage/ContainerUCRulesStorage.ts b/packages/ucp/src/storage/ContainerUCRulesStorage.ts index 3866b512..b852dc1a 100644 --- a/packages/ucp/src/storage/ContainerUCRulesStorage.ts +++ b/packages/ucp/src/storage/ContainerUCRulesStorage.ts @@ -18,6 +18,9 @@ export class ContainerUCRulesStorage implements UCRulesStorage { console.log(`[${new Date().toISOString()}] - ContainerUCRulesStore: LDP Container that will be used as source for the Usage Control Rules`, this.containerURL); this.fetch = customFetch ?? fetch; } + async deleteRuleFromPolicy(ruleID: string, PolicyID: string){ + return new Promise(() => {}) + } public async getStore(): Promise { const store = new Store() diff --git a/packages/ucp/src/storage/DirectoryUCRulesStorage.ts b/packages/ucp/src/storage/DirectoryUCRulesStorage.ts index 6d8f231b..67a2cccb 100644 --- a/packages/ucp/src/storage/DirectoryUCRulesStorage.ts +++ b/packages/ucp/src/storage/DirectoryUCRulesStorage.ts @@ -1,35 +1,40 @@ import { UCRulesStorage } from "./UCRulesStorage"; import * as path from 'path' import * as fs from 'fs' -import { Store } from "n3"; -import { parseAsN3Store } from "koreografeye"; +import { Parser, Store, Writer } from 'n3'; export class DirectoryUCRulesStorage implements UCRulesStorage { - private directoryPath: string; + protected directoryPath: string; + protected readonly baseIRI: string; + /** - * + * * @param directoryPath The absolute path to a directory + * @param baseIRI The base to use when parsing RDF documents. */ - public constructor(directoryPath: string) { + public constructor(directoryPath: string, baseIRI: string) { this.directoryPath = path.resolve(directoryPath); - console.log(`[${new Date().toISOString()}] - DirectoryUCRulesStore: Path that will be used as source directory for the Usage Control Rules`, this.directoryPath); if (!fs.lstatSync(directoryPath).isDirectory()) { throw Error(`${directoryPath} does not resolve to a directory`) } + this.baseIRI = baseIRI; } public async getStore(): Promise { const store = new Store() + const parser = new Parser({ baseIRI: this.baseIRI }); const files = fs.readdirSync(this.directoryPath).map(file => path.join(this.directoryPath, file)) for (const file of files) { - const fileStore = await parseAsN3Store(file) - store.addQuads(fileStore.getQuads(null, null, null, null)) + const quads = parser.parse((await fs.promises.readFile(file)).toString()); + store.addQuads(quads); } return store; } - + async deleteRuleFromPolicy(ruleID: string, PolicyID: string) { + return new Promise(() => { }) + } public async addRule(rule: Store): Promise { throw Error('not implemented'); } @@ -40,4 +45,3 @@ export class DirectoryUCRulesStorage implements UCRulesStorage { throw Error('not implemented'); } } - diff --git a/packages/ucp/src/storage/MemoryUCRulesStorage.ts b/packages/ucp/src/storage/MemoryUCRulesStorage.ts index e0b8b62d..e9d0af75 100644 --- a/packages/ucp/src/storage/MemoryUCRulesStorage.ts +++ b/packages/ucp/src/storage/MemoryUCRulesStorage.ts @@ -1,7 +1,9 @@ -import { Store } from "n3"; +import { DataFactory, Store } from "n3"; import { extractQuadsRecursive } from "../util/Util"; import { UCRulesStorage } from "./UCRulesStorage"; +const { namedNode } = DataFactory; + export class MemoryUCRulesStorage implements UCRulesStorage { private store: Store; @@ -27,4 +29,11 @@ export class MemoryUCRulesStorage implements UCRulesStorage { const store = await this.getRule(identifier) this.store.removeQuads(store.getQuads(null, null, null, null)); } + + public async deleteRuleFromPolicy(ruleID: string, PolicyID: string) { + // Delete the rule and its definition in the policy + this.store.getQuads(namedNode(PolicyID), null, namedNode(ruleID), null).forEach(quad => this.store.delete(quad)); + this.deleteRule(ruleID); + } + } \ No newline at end of file diff --git a/packages/ucp/src/storage/UCRulesStorage.ts b/packages/ucp/src/storage/UCRulesStorage.ts index e0a30c7f..aa33748e 100644 --- a/packages/ucp/src/storage/UCRulesStorage.ts +++ b/packages/ucp/src/storage/UCRulesStorage.ts @@ -20,4 +20,11 @@ export interface UCRulesStorage { * @returns */ deleteRule: (identifier: string) => Promise; + + /** + * Delete a Usage Control Rule with its reference from the storage + * @param identifier + * @returns + */ + deleteRuleFromPolicy: (ruleID: string, PolicyID: string) => Promise; } \ No newline at end of file diff --git a/packages/uma/bin/demo.ts b/packages/uma/bin/demo.js similarity index 62% rename from packages/uma/bin/demo.ts rename to packages/uma/bin/demo.js index e704569b..4bde38ec 100644 --- a/packages/uma/bin/demo.ts +++ b/packages/uma/bin/demo.js @@ -1,6 +1,6 @@ -import * as path from 'path'; -import { ComponentsManager } from 'componentsjs'; -import { ServerInitializer, setGlobalLoggerFactory, WinstonLoggerFactory } from '@solid/community-server'; +const path = require('path'); +const { ComponentsManager } = require('componentsjs'); +const { setGlobalLoggerFactory, WinstonLoggerFactory } = require('@solid/community-server'); const protocol = 'http'; const host = 'localhost'; @@ -9,13 +9,14 @@ const port = 4000; const baseUrl = `${protocol}://${host}:${port}/uma`; const rootDir = path.join(__dirname, '../'); -export const launch: () => Promise = async () => { - const variables: Record = {}; +const launch = async () => { + const variables = {}; variables['urn:uma:variables:port'] = port; variables['urn:uma:variables:baseUrl'] = baseUrl; // variables['urn:uma:variables:policyDir'] = path.join(rootDir, './config/rules/policy'); + variables['urn:uma:variables:policyContainer'] = 'http://localhost:3000/ruben/settings/policies/'; variables['urn:uma:variables:eyePath'] = 'eye'; const configPath = path.join(rootDir, './config/demo.json'); @@ -30,8 +31,8 @@ export const launch: () => Promise = async () => { await manager.configRegistry.register(configPath); - const umaServer: ServerInitializer = await manager.instantiate('urn:uma:default:NodeHttpServer',{variables}); - await umaServer.handleSafe(); + const umaServer = await manager.instantiate('urn:uma:default:App',{variables}); + await umaServer.start(); }; launch(); diff --git a/packages/uma/bin/main.ts b/packages/uma/bin/main.js similarity index 62% rename from packages/uma/bin/main.ts rename to packages/uma/bin/main.js index 37d7eebc..1f8dcc57 100644 --- a/packages/uma/bin/main.ts +++ b/packages/uma/bin/main.js @@ -1,6 +1,6 @@ -import * as path from 'path'; -import { ComponentsManager } from 'componentsjs'; -import { ServerInitializer, setGlobalLoggerFactory, WinstonLoggerFactory } from '@solid/community-server'; +const path = require('path'); +const { ComponentsManager } = require('componentsjs'); +const { setGlobalLoggerFactory, WinstonLoggerFactory } = require('@solid/community-server'); const protocol = 'http'; const host = 'localhost'; @@ -9,12 +9,13 @@ const port = 4000; const baseUrl = `${protocol}://${host}:${port}/uma`; const rootDir = path.join(__dirname, '../'); -export const launch: () => Promise = async () => { - const variables: Record = {}; +const launch = async () => { + const variables = {}; variables['urn:uma:variables:port'] = port; variables['urn:uma:variables:baseUrl'] = baseUrl; + variables['urn:uma:variables:policyBaseIRI'] = 'http://localhost:3000/'; variables['urn:uma:variables:policyDir'] = path.join(rootDir, './config/rules/policy'); variables['urn:uma:variables:eyePath'] = 'eye'; @@ -30,8 +31,8 @@ export const launch: () => Promise = async () => { await manager.configRegistry.register(configPath); - const umaServer: ServerInitializer = await manager.instantiate('urn:uma:default:NodeHttpServer',{variables}); - await umaServer.handleSafe(); + const umaServer = await manager.instantiate('urn:uma:default:App',{variables}); + await umaServer.start(); }; launch(); diff --git a/packages/uma/bin/odrl.ts b/packages/uma/bin/odrl.js similarity index 63% rename from packages/uma/bin/odrl.ts rename to packages/uma/bin/odrl.js index c7a39a6a..97785bdd 100644 --- a/packages/uma/bin/odrl.ts +++ b/packages/uma/bin/odrl.js @@ -1,6 +1,6 @@ -import { ServerInitializer, setGlobalLoggerFactory, WinstonLoggerFactory } from '@solid/community-server'; -import * as path from 'path'; -import { ComponentsManager } from 'componentsjs'; +const path = require('path'); +const { ComponentsManager } = require('componentsjs'); +const { setGlobalLoggerFactory, WinstonLoggerFactory } = require('@solid/community-server'); const protocol = 'http'; const host = 'localhost'; @@ -9,12 +9,13 @@ const port = 4000; const baseUrl = `${protocol}://${host}:${port}/uma`; const rootDir = path.join(__dirname, '../'); -export const launch: () => Promise = async () => { - const variables: Record = {}; +const launch = async () => { + const variables = {}; variables['urn:uma:variables:port'] = port; variables['urn:uma:variables:baseUrl'] = baseUrl; + variables['urn:uma:variables:policyBaseIRI'] = 'http://localhost:3000/'; variables['urn:uma:variables:policyDir'] = path.join(rootDir, './config/rules/odrl'); variables['urn:uma:variables:eyePath'] = 'eye'; @@ -30,8 +31,8 @@ export const launch: () => Promise = async () => { await manager.configRegistry.register(configPath); - const umaServer: ServerInitializer = await manager.instantiate('urn:uma:default:NodeHttpServer',{variables}); - await umaServer.handleSafe(); + const umaServer = await manager.instantiate('urn:uma:default:App',{variables}); + await umaServer.start(); }; launch(); diff --git a/packages/uma/config/default.json b/packages/uma/config/default.json index a264f9c3..4fcdfe6f 100644 --- a/packages/uma/config/default.json +++ b/packages/uma/config/default.json @@ -25,6 +25,23 @@ "sai-uma:config/variables/default.json" ], "@graph": [ + { + "comment": "This is the entry point to the application. It can be used to both start and stop the server.", + "@id": "urn:uma:default:App", + "@type": "App", + "initializer": { "@id": "urn:uma:default:NodeHttpServer" }, + "finalizer": { + "@id": "urn:uma:default:Finalizer", + "@type": "SequenceHandler", + "handlers": [ + { + "comment": "Provides handler to shut down the server", + "@type": "FinalizableHandler", + "finalizable": { "@id": "urn:uma:default:NodeHttpServer" } + } + ] + } + }, { "@id": "urn:uma:default:NodeHttpServer", "@type": "ServerInitializer", @@ -89,28 +106,44 @@ "@id": "urm:uma:default:JsonHttpErrorHandler", "@type": "JsonHttpErrorHandler", "handler": { - "@id": "urm:uma:default:JsonFormHttpHandler", - "@type": "JsonFormHttpHandler", - "handler": { - "@id": "urn:uma:default:RoutedHttpRequestHandler", - "@type": "RoutedHttpRequestHandler", - "routes": [ - { "@id": "urn:uma:default:UmaConfigRoute" }, - { "@id": "urn:uma:default:JwksRoute" }, - { "@id": "urn:uma:default:TokenRoute" }, - { "@id": "urn:uma:default:PolicyRoute" }, - { "@id": "urn:uma:default:PermissionRegistrationRoute" }, - { "@id": "urn:uma:default:ResourceRegistrationRoute" }, - { "@id": "urn:uma:default:ResourceRegistrationOpsRoute" }, - { "@id": "urn:uma:default:IntrospectionRoute" }, - { "@id": "urn:uma:default:LogRoute" }, - { "@id": "urn:uma:default:VCRoute" }, - { "@id": "urn:uma:default:ContractRoute" } - ], - "defaultHandler": { - "@type": "DefaultRequestHandler" + "@id": "urm:uma:default:RouteHandler", + "@type": "WaterfallHandler", + "handlers": [ + { + "comment": "Handles all JSON and form encoded input/output.", + "@id": "urm:uma:default:JsonFormHttpHandler", + "@type": "JsonFormHttpHandler", + "handler": { + "@id": "urn:uma:default:JsonRoutedHttpRequestHandler", + "@type": "RoutedHttpRequestHandler", + "routes": [ + { "@id": "urn:uma:default:UmaConfigRoute" }, + { "@id": "urn:uma:default:JwksRoute" }, + { "@id": "urn:uma:default:TokenRoute" }, + { "@id": "urn:uma:default:PermissionRegistrationRoute" }, + { "@id": "urn:uma:default:ResourceRegistrationRoute" }, + { "@id": "urn:uma:default:ResourceRegistrationOpsRoute" }, + { "@id": "urn:uma:default:IntrospectionRoute" } + ] + } + }, + { + "comment": "Handles all remaining output. These handlers have to handle input/output parsing themselves. TODO: At some point we want more generic conneg.", + "@id": "urn:uma:default:RawRoutedHttpRequestHandler", + "@type": "RoutedHttpRequestHandler", + "routes": [ + { "@id": "urn:uma:default:ContractRoute" }, + { "@id": "urn:uma:default:LogRoute" }, + { "@id": "urn:uma:default:VCRoute" }, + { "@id": "urn:uma:default:PolicyRoute" }, + { "@id": "urn:uma:default:OnePolicyRoute"} + ] + }, + { + "@type": "StaticThrowHandler", + "error": { "@type": "NotFoundHttpError" } } - } + ] } } }, diff --git a/packages/uma/config/demo.json b/packages/uma/config/demo.json index 5ba92ebd..07ae53a4 100644 --- a/packages/uma/config/demo.json +++ b/packages/uma/config/demo.json @@ -44,7 +44,9 @@ }, "overrideParameters": { "@type": "ContainerUCRulesStorage", - "containerURL": "http://localhost:3000/ruben/settings/policies/" + "containerURL": { + "@id": "urn:uma:variables:policyContainer" + } } } ] diff --git a/packages/uma/config/policies/authorizers/default.json b/packages/uma/config/policies/authorizers/default.json index c6daccc1..1b7a8ff5 100644 --- a/packages/uma/config/policies/authorizers/default.json +++ b/packages/uma/config/policies/authorizers/default.json @@ -54,10 +54,7 @@ "eyePath": { "@id": "urn:uma:variables:eyePath" }, "policies": { "@id": "urn:uma:default:RulesStorage", - "@type": "DirectoryUCRulesStorage", - "directoryPath": { - "@id": "urn:uma:variables:policyDir" - } + "@type": "MemoryUCRulesStorage" } } } diff --git a/packages/uma/config/routes/policies.json b/packages/uma/config/routes/policies.json index bb546dd0..823b8ea3 100644 --- a/packages/uma/config/routes/policies.json +++ b/packages/uma/config/routes/policies.json @@ -7,15 +7,37 @@ "@id": "urn:uma:default:PolicyRoute", "@type": "HttpHandlerRoute", "methods": [ - "GET" + "GET", + "POST", + "OPTIONS" ], "handler": { "@type": "PolicyRequestHandler", "storage": { "@id": "urn:uma:default:RulesStorage" - } + }, + "baseUrl": { "@id": "urn:uma:variables:baseUrl" } }, "path": "/uma/policies" + }, + { + "@id": "urn:uma:default:OnePolicyRoute", + "@type": "HttpHandlerRoute", + "methods": [ + "GET", + "DELETE", + "PATCH", + "PUT", + "OPTIONS" + ], + "handler": { + "@type": "PolicyRequestHandler", + "storage": { + "@id": "urn:uma:default:RulesStorage" + }, + "baseUrl": { "@id": "urn:uma:variables:baseUrl" } + }, + "path": "/uma/policies/{id}" } ] } diff --git a/packages/uma/config/rules/odrl/policy0.ttl b/packages/uma/config/rules/odrl/policy0.ttl index 07b9f138..6d103668 100644 --- a/packages/uma/config/rules/odrl/policy0.ttl +++ b/packages/uma/config/rules/odrl/policy0.ttl @@ -5,7 +5,7 @@ ex:usagePolicy1 a odrl:Agreement . ex:usagePolicy1 odrl:permission ex:permission1 . ex:permission1 a odrl:Permission . ex:permission1 odrl:action odrl:modify . -ex:permission1 odrl:target . +ex:permission1 odrl:target . ex:permission1 odrl:assignee . ex:permission1 odrl:assigner . @@ -13,7 +13,7 @@ ex:usagePolicy1a a odrl:Agreement . ex:usagePolicy1a odrl:permission ex:permission1a . ex:permission1a a odrl:Permission . ex:permission1a odrl:action odrl:create . -ex:permission1a odrl:target . +ex:permission1a odrl:target . ex:permission1a odrl:assignee . ex:permission1a odrl:assigner . @@ -21,7 +21,7 @@ ex:usagePolicy2 a odrl:Agreement . ex:usagePolicy2 odrl:permission ex:permission2a . ex:permission2 a odrl:Permission . ex:permission2 odrl:action odrl:modify . -ex:permission2 odrl:target . +ex:permission2 odrl:target . ex:permission2 odrl:assignee . ex:permission2 odrl:assigner . @@ -29,7 +29,7 @@ ex:usagePolicy2a a odrl:Agreement . ex:usagePolicy2a odrl:permission ex:permission2 . ex:permission2a a odrl:Permission . ex:permission2a odrl:action odrl:create . -ex:permission2a odrl:target . +ex:permission2a odrl:target . ex:permission2a odrl:assignee . ex:permission2a odrl:assigner . @@ -38,6 +38,6 @@ ex:usagePolicy3 a odrl:Agreement . ex:usagePolicy3 odrl:permission ex:permission3 . ex:permission3 a odrl:Permission . ex:permission3 odrl:action odrl:read . -ex:permission3 odrl:target . +ex:permission3 odrl:target . ex:permission3 odrl:assignee . ex:permission3 odrl:assigner . diff --git a/packages/uma/config/rules/policy/policy0.ttl b/packages/uma/config/rules/policy/policy0.ttl index 8a267103..971ed60f 100644 --- a/packages/uma/config/rules/policy/policy0.ttl +++ b/packages/uma/config/rules/policy/policy0.ttl @@ -5,7 +5,7 @@ ex:usagePolicy a odrl:Agreement . ex:usagePolicy odrl:permission ex:permission . ex:permission a odrl:Permission . ex:permission odrl:action odrl:read , odrl:create , odrl:modify . -ex:permission odrl:target , . +ex:permission odrl:target , . ex:permission odrl:assignee . ex:permission odrl:assigner . @@ -13,6 +13,6 @@ ex:usagePolicy2 a odrl:Agreement . ex:usagePolicy2 odrl:permission ex:permission2 . ex:permission2 a odrl:Permission . ex:permission2 odrl:action odrl:create , odrl:modify . -ex:permission2 odrl:target , . +ex:permission2 odrl:target , . ex:permission2 odrl:assignee . ex:permission2 odrl:assigner . diff --git a/packages/uma/config/variables/default.json b/packages/uma/config/variables/default.json index 43b003c3..ed9164dd 100644 --- a/packages/uma/config/variables/default.json +++ b/packages/uma/config/variables/default.json @@ -17,10 +17,20 @@ "@id": "urn:uma:variables:policyDir", "@type": "Variable" }, + { + "comment": "Base IRI to use when parsing policies.", + "@id": "urn:uma:variables:policyBaseIRI", + "@type": "Variable" + }, { "comment": "Path of the local eye reasoner.", "@id": "urn:uma:variables:eyePath", "@type": "Variable" + }, + { + "comment": "URL of container where policies are stored.", + "@id": "urn:uma:variables:policyContainer", + "@type": "Variable" } ] } diff --git a/packages/uma/package.json b/packages/uma/package.json index 59a154c7..45827ba4 100644 --- a/packages/uma/package.json +++ b/packages/uma/package.json @@ -32,7 +32,7 @@ } ], "private": true, - "packageManager": "yarn@4.0.2", + "packageManager": "yarn@4.9.2", "engines": { "node": ">=20.0", "yarn": ">=4.0" @@ -55,34 +55,27 @@ "build": "yarn build:ts && yarn build:components", "build:ts": "yarn run -T tsc", "build:components": "yarn run -T componentsjs-generator -r sai-uma -s src -c dist/components -i .componentsignore --lenient", - "test": "yarn run -T jest --coverage", - "start": "yarn run -T ts-node bin/main.ts", - "start:odrl": "yarn run -T ts-node bin/odrl.ts", - "demo": "yarn run -T ts-node bin/demo.ts" + "start": "node bin/main.js", + "start:odrl": "node bin/odrl.js", + "demo": "node bin/demo.js" }, "dependencies": { "@httpland/authorization-parser": "^1.1.0", "@solid/access-token-verifier": "^1.2.0", "@solid/community-server": "^7.1.7", "@solidlab/ucp": "workspace:^", + "@comunica/query-sparql": "^2.9.0", "@types/n3": "^1.16.4", "componentsjs": "^5.5.1", "get-jwks": "^9.0.1", "http-message-signatures": "^1.0.4", "jose": "^5.2.2", - "koreografeye": "^0.4.8", "logform": "^2.6.0", "n3": "^1.17.2", "odrl-evaluator": "^0.3.0", - "ts-node": "^10.9.2", "uri-template-lite": "^23.4.0", "winston": "^3.11.0" }, - "jest": { - "preset": "ts-jest", - "testEnvironment": "node", - "testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts)$" - }, "lsd:module": "https://linkedsoftwaredependencies.org/bundles/npm/@solidlab/uma", "lsd:components": "dist/components/components.jsonld", "lsd:contexts": { diff --git a/packages/uma/src/dialog/ContractNegotiator.ts b/packages/uma/src/dialog/ContractNegotiator.ts index ab30d720..3bad32f4 100644 --- a/packages/uma/src/dialog/ContractNegotiator.ts +++ b/packages/uma/src/dialog/ContractNegotiator.ts @@ -165,14 +165,21 @@ export class ContractNegotiator extends BaseNegotiator { // todo: fix instantiated from url // contract['http://www.w3.org/ns/prov#wasDerivedFrom'] = [ 'urn:ucp:be-gov:policy:d81b8118-af99-4ab3-b2a7-63f8477b6386 '] // TODO: test-private error: this container does not exist and unauth does not have append perms - const instantiatedPolicyContainer = 'http://localhost:3000/ruben/settings/policies/instantiated/'; - const policyCreationResponse = await fetch(instantiatedPolicyContainer, { - method: 'POST', - headers: { 'content-type': 'application/ld+json' }, - body: JSON.stringify(contract, null, 2) - }); - - if (policyCreationResponse.status !== 201) { this.logger.warn('Adding a policy did not succeed...') } + try { + const instantiatedPolicyContainer = 'http://localhost:3000/ruben/settings/policies/instantiated/'; + const policyCreationResponse = await fetch(instantiatedPolicyContainer, { + method: 'POST', + headers: { 'content-type': 'application/ld+json' }, + body: JSON.stringify(contract, null, 2) + }); + + if (policyCreationResponse.status !== 201) { + this.logger.warn(`Adding the contract to the instantiated policies failed: ${ + policyCreationResponse.status} - ${await policyCreationResponse.text()}`); + } + } catch (error: unknown) { + this.logger.warn(`Adding the contract to the instantiated policies failed: ${createErrorMessage(error)}`); + } // TODO:: dynamic contract link to stored signed contract. // If needed we can always embed here directly into the return JSON diff --git a/packages/uma/src/index.ts b/packages/uma/src/index.ts index df3967a9..183a013c 100644 --- a/packages/uma/src/index.ts +++ b/packages/uma/src/index.ts @@ -74,5 +74,10 @@ export * from './util/ConvertUtil'; export * from './util/HttpMessageSignatures'; export * from './util/Result'; export * from './util/ReType'; -export * from './util/routeSpecific/policies/GetPolicies'; export * from './util/routeSpecific/policies/PolicyUtil'; +export * from './util/routeSpecific/policies/CreatePolicies'; +export * from './util/routeSpecific/policies/GetPolicies'; +export * from './util/routeSpecific/policies/EditPolicies'; +export * from './util/routeSpecific/policies/RewritePolicies'; +export * from './util/routeSpecific/policies/DeletePolicies'; +export * from './util/routeSpecific/policies/PolicyOptions'; diff --git a/packages/uma/src/logging/OperationLogger.ts b/packages/uma/src/logging/OperationLogger.ts index 12be796a..51f6cb59 100644 --- a/packages/uma/src/logging/OperationLogger.ts +++ b/packages/uma/src/logging/OperationLogger.ts @@ -1,7 +1,6 @@ import { Store, Triple, DataFactory, Quad_Graph, Quad } from 'n3' - -class OperationLogger { +export class OperationLogger { store: Store = new Store(); @@ -11,7 +10,7 @@ class OperationLogger { * @returns {Quad_Graph} name of the graph in which the triples are stored */ addLogEntry(triples: Triple[], graphName?: string): Quad_Graph { - let graphTerm: Quad_Graph = graphName + let graphTerm: Quad_Graph = graphName ? DataFactory.namedNode(graphName) : DataFactory.blankNode() this.store.addQuads( @@ -44,4 +43,4 @@ const logger = new OperationLogger(); export function getOperationLogger() { return logger; -} \ No newline at end of file +} diff --git a/packages/uma/src/policies/contracts/ContractManager.ts b/packages/uma/src/policies/contracts/ContractManager.ts index e9f733ac..f05e3d78 100644 --- a/packages/uma/src/policies/contracts/ContractManager.ts +++ b/packages/uma/src/policies/contracts/ContractManager.ts @@ -25,8 +25,6 @@ export class ContractManager { } createContract(perms: Permission[]): ODRLContract { - console.log('Creating Contract', JSON.stringify(perms, null, 2)) - // todo: un-mock this!!! type Pair = { action: string, target: string }; const permissionPairs: Pair[] = perms.flatMap( diff --git a/packages/uma/src/routes/Policy.ts b/packages/uma/src/routes/Policy.ts index 1bfd7ac1..3e70353e 100644 --- a/packages/uma/src/routes/Policy.ts +++ b/packages/uma/src/routes/Policy.ts @@ -1,7 +1,12 @@ import { BadRequestHttpError, getLoggerFor, MethodNotAllowedHttpError } from "@solid/community-server"; import { UCRulesStorage } from "@solidlab/ucp"; import { HttpHandlerContext, HttpHandlerResponse, HttpHandler, HttpHandlerRequest } from "../util/http/models/HttpHandler"; -import { getPolicies as getPolicies } from "../util/routeSpecific/policies/GetPolicies"; +import { getPolicies } from "../util/routeSpecific/policies/GetPolicies"; +import { addPolicies } from "../util/routeSpecific/policies/CreatePolicies"; +import { deletePolicy } from "../util/routeSpecific/policies/DeletePolicies"; +import { editPolicy } from "../util/routeSpecific/policies/EditPolicies"; +import { rewritePolicy } from "../util/routeSpecific/policies/RewritePolicies"; +import { policyOptions } from "../util/routeSpecific/policies/PolicyOptions"; /** * Endpoint to handle policies, this implementation gives all policies that have the @@ -12,7 +17,8 @@ export class PolicyRequestHandler extends HttpHandler { protected readonly logger = getLoggerFor(this); constructor( - private readonly storage: UCRulesStorage + protected readonly storage: UCRulesStorage, + protected readonly baseUrl: string, ) { super(); } @@ -22,11 +28,11 @@ export class PolicyRequestHandler extends HttpHandler { * (To be altered with actual Solid-OIDC) * * @param request the request with the client 'id' as body - * @returns the client id + * @returns the client webID */ protected getCredentials(request: HttpHandlerRequest): string { const header = request.headers['authorization']; - if (typeof header !== 'string') { + if (typeof header !== 'string' && request.method !== "OPTIONS") { throw new BadRequestHttpError('Missing Authorization header'); } return header; @@ -43,8 +49,12 @@ export class PolicyRequestHandler extends HttpHandler { const store = await this.storage.getStore(); switch (request.method) { - case 'GET': return getPolicies(request, store, client); - // TODO: add other endpoints + case 'GET': return getPolicies(request, store, client, this.baseUrl); + case 'POST': return addPolicies(request, store, this.storage, client); + case 'DELETE': return deletePolicy(request, store, this.storage, client, this.baseUrl); + case 'PATCH': return editPolicy(request, store, this.storage, client, this.baseUrl); + case 'PUT': return rewritePolicy(request, store, this.storage, client, this.baseUrl); + case 'OPTIONS': return policyOptions(request, this.baseUrl); default: throw new MethodNotAllowedHttpError(); } } diff --git a/packages/uma/src/util/http/server/RoutedHttpRequestHandler.ts b/packages/uma/src/util/http/server/RoutedHttpRequestHandler.ts index 0c627b37..4840c687 100644 --- a/packages/uma/src/util/http/server/RoutedHttpRequestHandler.ts +++ b/packages/uma/src/util/http/server/RoutedHttpRequestHandler.ts @@ -1,8 +1,15 @@ -import { getLoggerFor } from '@solid/community-server'; +import { + getLoggerFor, + InternalServerError, + MethodNotAllowedHttpError, + NotImplementedHttpError +} from '@solid/community-server'; import Template from 'uri-template-lite'; import { HttpHandler, HttpHandlerContext, HttpHandlerResponse } from '../models/HttpHandler'; import { HttpHandlerRoute } from '../models/HttpHandlerRoute'; +type RouteMatch = { parameters: Record, route: HttpHandlerRoute }; + /** * A {@link HttpHandler} handling requests based on routes in a given list of {@link HttpHandlerRoute}s. * Route paths can contain variables as described in RFC 6570. @@ -18,16 +25,17 @@ import { HttpHandlerRoute } from '../models/HttpHandlerRoute'; * E.g., `http://example.com/foo/bar` will match the route template `/bar`. */ export class RoutedHttpRequestHandler extends HttpHandler { + protected readonly logger = getLoggerFor(this); protected readonly routeMap: Map; - protected readonly logger = getLoggerFor(this); + protected readonly handledRequests: WeakMap; + /** * Creates a RoutedHttpRequestHandler, super calls the HttpHandler class and expects a list of HttpHandlerControllers. */ constructor( routes: HttpHandlerRoute[], - protected readonly defaultHandler?: HttpHandler, onlyMatchTail = false, ) { super(); @@ -37,9 +45,10 @@ export class RoutedHttpRequestHandler extends HttpHandler { // Add a catchall variable to the front if only the URL tail needs to be matched. this.routeMap.set(new Template(onlyMatchTail ? `{_prefix}${route.path}` : route.path), route); } + this.handledRequests = new WeakMap(); } - async handle(context: HttpHandlerContext): Promise { + public async canHandle(context: HttpHandlerContext): Promise { const request = context.request; const path = request.url.pathname; @@ -55,26 +64,24 @@ export class RoutedHttpRequestHandler extends HttpHandler { } if (!match) { - if (this.defaultHandler) { - this.logger.info(`No matching route found, calling default handler. ${path}`); - return this.defaultHandler.handleSafe(context); - } else { - this.logger.error(`No matching route found. ${path}`); - return { body: '', headers: {}, status: 404 }; - } + throw new NotImplementedHttpError(); } this.logger.debug(`Route matched: ${JSON.stringify({ path, parameters: match.parameters })}`); if (match.route.methods && !match.route.methods.includes(request.method)) { this.logger.info(`Operation not supported. Supported operations: ${ match.route.methods }`); - return { - status: 405, - headers: { 'allow': match.route.methods.join(', ') }, - body: '', - }; + throw new MethodNotAllowedHttpError([ request.method ]); + } + this.handledRequests.set(context, match); + } + + public async handle(context: HttpHandlerContext): Promise { + const match = this.handledRequests.get(context); + if (!match) { + throw new InternalServerError('Calling handle without successful canHandle'); } - request.parameters = { ...request.parameters, ...match.parameters }; + context.request.parameters = { ...context.request.parameters, ...match.parameters }; return match.route.handler.handleSafe(context); } diff --git a/packages/uma/src/util/routeSpecific/policies/CreatePolicies.ts b/packages/uma/src/util/routeSpecific/policies/CreatePolicies.ts index ea641885..dad50bbf 100644 --- a/packages/uma/src/util/routeSpecific/policies/CreatePolicies.ts +++ b/packages/uma/src/util/routeSpecific/policies/CreatePolicies.ts @@ -1 +1,90 @@ -//TODO \ No newline at end of file +import { Quad, Store } from "n3"; +import { HttpHandlerRequest, HttpHandlerResponse } from "../../http/models/HttpHandler"; +import { odrlAssigner, parseBodyToStore, relations } from "./PolicyUtil"; +import { BadRequestHttpError, InternalServerError } from "@solid/community-server"; +import { UCRulesStorage } from "@solidlab/ucp"; +import { getPolicyInfo, OnePolicy } from "./GetPolicies"; + +export function sanitizeRule(parsedPolicy: Store, clientId: string, strict: boolean = false): Set { + // Check that every rule defined by the policy has exactly one assigner, every rule is unique and every assigner is the client + const definedRules = new Set(); + const policyIds: Set = new Set(); + for (const relation of relations) { + + // Every rule definition of every policy + const policyRelationRules = parsedPolicy.getQuads(null, relation, null, null); + + for (const quad of policyRelationRules) { + const rule = quad.object; + policyIds.add(quad.subject.id); + // The policy should not define multiple rules with the same ID, this check also + // restricts the same rule to be defined twice (even if relation is equal) + if (definedRules.has(rule)) throw new BadRequestHttpError(`Rule ambiguity in rule ${rule.id}`); + definedRules.add(rule); + + // The rule should have exactly one assigner, and it should be the client + const ruleAssignerX = parsedPolicy.getQuads(rule, odrlAssigner, null, null); + + if (ruleAssignerX.length !== 1) throw new BadRequestHttpError(`Rule ${rule.id} should have exactly one assigner`); + if (ruleAssignerX[0].object.id !== clientId) throw new BadRequestHttpError(`Rule ${rule.id} needs an authorized assigner`); + } + } + + // Check if assigner of the policy has access to the target + // Check if there is at least one permission/prohibition/duty + // Check if every rule has a target + // ... + + // Return the policies in the store for further use + return policyIds; +} + +export async function addPolicies(request: HttpHandlerRequest, store: Store, storage: UCRulesStorage, clientId: string): Promise> { + + // 1. Parse the requested policy + const parsedPolicy = await parseBodyToStore(request); + + // 2. Sanitization checks (error is thrown when checks fail) + const newPolicies = sanitizeRule(parsedPolicy, clientId); + + // Extra checks + const totalQuads: Quad[] = []; + if ([...newPolicies].some(id => { + const existingInfo = getPolicyInfo(id, store, clientId); + // None of the policies in the request should already exist + if ([...existingInfo.policyDefinitions, ...existingInfo.ownedPolicyRules, ...existingInfo.otherPolicyRules, + ...existingInfo.ownedRules, ...existingInfo.otherRules].length > 0) { + return true; + } + + const { policyDefinitions, ownedPolicyRules, otherPolicyRules, ownedRules, otherRules } = getPolicyInfo(id, parsedPolicy, clientId); + + // The policies may not declare rules out of scope + if (otherRules.length !== 0 || otherPolicyRules.length !== 0) { + return true; + } + + totalQuads.push(...policyDefinitions, ...ownedPolicyRules, ...ownedRules); + })) + throw new BadRequestHttpError("POST not allowed: improper request body"); + + // Extra check: No unrelated rules may be inserted + // The policies may not declare any quads unrelated to its own policy + const newQuads = parsedPolicy.getQuads(null, null, null, null); + if (newQuads.length - totalQuads.length !== 0) + throw new BadRequestHttpError("POST not allowed: inserted unrelated quads"); + + + // 3 Add the policy to the rule storage + try { + await storage.addRule(parsedPolicy); + } catch (error) { + throw new InternalServerError("Failed to add policy"); + } + + + return { + status: 201, + headers: { 'access-control-allow-origin': 'http://localhost:5173' } + } +} \ No newline at end of file diff --git a/packages/uma/src/util/routeSpecific/policies/DeletePolicies.ts b/packages/uma/src/util/routeSpecific/policies/DeletePolicies.ts new file mode 100644 index 00000000..7db61ef2 --- /dev/null +++ b/packages/uma/src/util/routeSpecific/policies/DeletePolicies.ts @@ -0,0 +1,67 @@ +import { UCRulesStorage } from "@solidlab/ucp"; +import { HttpHandlerRequest, HttpHandlerResponse } from "../../http/models/HttpHandler"; +import { checkBaseURL, namedNode, odrlAssigner, quadsToText, relations, retrieveID } from "./PolicyUtil"; +import { Quad, Store } from "n3"; +import { InternalServerError } from "@solid/community-server"; + +export async function deletePolicy(request: HttpHandlerRequest, store: Store, storage: UCRulesStorage, clientId: string, baseUrl: string): Promise> { + + const policyId = decodeURIComponent(retrieveID(checkBaseURL(request, baseUrl))); + return deleteOnePolicy(policyId, store, storage, clientId) +} + + +/** + * To delete a policy, send a DELETE request to `/uma/policies/` with the URL encoded ID of the policy. The DELETE works like this: + * 1. Find the rules defined in the policy + * 2. Filter the rules that are assigned by the client, and delete them + * 3. Find out if there are rules not assigned by the client + * if there are other rules, we cannot delete the policy information as well + * if there are no other rules, we can delete the entire policy + * + * As read in /docs/policy-managament.md + */ +export async function deleteOnePolicy(policyId: string, store: Store, storage: UCRulesStorage, clientId: string): Promise> { + + // 1. Collect the IDs of the rules we want to delete + const policyRules: Quad[] = relations.flatMap(relation => + store.getQuads(namedNode(policyId), relation, null, null) + ) + + // Keep track of IDs that are (not) within the clients reach + const otherRules: string[] = []; + const ownedRules: string[] = []; + policyRules.forEach(quad => { + if (store.getQuads(quad.object, odrlAssigner, namedNode(clientId), null).length === 1) + ownedRules.push(quad.object.id); + else + otherRules.push(quad.object.id); + }); + + // Nothing to delete + if (ownedRules.length === 0) { + return { + status: 204, + }; + } + + // DELETE the quads + try { + if (otherRules.length === 0) { + // If the policy contains only rules assigned by the client, we can remove the entire policy + await storage.deleteRule(policyId); + } else { + // Otherwise, we only remove the rules within our reach + await Promise.all(ownedRules.map(id => storage.deleteRuleFromPolicy(id, policyId))); + } + + } catch (error) { + throw new InternalServerError(`Failed to delete rules: ${error}`); + } + + // Delete succesful + return { + status: 200, + headers: { 'access-control-allow-origin': 'http://localhost:5173' } + } +} \ No newline at end of file diff --git a/packages/uma/src/util/routeSpecific/policies/EditPolicies.ts b/packages/uma/src/util/routeSpecific/policies/EditPolicies.ts index e69de29b..2a72953a 100644 --- a/packages/uma/src/util/routeSpecific/policies/EditPolicies.ts +++ b/packages/uma/src/util/routeSpecific/policies/EditPolicies.ts @@ -0,0 +1,72 @@ +import { Store, Writer } from "n3"; +import { HttpHandlerRequest, HttpHandlerResponse } from "../../http/models/HttpHandler"; +import { UCRulesStorage } from "@solidlab/ucp"; +import { checkBaseURL, parseBufferToString, quadsToText, retrieveID } from "./PolicyUtil"; +import { QueryEngine } from '@comunica/query-sparql'; +import { BadRequestHttpError, InternalServerError } from "@solid/community-server"; +import { getPolicyInfo } from "./GetPolicies"; +import { sanitizeRule } from "./CreatePolicies"; + +export async function editPolicy(request: HttpHandlerRequest, store: Store, storage: UCRulesStorage, clientId: string, baseUrl: string): Promise> { + // Retrieve Policy ID + const policyId = decodeURIComponent(retrieveID(checkBaseURL(request, baseUrl))); + + // 1. Retrieve the existing policy info + const { policyDefinitions, ownedPolicyRules, otherPolicyRules, ownedRules, otherRules } = getPolicyInfo(policyId, store, clientId); + + // Cannot update a nonexistent policy + if (policyDefinitions.length === 0) + throw new BadRequestHttpError("Update not allowed: You cannot update a nonexistent policy"); + + // Implementation Choice: You cannot PATCH a policy that you are not affiliated with + if (ownedRules.length === 0) + throw new BadRequestHttpError("Update not allowed: You cannot update policies that you are not affiliated with"); + + // 2. Retrieve the Policy Body + const contentType = request.headers['content-type']; + if (!/(?:application\/sparql-update)$/i.test(contentType)) { + throw new BadRequestHttpError(`Content-Type ${contentType} is not supported.`); + } + const query = parseBufferToString(request.body); + + + // 3. Execute the query on the part of the policy that lays within reach + const policyStore = new Store([...policyDefinitions, ...ownedPolicyRules, ...ownedRules]); + const initialQuads = policyStore.getQuads(null, null, null, null); + try { + await new QueryEngine().queryVoid(query, { sources: [policyStore] }); + } catch (error) { + throw new BadRequestHttpError("Query could not be executed:", error); + } + + // Sanitization + sanitizeRule(policyStore, clientId); + + // 3.1 Check that the other rules are unchanged + const initialState = { policyDefinitions, ownedPolicyRules, otherPolicyRules, ownedRules, otherRules }; + const newState = getPolicyInfo(policyId, policyStore, clientId); + + if (newState.otherRules.length !== 0 || newState.otherPolicyRules.length !== 0) + throw new BadRequestHttpError("Update not allowed: attempted to modify rules not owned by client"); + + // 3.2 Check that only Policy/Rule changing quads are introduced and removed + // The only modifications we allow are policy definitions, policy rules that define owned rules and owned rules themselves + const newQuads = policyStore.getQuads(null, null, null, null); + if (newQuads.length - newState.ownedRules.length - newState.ownedPolicyRules.length - newState.policyDefinitions.length !== 0) + throw new BadRequestHttpError("Update not allowed: this query changes quads that have nothing to do with the policy/rules you own"); + // 4 Modify the storage to the updated version + try { + // Since no update function is available, we need to remove the old one and set the updated one + await storage.deleteRule(policyId); + + // Add the other quads back into the policy + policyStore.addQuads([...otherPolicyRules, ...otherRules]); + await storage.addRule(policyStore); + } catch (error) { + throw new InternalServerError("Something went wrong while editting the policy:", error); + } + + // 7. Print information within reach + const finalState = getPolicyInfo(policyId, policyStore, clientId); + return quadsToText([...finalState.policyDefinitions, ...finalState.ownedPolicyRules, ...finalState.ownedRules]); +} \ No newline at end of file diff --git a/packages/uma/src/util/routeSpecific/policies/GetPolicies.ts b/packages/uma/src/util/routeSpecific/policies/GetPolicies.ts index 15877733..4c52f7e0 100644 --- a/packages/uma/src/util/routeSpecific/policies/GetPolicies.ts +++ b/packages/uma/src/util/routeSpecific/policies/GetPolicies.ts @@ -1,43 +1,125 @@ import { HttpHandlerRequest, HttpHandlerResponse } from "../../http/models/HttpHandler"; -import { Quad, Store, Writer } from "n3"; -import { odrlAssigner, relations, namedNode } from "./PolicyUtil"; -import { MethodNotAllowedHttpError } from "@solid/community-server"; +import { Quad, Store } from "n3"; +import { odrlAssigner, relations, namedNode, quadsToText, checkBaseURL, retrieveID } from "./PolicyUtil"; + /** * Handling of the GET /uma/policies endpoint * * @param request will give all policies when no is fixed in the URL, otherwise it will give the required policy (if allowed) */ -export async function getPolicies(request: HttpHandlerRequest, store: Store, clientId: string): Promise> { - if (request.url.pathname === '/uma/policies') +export async function getPolicies(request: HttpHandlerRequest, store: Store, clientId: string, baseUrl: string): Promise> { + // This shouldn't happen + const pathname = checkBaseURL(request, baseUrl); + + // If no other argument(s), get all + if (pathname === '/policies') return getAllPolicies(store, clientId); - // If asked for a policy, validate the policy ID - const args = request.url.pathname.split('/'); - if (args.length === 4 && isPolicy(args[-1])) - return getOnePolicy(args[-1], store, clientId); + // If asked for a policy, get one + const id = retrieveID(pathname); + return getOnePolicy(id, store, clientId); - throw new MethodNotAllowedHttpError(); } -/** - * Function to determine the validity of the of the GET /uma/policies/ endpoint (not implemented yet) - * - * @param policyId - * @returns the validity of policyId - */ -function isPolicy(policyId: string): boolean { - // TODO - return true; +// Interface to represent a policy based on a client +export interface OnePolicy { + clientId: string; + policyId: string; + + // Policy quads are split in three parts, to not leak information out of the clients reach + // The definitions are every policy quad that do not declare a rule + policyDefinitions: Quad[]; + ownedPolicyRules: Quad[]; + otherPolicyRules: Quad[]; + ownedRules: Quad[]; + otherRules: Quad[]; } +// Functional implementation to get one policy +export function getPolicyInfo(policyId: string, store: Store, clientId: string): OnePolicy { + + // 1. Find the rules that this policy defines + const policyRules: Quad[] = relations.flatMap(relation => + store.getQuads(namedNode(policyId), relation, null, null) + ); + + // 2. Collect the policy quads unrelated to rules + const policyDefinitions = store.getQuads(namedNode(policyId), null, null, null).filter(quad => + !policyRules.some(rule => quad.equals(rule)) + ); + + // 3. Separate the rules owned by the client from the others + const otherRules: Quad[] = []; + const ownedRules: Quad[] = []; + const ownedPolicyRules: Quad[] = []; + const otherPolicyRules: Quad[] = []; + policyRules.forEach(quad => { + if (store.getQuads(quad.object, odrlAssigner, namedNode(clientId), null).length === 1) { + // TODO: This is the step to be replaced with the recursive variant + store.getQuads(quad.object, null, null, null).forEach( + quad => ownedRules.push(quad) + ); + ownedPolicyRules.push(quad); + } else { + // TODO: Once again, this is to be replaced with the recursive variant + store.getQuads(quad.object, null, null, null).forEach( + quad => otherRules.push(quad) + ); + otherPolicyRules.push(quad); + } + + }); + + // 4. Return the detailed object + return { + policyId: policyId, + clientId: clientId, + policyDefinitions: policyDefinitions, + ownedPolicyRules: ownedPolicyRules, + otherPolicyRules: otherPolicyRules, + ownedRules: ownedRules, + otherRules: otherRules + }; + +} + + /** * Function to implement the GET /uma/policies/ endpoint, it retrieves all information about a certain - * policy if available. Yet to be implemented. + * policy if available. + * + * @param policyId the policy id, which is ENCODED + * @param store + * @param clientId the clients webID + * @returns aynchronous HTTP response: */ -function getOnePolicy(policyId: string, store: Store, clientId: string): Promise> { - // TODO - return getAllPolicies(store, clientId); +async function getOnePolicy(policyId: string, store: Store, clientId: string): Promise> { + policyId = decodeURIComponent(policyId); + + const { policyDefinitions, ownedPolicyRules, ownedRules } = getPolicyInfo(policyId, store, clientId); + + if (ownedRules.length === 0) + return { + status: 204, + headers: { + 'content-type': 'text/turtle', 'access-control-allow-origin': 'http://localhost:5173' + }, + body: '', + } + + return quadsToText([...policyDefinitions, ...ownedPolicyRules, ...ownedRules]); +} + +// Fill the policyDetails store with +// 1. The policy definitions +// 2. The owned rules declared in the policy +// TODO: This is a depth 1 algorithm that has to be replaced +export function getFilteredPolicyQuads(dataStore: Store, policyDetails: Store, policyId: string, clientId: string) { + dataStore.getQuads(namedNode(policyId), null, null, null).forEach(quad => { + if (!(relations.map(r => r.value as string).includes(quad.predicate.id)) || dataStore.getQuads(quad.object, odrlAssigner, namedNode(clientId), null).length > 0) + policyDetails.addQuad(quad); + }); } @@ -48,10 +130,11 @@ function getOnePolicy(policyId: string, store: Store, clientId: string): Promise * @param param0 a request with the clients webID as authorization header. * @returns all policy information (depth 1) relevant to the client */ -function getAllPolicies(store: Store, clientId: string): Promise> { +async function getAllPolicies(store: Store, clientId: string): Promise> { - // Keep track of all the matching policies - const policyDetails: Set = new Set(); + // Keep track of all the matching policies (use store because javascript does not know how sets work) + const policyDetails: Store = new Store(); + const memory: Set = new Set(); for (const relation of relations) { // Collect every quad that matches with the relation (one of Permission, Prohibition or Duty) @@ -66,29 +149,15 @@ function getAllPolicies(store: Store, clientId: string): Promise 0) { - // Because an ODRL policy may only have one assigner, we can now add all policy and rule information - store.getQuads(policy, null, null, null).forEach(quad => policyDetails.add(quad)); - store.getQuads(rule, null, null, null).forEach(quad => policyDetails.add(quad)); + // Because an ODRL policy may only have one assigner, we can now add all policy and rule information, except the policy quads that define other clients rules + // Note that this is the only part of the function to be replaced with the recursive variant + if (!memory.has(policy.id)) { + getFilteredPolicyQuads(store, policyDetails, policy.id, clientId); + memory.add(policy.id); + } + store.getQuads(rule, null, null, null).forEach(quad => policyDetails.addQuad(quad)); } } } - - - // Serialize as Turtle - const writer = new Writer({ format: 'Turtle' }); - writer.addQuads(Array.from(policyDetails)); - - return new Promise>((resolve, reject) => { - writer.end((error, result) => { - if (error) { - reject(error); - } else { - resolve({ - status: 200, - headers: { 'content-type': 'text/turtle' }, - body: result - }); - } - }); - }); + return quadsToText(policyDetails.getQuads(null, null, null, null)); } \ No newline at end of file diff --git a/packages/uma/src/util/routeSpecific/policies/PolicyOptions.ts b/packages/uma/src/util/routeSpecific/policies/PolicyOptions.ts new file mode 100644 index 00000000..b2b47b35 --- /dev/null +++ b/packages/uma/src/util/routeSpecific/policies/PolicyOptions.ts @@ -0,0 +1,29 @@ +import { HttpHandlerRequest } from "../../http/models/HttpHandler"; +import { checkBaseURL, retrieveID } from "./PolicyUtil"; + +export function policyOptions(request: HttpHandlerRequest, baseUrl: string) { + try { + retrieveID(checkBaseURL(request, baseUrl)) + return { + status: 204, + headers: { + // this is only for the url with + 'Access-Control-Allow-Origin': 'http://localhost:5173', + 'Access-Control-Allow-Methods': 'GET, PATCH, PUT, DELETE, OPTIONS', + 'Access-Control-Allow-Headers': 'Authorization, Content-Type', + } + } + + } catch (error) { + return { + status: 204, + headers: { + // this is only for the url without + 'Access-Control-Allow-Origin': 'http://localhost:5173', + 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS', + 'Access-Control-Allow-Headers': 'Authorization, Content-Type', + } + } + + } +} \ No newline at end of file diff --git a/packages/uma/src/util/routeSpecific/policies/PolicyUtil.ts b/packages/uma/src/util/routeSpecific/policies/PolicyUtil.ts index 366fb543..cc433695 100644 --- a/packages/uma/src/util/routeSpecific/policies/PolicyUtil.ts +++ b/packages/uma/src/util/routeSpecific/policies/PolicyUtil.ts @@ -1,5 +1,8 @@ import { ODRL } from "@solidlab/ucp"; -import { DataFactory } from "n3"; +import { DataFactory, Quad, Store, Writer } from "n3"; +import { HttpHandlerRequest, HttpHandlerResponse } from "../../http/models/HttpHandler"; +import { BadRequestHttpError, MethodNotAllowedHttpError } from "@solid/community-server"; +import { parseStringAsN3Store } from "koreografeye"; // relevant ODRL implementations export const odrlAssigner = ODRL.terms.assigner; @@ -11,3 +14,79 @@ export const relations = [ export const { namedNode } = DataFactory; +export interface PolicyBody { + policy: string; +} + +/** + * Function to test if the baseUrl is a prefix of the full URL. It returns the part after the baseUrl + * + * @param request + * @param baseUrl + * @returns the part after the baseUrl + */ +export const checkBaseURL = (request: HttpHandlerRequest, baseUrl: string) => { + if (request.url.href.slice(0, baseUrl.length) !== baseUrl) throw new MethodNotAllowedHttpError(); + return request.url.href.slice(baseUrl.length); +} + +/** + * Function to extract the ID for endpoints with URL baseUrl/policies/ + * + * @param pathname the part of the URL after the baseUrl + * @returns the ID + */ +export const retrieveID = (pathname: string): string => { + const args = pathname.split('/'); + if (args.length !== 3 || args[1] !== 'policies') throw new MethodNotAllowedHttpError(); + return args[2]; +} + +export async function quadsToText(quads: Quad[]): Promise> { + // Serialize as Turtle + const writer = new Writer({ format: 'Turtle' }); + writer.addQuads(quads); + + return new Promise>((resolve, reject) => { + writer.end((error, result) => { + if (error) { + reject(error); + } else { + resolve({ + status: 200, + headers: { 'content-type': 'text/turtle', 'access-control-allow-origin': 'http://localhost:5173' }, + body: result + }); + } + }); + }); +} + +export function parseBufferToString(body: any): string { + let requestedPolicy; + if (Buffer.isBuffer(body)) { + requestedPolicy = body.toString('utf-8'); + } else { + throw new BadRequestHttpError("Expected Buffer body"); + } + return requestedPolicy; +} + +export async function parseBodyToStore(request: HttpHandlerRequest): Promise { + // Regex check for content type + const contentType = request.headers['content-type']; + if (!/(?:n3|trig|turtle|nquads?|ntriples?)$/i.test(contentType)) { + throw new BadRequestHttpError(`Content-Type ${contentType} is not supported.`); + } + + // Try to parse the body + const requestedPolicy = parseBufferToString(request.body); + + let parsedPolicy: Store; + try { + parsedPolicy = await parseStringAsN3Store(requestedPolicy, { format: contentType }); + } catch (error) { + throw new BadRequestHttpError(`Policy string can not be parsed: ${error}`) + } + return parsedPolicy +} \ No newline at end of file diff --git a/packages/uma/src/util/routeSpecific/policies/rewritePolicies.ts b/packages/uma/src/util/routeSpecific/policies/rewritePolicies.ts new file mode 100644 index 00000000..e2d08495 --- /dev/null +++ b/packages/uma/src/util/routeSpecific/policies/rewritePolicies.ts @@ -0,0 +1,65 @@ +import { UCRulesStorage } from "@solidlab/ucp"; +import { HttpHandlerRequest, HttpHandlerResponse } from "../../http/models/HttpHandler"; +import { BadRequestHttpError, InternalServerError, NotFoundHttpError } from "@solid/community-server"; +import { checkBaseURL, parseBodyToStore, quadsToText, relations, retrieveID } from "./PolicyUtil"; +import { Quad, Store } from "n3"; +import { sanitizeRule } from "./CreatePolicies"; +import { deleteOnePolicy } from "./DeletePolicies"; +import { getPolicyInfo } from "./GetPolicies"; + +export async function rewritePolicy(request: HttpHandlerRequest, store: Store, storage: UCRulesStorage, clientId: string, baseUrl: string): Promise> { + // Retrieve Policy ID + const policyId = decodeURIComponent(retrieveID(checkBaseURL(request, baseUrl))); + + // 1: Get all reachable policy information + const policyInfo = getPolicyInfo(policyId, store, clientId); + if (policyInfo.policyDefinitions.length === 0) + throw new NotFoundHttpError("Patch not allowed: policy does not exist"); + + + // 2. Parse the requested policy, perform checks + const parsedPolicy = await parseBodyToStore(request); + + // Sanitization checks (error is thrown when checks fail) + sanitizeRule(parsedPolicy, clientId); + + // Extra checks: this newly defined policy should not define other policies + if (relations.some(relation => parsedPolicy.getQuads(null, relation, null, null).some(quad => quad.subject.id !== policyId))) + throw new BadRequestHttpError("PUT not allowed: the request went out of scope"); + + // Extra checks: new policy should not contain out of scope rules + const newState = getPolicyInfo(policyId, parsedPolicy, clientId); + if (newState.otherRules.length !== 0 || newState.otherPolicyRules.length !== 0) + throw new BadRequestHttpError("PUT not allowed: attempted to modify rules not owned by client"); + + // Extra checks: only Policy/Rule changing quads are introduced and removed + // The only modifications we allow are policy definitions, policy rules that define owned rules and owned rules themselves + const newQuads = parsedPolicy.getQuads(null, null, null, null); + if (newQuads.length - newState.ownedRules.length - newState.ownedPolicyRules.length - newState.policyDefinitions.length !== 0) + throw new BadRequestHttpError("PUT not allowed: this query introduces quads that have nothing to do with the policy/rules you own"); + + + // 3. Delete the old policy information and keep track of the old ones for possible rollback + const oldQuads: Quad[] = [...policyInfo.policyDefinitions, ...policyInfo.ownedPolicyRules, ...policyInfo.otherPolicyRules, ...policyInfo.ownedRules, ...policyInfo.otherRules]; + + await deleteOnePolicy(policyId, store, storage, clientId); + + try { + // 4. Add the new policy information + await storage.addRule(parsedPolicy); + } catch (error) { + // If addition fails, try to restore the old quads + try { + await storage.addRule(new Store(oldQuads)); + } catch (error) { + // The restored quads could also not be added, the patch failed and the old policy (whithin your reach) is deleted + throw new InternalServerError("Deleted, but not rewritten\n", error); + } + // The restored quads have been added, the patch failed and nothing changed + throw new InternalServerError("Failed to PATCH policy\n", error); + } + + // Delete only what is in your reach + const { policyDefinitions, ownedPolicyRules, ownedRules } = getPolicyInfo(policyId, parsedPolicy, clientId); + return quadsToText([...policyDefinitions, ...ownedPolicyRules, ...ownedRules]); +} \ No newline at end of file diff --git a/scripts/demo-uma-policy.ts b/scripts/demo-uma-policy.ts new file mode 100644 index 00000000..f00c6adf --- /dev/null +++ b/scripts/demo-uma-policy.ts @@ -0,0 +1,74 @@ +import { UserManagedAccessFetcher } from "./util/UMA-client"; +import * as readline from 'readline'; + +const claim_token_format = 'urn:solidlab:uma:claims:formats:webid'; + +const testCode = (code: number, shouldBe: number = 2, trunc: boolean = true): boolean => { + return (trunc ? Math.trunc(code / 100) : code) === shouldBe; +}; + +async function traverseFile(text: string, claim_token: string, resource: string) { + const fetcher = new UserManagedAccessFetcher({ + token: claim_token, + token_format: claim_token_format + }); + + console.log(`\nTest creation/modification rights with RPT`); + const response = await fetcher.fetch(resource, { + method: "PUT", + body: text + }); + + if (testCode(response.status)) { + console.log(`Document created. Server responded with status code ${response.status}`); + } else { + console.log(`Access denied. Creation responded with status code ${response.status}`); + } + + console.log(`\nTesting reading rights with RPT`); + const readingResponse = await fetcher.fetch(resource); + + if (testCode(readingResponse.status)) { + const contents = await readingResponse.text(); + console.log(`Reading successful (status ${readingResponse.status}). Contents:\n${contents}\n`); + } else { + console.log(`Access denied. Insufficient reading rights (status ${readingResponse.status})`); + } +} + +async function main() { + let state: 'NO' | 'ResourceSet' | 'AssigneeSet' = 'NO'; + let resourceId = ""; + let assigneeId = ""; + + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout + }); + + console.log("What resource file do you want to write to?"); + + rl.on('line', async (input) => { + switch (state) { + case 'NO': + resourceId = input; + state = 'ResourceSet'; + console.log("What is your WebID?"); + break; + + case 'ResourceSet': + assigneeId = input; + state = 'AssigneeSet'; + console.log("What do you want to write?"); + break; + + case 'AssigneeSet': + await traverseFile(input, assigneeId, resourceId); + console.log("\n\n\n*************************************************\n\n\nWhat resource file do you want to write to?"); + state = 'NO'; + break; + } + }); +} + +main(); diff --git a/scripts/seed-uma-ODRL-policy.ts b/scripts/seed-uma-ODRL-policy.ts new file mode 100644 index 00000000..b1ac008a --- /dev/null +++ b/scripts/seed-uma-ODRL-policy.ts @@ -0,0 +1,70 @@ +import * as readline from 'readline'; +import { seedingPolicies, seedingPolicies2, seedingPolicies3 } from './util/policyExamples'; + +async function seedForOneClient(id: string) { + await fetch("http://localhost:4000/uma/policies", { method: 'POST', headers: { 'Authorization': id, 'Content-Type': 'text/turtle' }, body: Buffer.from(seedingPolicies3(id), 'utf-8') }); +} + +async function deleteForOneClient(id: string) { + const policyIds = [ + 'http://example.org/usagePolicy1-read', + 'http://example.org/usagePolicy1-write', + 'http://example.org/usagePolicy1-append', + 'http://example.org/usagePolicy1a-control-1', + 'http://example.org/usagePolicy1a-control-2', + 'http://example.org/usagePolicy3-create', + 'http://example.org/usagePolicy3b-create', + 'http://example.org/usagePolicy3b-read', + 'http://example.org/usagePolicy3b-write', + 'http://example.org/usagePolicy3b-control', + 'urn:uuid:policy-read', + 'urn:uuid:policy-append', + 'urn:uuid:policy-write', + ]; + + for (const policyId of policyIds) { + await fetch(`http://localhost:4000/uma/policies/${encodeURIComponent(policyId)}`, { + method: 'DELETE', + headers: { 'Authorization': id } + }); + } +} + + +async function main() { + let started: 'NO' | 'SEED' | 'DELETE' = 'NO'; + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout + }); + console.log("Do you want to seed or delete? (type 'seed' or 'delete')"); + rl.on('line', async (input) => { + if (started === 'NO') { + if (input === "seed") { + started = 'SEED'; + console.log("Type the webID that you wish to seed, or cancel:"); + } + else if (input === "delete") { + console.log("Type the webID of the client who's seeded data you want to delete, or cancel:") + started = 'DELETE'; + } + else + console.log("Type 'seed' or 'delete'") + } else { + if (input === 'cancel') + started = 'NO'; + else if (started === 'SEED') { + await seedForOneClient(input); + console.log('seeding completed') + } else { + await deleteForOneClient(input); + console.log('deleting complete') + } + console.log("Do you want to seed or delete? (type 'seed' or 'delete')"); + started = 'NO'; + } + + }); +} + +main(); \ No newline at end of file diff --git a/scripts/test-private.ts b/scripts/test-private.ts index 7b02f6f4..a3411654 100644 --- a/scripts/test-private.ts +++ b/scripts/test-private.ts @@ -1,4 +1,4 @@ -#!/usr/bin/env ts-node +#!/usr/bin/env -S npx tsx const privateResource = "http://localhost:3000/alice/private/resource.txt" diff --git a/scripts/test-public.ts b/scripts/test-public.ts index ead0553c..7f745b5c 100644 --- a/scripts/test-public.ts +++ b/scripts/test-public.ts @@ -1,4 +1,4 @@ -#!/usr/bin/env ts-node +#!/usr/bin/env -S npx tsx const publicResource = "http://localhost:3000/alice/profile/card" diff --git a/scripts/test-registration.ts b/scripts/test-registration.ts index d69d330d..c58338a6 100644 --- a/scripts/test-registration.ts +++ b/scripts/test-registration.ts @@ -1,4 +1,4 @@ -#!/usr/bin/env ts-node +#!/usr/bin/env -S npx tsx const container = "http://localhost:3000/alice/public/"; const slug = "resource.txt"; diff --git a/scripts/test-uma-ODRL-policy.ts b/scripts/test-uma-ODRL-policy.ts index fc1a0c18..5404cba5 100644 --- a/scripts/test-uma-ODRL-policy.ts +++ b/scripts/test-uma-ODRL-policy.ts @@ -4,45 +4,193 @@ * The purpose of this file is to test the /policies endpoint. */ -import path from "path"; -import { DirectoryUCRulesStorage } from "../packages/ucp/src/storage/DirectoryUCRulesStorage" -import { PolicyRequestHandler } from "../packages/uma/src/routes/Policy" +import { policyA, policyB, policyC, badPolicy1, changePolicy1, changePolicy95e, putPolicy95e, putPolicyB } from "./util/policyExamples"; -const endpoint = 'http://localhost:4000/uma/policies' -const client1 = 'https://pod.woutslabbinck.com/profile/card#me'; -const client2 = 'https://pod.example.com/profile/card#me'; +const endpoint = (extra: string = '') => 'http://localhost:4000/uma/policies' + extra; +const client = (client: string = 'a') => `https://pod.${client}.com/profile/card#me`; +const policyId1 = 'http://example.org/usagePolicy1'; +const policyId95e = 'urn:uuid:95efe0e8-4fb7-496d-8f3c-4d78c97829bc' +const badPolicyId = 'nonExistentPolicy'; +const quickBuffer = (text: string) => Buffer.from(text, 'utf-8'); +let errorCounter = 0; -// Pathname for the test-policy directory, will probably be changed with the new test structure -const policyStorePath = path.join(__dirname, '..', 'packages', 'uma', 'config', 'rules', 'test'); +// Test if the first digit of the status code equals the second arg, or match the entire code when specific is false +const testCode = (code: number, shouldbe: number = 2, trunc: boolean = true) => { + if ((trunc ? Math.trunc(Number(code) / 100) : code) !== shouldbe) { errorCounter++; console.log("here") } +} + +async function putPolicies() { + const encoded = encodeURIComponent(policyId95e); + console.log("test PUT policies"); -async function testGetAllPolicies() { - console.log("\n\nTest GET all policies endpoint",); + // reset the policy to be sure + await deleteAll(); + await postPolicy(); - let response = await fetch(endpoint, { headers: { 'Authorization': client1 } }); + let response = await fetch(endpoint(`/${encoded}`), { method: 'PUT', headers: { 'Authorization': client('a'), 'Content-Type': 'text/turtle' }, body: quickBuffer(putPolicy95e) }); + console.log(`expecting Policy header to mistakenly contain the new policies: ${response.status}\n${await response.text()}`); - console.log("expecting all five policies and their relations: \n", await response.text()); + response = await fetch(endpoint(`/${encoded}`), { headers: { 'Authorization': client('b') } }); + console.log(`expecting to stay the same as before ${policyId95e}`, await response.text()); - response = await fetch(endpoint, { headers: { 'Authorization': client2 } }); +} - console.log("expecting zero policies: ", await response.text()); +async function patchPolicies() { + console.log("Simple test for the PATCH policy endpoint"); + const encoded1 = encodeURIComponent(policyId1); + const encoded95e = encodeURIComponent(policyId95e); - response = await fetch(endpoint, {}); + let response = await fetch(endpoint(`/${encoded1}`), { method: 'PATCH', headers: { 'Authorization': client('a'), 'Content-Type': 'application/sparql-update' }, body: quickBuffer(changePolicy1) }); + console.log(`expecting a positive response: status code ${response.status}\n expecting to see policy100 as its only rule: \n${await response.text()}`); + testCode(response.status); - console.log(`expecting 4xx error code (no authorization header provided): ${response.status}`); + response = await fetch(endpoint(`/${encoded95e}`), { method: 'PATCH', headers: { 'Authorization': client('a'), 'Content-Type': 'application/sparql-update' }, body: quickBuffer(changePolicy95e) }); + console.log(`expecting a positive response: status code ${response.status}\nexpecting the old rule to delete and two rules to take its place: \n${await response.text()}`); + testCode(response.status); - // Manual test for specific test cases - // This test uses the existing test.ttl policy directory as the store, could be any other store - const store = new DirectoryUCRulesStorage(policyStorePath); - const handler = new PolicyRequestHandler(store); + response = await fetch(endpoint(`/${encoded1}`), { method: 'PATCH', headers: { 'Authorization': client('c'), 'Content-Type': 'application/sparql-update' }, body: quickBuffer(changePolicy1) }); + console.log(`expecting a negative response since the query changes another client's rules ${response.status}\nmessage: ${await response.text()}`); + testCode(response.status, 4); - let res = await handler.handle({ request: { url: new URL("http://localhost:4000/uma/policies"), method: 'GET', headers: { 'authorization': "https://pod.a.com/profile/card#me" } } }); - console.log("expecting only policy 1: ", res.body); + response = await fetch(endpoint(), { headers: { 'Authorization': client('a') } }) + console.log("expecting to see the patched policy for client a: \n", await response.text()) + testCode(response.status); } -async function main() { - console.log(`Primitive unit test to check policy access based on the client\n`); +async function getAllPolicies() { + console.log("Simple test for the GET All Policies endpoint\n"); + + let response = await fetch(endpoint(), { headers: { 'Authorization': client('a') } }) + console.log("expecting policy 1, 1a and : \n", await response.text()) + testCode(response.status); + + response = await fetch(endpoint(), { headers: { 'Authorization': client('b') } }) + console.log("expecting policy 2, 2a and : \n", await response.text()) + testCode(response.status); + + response = await fetch(endpoint(), {}); + console.log(`expecting 4xx error code (no authorization header provided): ${response.status}`) + testCode(response.status, 4); +} + +async function getOnePolicy() { + console.log("Simple test for the GET One Policy endpoint"); + + const encoded = encodeURIComponent(policyId1); + + let response = await fetch(endpoint(`/${encoded}`), { headers: { 'Authorization': client('a') } }); + console.log(`expecting to return relevent information about ${policyId1}`, await response.text()); + + response = await fetch(endpoint(`/${badPolicyId}`), { headers: { 'Authorization': client('b') } }); + let resText = await response.text(); + console.log(`expecting an empty body, the policy ID does not exist: ${resText}`); + testCode(resText.length, 0, false); + + response = await fetch(endpoint(`/${encoded}`), { headers: { 'Authorization': client('c') } }); + resText = await response.text(); + console.log(`expecting an empty body, the client is not authorized: ${resText}`); + testCode(resText.length, 0, false); +} + +async function postPolicy() { + console.log("Simple test for the POST policy endpoint"); + + let response = await fetch(endpoint(), { method: 'POST', headers: { 'Authorization': client('a'), 'Content-Type': 'text/turtle' }, body: quickBuffer(policyB) }); + console.log(`expecting a negative response since assigner != client: status code ${response.status}\nmessage: ${await response.text()}`); + testCode(response.status, 4); + + response = await fetch(endpoint(), { method: 'POST', headers: { 'Authorization': client('b'), 'Content-Type': 'text/turtle' }, body: quickBuffer(badPolicy1) }); + console.log(`expecting a negative response since policy has a rule with no assigner ${response.status}\nmessage: ${await response.text()}`); + testCode(response.status, 4); + + response = await fetch(endpoint(), { method: 'POST', headers: { 'Authorization': client('a'), 'Content-Type': 'text/turtle' }, body: quickBuffer(policyA) }); + console.log(`expecting a positive response: status code ${response.status}, ${await response.text()}`); + testCode(response.status); - await testGetAllPolicies(); + response = await fetch(endpoint(), { method: 'POST', headers: { 'Authorization': client('b'), 'Content-Type': 'text/turtle' }, body: quickBuffer(policyB) }); + console.log(`expecting a positive response: status code ${response.status}, ${await response.text()}`); + testCode(response.status); + + response = await fetch(endpoint(), { method: 'POST', headers: { 'Authorization': client('c'), 'Content-Type': 'text/turtle' }, body: quickBuffer(policyC) }); + console.log(`expecting a positive response: status code ${response.status}, ${await response.text()}`); + testCode(response.status); +} + +async function testDelete() { + const encodedPolicyId = encodeURIComponent(policyId95e); + console.log("Testing Delete endpoint"); + + let response = await fetch(endpoint(`/${encodedPolicyId}`), { method: 'DELETE', headers: { 'Authorization': client('c') } }); + console.log(`expecting status 204, nothing to delete: ${response.status}`); + testCode(response.status, 204, false); + + response = await fetch(endpoint(`/${encodedPolicyId}`), { method: 'DELETE', headers: { 'Authorization': client('a') } }); + console.log(`expecting status 200: ${response.status}\n`); + testCode(response.status, 200, false); + + console.log('testing if the policy is deleted for client a, but not for client b\n'); + response = await fetch(endpoint(`/${encodedPolicyId}`), { headers: { 'Authorization': client('a') } }); + let resText = await response.text(); + console.log(`expecting an empty body, the policy should be deleted for client a: ${resText}`); + testCode(resText.length, 0, false); + + response = await fetch(endpoint(`/${encodedPolicyId}`), { headers: { 'Authorization': client('b') } }); + resText = await response.text(); + console.log(`expecting the policy with one rule: ${resText}\n\n`); + + console.log('now we delete the policy for client b. It should delete the rules AND the policy information'); + response = await fetch(endpoint(`/${encodedPolicyId}`), { method: 'DELETE', headers: { 'Authorization': client('b') } }); + console.log(`expecting status 200: ${response.status}`); + testCode(response.status, 200, false); + response = await fetch(endpoint(`/${encodedPolicyId}`), { headers: { 'Authorization': client('a') } }); + resText = await response.text(); + console.log(`expecting an empty body, the policy should be deleted for client a: ${resText}`); + testCode(resText.length, 0, false); +} + +async function furtherSeeding() { + // Due to new POST implementation, client B must PUT its own rules into existing policy `policy95e` + const response = await fetch(endpoint(`/${encodeURIComponent(policyId95e)}`), { method: 'PUT', headers: { 'Authorization': client('b'), 'Content-Type': 'text/turtle' }, body: quickBuffer(putPolicyB) }); + console.log(`expecting Policy header to mistakenly contain the new policies: ${response.status}\n${await response.text()}`); +} + +async function deleteAll() { + const obj = { + 'a': ['http://example.org/usagePolicy1', 'http://example.org/usagePolicy1a', 'urn:uuid:95efe0e8-4fb7-496d-8f3c-4d78c97829bc'], + 'b': ['http://example.org/usagePolicy2', 'http://example.org/usagePolicy2a', 'urn:uuid:95efe0e8-4fb7-496d-8f3c-4d78c97829bc'], 'c': ['http://example.org/usagePolicy3'] + } + console.log("deleting all policies") + for (const [clientId, policyIds] of Object.entries(obj)) { + for (const policyId of policyIds) { + const response = await fetch(endpoint(`/${encodeURIComponent(policyId)}`), { method: 'DELETE', headers: { 'Authorization': client(clientId) } }) + console.log(`DELETE ${policyId} from client ${clientId} responded with status ${response.status}`) + } + } +} + +/** + * As explained in the docs, the order of execution is extremely important. + * The storage is filled with the POST requests, so this must precede the other tests! + */ +async function main() { + errorCounter = 0; + console.log("Testing all implemented Policy Endpoints:\n\n\n"); + await postPolicy(); + await furtherSeeding(); + console.log("\n\n\n"); + await getAllPolicies(); + console.log("\n\n\n"); + await getOnePolicy(); + console.log("\n\n\n"); + await patchPolicies(); + console.log("\n\n\n"); + await testDelete(); + console.log("\n\n\n"); + await putPolicies(); + console.log("\n\n\n"); + await deleteAll() + console.log("\n\n\n"); + console.log(errorCounter === 0 ? `No fails detected` : `${errorCounter} tests have failed`); } main() diff --git a/scripts/test-uma-ucp.ts b/scripts/test-uma-ucp.ts index 889462c7..79b65e0c 100644 --- a/scripts/test-uma-ucp.ts +++ b/scripts/test-uma-ucp.ts @@ -1,4 +1,4 @@ -#!/usr/bin/env ts-node +#!/usr/bin/env -S npx tsx // Resource and WebID as set in config/rules/policy/policy0.ttl const resource = "http://localhost:3000/alice/other/resource.txt"; diff --git a/scripts/util/policyExamples.ts b/scripts/util/policyExamples.ts new file mode 100644 index 00000000..f7f7b216 --- /dev/null +++ b/scripts/util/policyExamples.ts @@ -0,0 +1,484 @@ +export const policyA = ` +@prefix ex: . +@prefix odrl: . +@prefix dct: . + +ex:usagePolicy1 a odrl:Agreement . +ex:usagePolicy1 odrl:permission ex:permission1 . +ex:permission1 a odrl:Permission . +ex:permission1 odrl:action odrl:modify . +ex:permission1 odrl:target . +ex:permission1 odrl:assignee . +ex:permission1 odrl:assigner . + +ex:usagePolicy1a a odrl:Agreement . +ex:usagePolicy1a odrl:permission ex:permission1a . +ex:permission1a a odrl:Permission . +ex:permission1a odrl:action odrl:read . +ex:permission1a odrl:target . +ex:permission1a odrl:assignee . +ex:permission1a odrl:assigner . + + a odrl:Set; + dct:description "A is data owner of resource X. ALICE may READ resource X."; + odrl:permission . + a odrl:Permission; + odrl:action odrl:read; + odrl:target ex:x; + odrl:assignee ex:alice; + odrl:assigner . +`; +export const policyB = `@prefix ex: . +@prefix odrl: . +@prefix dct: . + +ex:usagePolicy2 a odrl:Agreement . +ex:usagePolicy2 odrl:permission ex:permission2a . +ex:permission2 a odrl:Permission . +ex:permission2 odrl:action odrl:modify . +ex:permission2 odrl:target . +ex:permission2 odrl:assignee . +ex:permission2 odrl:assigner . + +ex:usagePolicy2a a odrl:Agreement . +ex:usagePolicy2a odrl:permission ex:permission2 . +ex:permission2a a odrl:Permission . +ex:permission2a odrl:action odrl:write . +ex:permission2a odrl:target . +ex:permission2a odrl:assignee . +ex:permission2a odrl:assigner . +`; + +export const putPolicyB = ` +@prefix ex: . +@prefix odrl: . +@prefix dct: . + a odrl:Set; + dct:description "ZENO is data owner of resource X. ALICE may READ resource X."; + odrl:permission . + + a odrl:Permission ; + odrl:assignee ex:bob ; + odrl:assigner ; + odrl:action odrl:read ; + odrl:target ex:x .`; + +export const policyC = `@prefix ex: . +@prefix odrl: . +@prefix dct: . + +ex:usagePolicy3 a odrl:Agreement . +ex:usagePolicy3 odrl:permission ex:permission3 . +ex:permission3 a odrl:Permission . +ex:permission3 odrl:action odrl:read . +ex:permission3 odrl:target . +ex:permission3 odrl:assignee . +ex:permission3 odrl:assigner .`; + +export const badPolicy1 = ` +@prefix ex: . +@prefix odrl: . +@prefix dct: . + +ex:usagePolicyBad a odrl:Agreement . +ex:usagePolicyBad odrl:permission ex:permissionBad . +ex:permissionBad a odrl:Permission . +ex:permissionBad odrl:action odrl:modify . +ex:permissionBad odrl:target . +ex:permissionBad odrl:assignee . +` + +export const changePolicy1 = ` +PREFIX ex: +PREFIX odrl: +PREFIX dct: + +DELETE { + ex:usagePolicy1 odrl:permission ex:permission1 . + ex:permission1 a odrl:Permission ; + odrl:action odrl:modify ; + odrl:target ; + odrl:assignee ; + odrl:assigner . +} +INSERT { + ex:usagePolicy1 odrl:permission ex:permission100 . + ex:permission100 a odrl:Permission ; + odrl:action odrl:read ; + odrl:target ; + odrl:assignee ; + odrl:assigner . +} +WHERE { + ex:usagePolicy1 odrl:permission ex:permission1 . + ex:permission1 a odrl:Permission ; + odrl:action odrl:modify ; + odrl:target ; + odrl:assignee ; + odrl:assigner . +} +` + +export const changePolicy95e = ` +PREFIX ex: +PREFIX odrl: +PREFIX dct: + +DELETE { + odrl:permission . + ?p ?o . +} +INSERT { + odrl:permission . + odrl:permission . + + a odrl:Permission ; + odrl:assignee ex:alice ; + odrl:assigner ; + odrl:action odrl:write ; + odrl:target ex:x . + + a odrl:Permission ; + odrl:assignee ex:alice ; + odrl:assigner ; + odrl:action odrl:delete ; + odrl:target ex:x . +} +WHERE { + OPTIONAL { + ?p ?o . + } +} +` + +export const putPolicy95e = ` + a ; + "ZENO is data owner of resource X. ALICE may READ resource X."; + , . + a ; + ; + ; + ; + . + a ; + ; + ; + ; + . +` + +export const seedingPolicies = (id: string) => ` +@prefix ex: . +@prefix odrl: . +@prefix dct: . + +ex:usagePolicy1 a odrl:Agreement . +ex:usagePolicy1 odrl:permission ex:permission1 . +ex:permission1 a odrl:Permission . +ex:permission1 odrl:action odrl:read . +ex:permission1 odrl:action odrl:write . +ex:permission1 odrl:action odrl:append . +ex:permission1 odrl:target . +ex:permission1 odrl:assignee . +ex:permission1 odrl:assigner <${id}> . + +ex:usagePolicy1a a odrl:Agreement . +ex:usagePolicy1a odrl:permission ex:permission1a . +ex:permission1a a odrl:Permission . +ex:permission1a odrl:action odrl:control . +ex:permission1a odrl:target . +ex:permission1a odrl:assignee . +ex:permission1a odrl:assignee . +ex:permission1a odrl:assigner <${id}> . + + a odrl:Set; + dct:description "A is data owner of resource X. ALICE may READ resource X."; + odrl:permission . + a odrl:Permission; + odrl:action odrl:read; + odrl:action odrl:append; + odrl:action odrl:write; + odrl:target ex:x; + odrl:assignee ex:alice; + odrl:assigner <${id}>. + +ex:usagePolicy3 a odrl:Agreement . +ex:usagePolicy3 odrl:permission ex:permission3 . +ex:permission3 a odrl:Permission . +ex:permission3 odrl:action odrl:control . +ex:permission3 odrl:target . +ex:permission3 odrl:assignee . +ex:permission3 odrl:assigner <${id}> . + +ex:usagePolicy3 odrl:permission ex:permission3b . +ex:permission3b a odrl:Permission . +ex:permission3b odrl:action odrl:create . +ex:permission3b odrl:action odrl:read . +ex:permission3b odrl:action odrl:write . +ex:permission3b odrl:action odrl:control . +ex:permission3b odrl:target . +ex:permission3b odrl:assigner <${id}> . + +` + +export const seedingPolicies2 = (id: string) => ` +@prefix ex: . +@prefix odrl: . +@prefix dct: . + +ex:usagePolicy1-read a odrl:Agreement . +ex:usagePolicy1-read odrl:permission ex:permission1-read . +ex:permission1-read a odrl:Permission . +ex:permission1-read odrl:action odrl:read . +ex:permission1-read odrl:target . +ex:permission1-read odrl:assignee . +ex:permission1-read odrl:assigner <${id}> . + +ex:usagePolicy1-write a odrl:Agreement . +ex:usagePolicy1-write odrl:permission ex:permission1-write . +ex:permission1-write a odrl:Permission . +ex:permission1-write odrl:action odrl:write . +ex:permission1-write odrl:target . +ex:permission1-write odrl:assignee . +ex:permission1-write odrl:assigner <${id}> . + +ex:usagePolicy1-append a odrl:Agreement . +ex:usagePolicy1-append odrl:permission ex:permission1-append . +ex:permission1-append a odrl:Permission . +ex:permission1-append odrl:action odrl:append . +ex:permission1-append odrl:target . +ex:permission1-append odrl:assignee . +ex:permission1-append odrl:assigner <${id}> . + +ex:usagePolicy1a-control-1 a odrl:Agreement . +ex:usagePolicy1a-control-1 odrl:permission ex:permission1a-control-1 . +ex:permission1a-control-1 a odrl:Permission . +ex:permission1a-control-1 odrl:action odrl:control . +ex:permission1a-control-1 odrl:target . +ex:permission1a-control-1 odrl:assignee . +ex:permission1a-control-1 odrl:assigner <${id}> . + +ex:usagePolicy1a-control-2 a odrl:Agreement . +ex:usagePolicy1a-control-2 odrl:permission ex:permission1a-control-2 . +ex:permission1a-control-2 a odrl:Permission . +ex:permission1a-control-2 odrl:action odrl:control . +ex:permission1a-control-2 odrl:target . +ex:permission1a-control-2 odrl:assignee . +ex:permission1a-control-2 odrl:assigner <${id}> . + + a odrl:Set; + dct:description "A is data owner of resource X. ALICE may READ resource X."; + odrl:permission . + a odrl:Permission; + odrl:action odrl:read; + odrl:target ex:x; + odrl:assignee ex:alice; + odrl:assigner <${id}> . + + a odrl:Set; + odrl:permission . + a odrl:Permission; + odrl:action odrl:append; + odrl:target ex:x; + odrl:assignee ex:alice; + odrl:assigner <${id}> . + + a odrl:Set; + odrl:permission . + a odrl:Permission; + odrl:action odrl:write; + odrl:target ex:x; + odrl:assignee ex:alice; + odrl:assigner <${id}> . + +ex:usagePolicy3-create a odrl:Agreement . +ex:usagePolicy3-create odrl:permission ex:permission3-create . +ex:permission3-create a odrl:Permission . +ex:permission3-create odrl:action odrl:create . +ex:permission3-create odrl:target . +ex:permission3-create odrl:assignee . +ex:permission3-create odrl:assigner <${id}> . + +ex:usagePolicy3b-create a odrl:Agreement . +ex:usagePolicy3b-create odrl:permission ex:permission3b-create . +ex:permission3b-create a odrl:Permission . +ex:permission3b-create odrl:action odrl:create . +ex:permission3b-create odrl:target . +ex:permission3b-create odrl:assigner <${id}> . + +ex:usagePolicy3b-read a odrl:Agreement . +ex:usagePolicy3b-read odrl:permission ex:permission3b-read . +ex:permission3b-read a odrl:Permission . +ex:permission3b-read odrl:action odrl:read . +ex:permission3b-read odrl:target . +ex:permission3b-read odrl:assigner <${id}> . + +ex:usagePolicy3b-write a odrl:Agreement . +ex:usagePolicy3b-write odrl:permission ex:permission3b-write . +ex:permission3b-write a odrl:Permission . +ex:permission3b-write odrl:action odrl:write . +ex:permission3b-write odrl:target . +ex:permission3b-write odrl:assigner <${id}> . + +ex:usagePolicy3b-control a odrl:Agreement . +ex:usagePolicy3b-control odrl:permission ex:permission3b-control . +ex:permission3b-control a odrl:Permission . +ex:permission3b-control odrl:action odrl:control . +ex:permission3b-control odrl:target . +ex:permission3b-control odrl:assigner <${id}> . +` +export const seedingPolicies3 = (id: string) => ` +@prefix ex: . +@prefix odrl: . +@prefix dct: . + +ex:usagePolicy1 a odrl:Agreement . +ex:usagePolicy1 odrl:permission ex:permission1-read . +ex:permission1-read a odrl:Permission . +ex:permission1-read odrl:action odrl:read . +ex:permission1-read odrl:target . +ex:permission1-read odrl:assignee . +ex:permission1-read odrl:assigner <${id}> . + +ex:usagePolicy1 odrl:permission ex:permission1-write . +ex:permission1-write a odrl:Permission . +ex:permission1-write odrl:action odrl:write . +ex:permission1-write odrl:target . +ex:permission1-write odrl:assignee . +ex:permission1-write odrl:assigner <${id}> . + +ex:usagePolicy1 odrl:permission ex:permission1-append . +ex:permission1-append a odrl:Permission . +ex:permission1-append odrl:action odrl:append . +ex:permission1-append odrl:target . +ex:permission1-append odrl:assignee . +ex:permission1-append odrl:assigner <${id}> . + +ex:usagePolicy1a a odrl:Agreement . +ex:usagePolicy1a odrl:permission ex:permission1a-control-1 . +ex:permission1a-control-1 a odrl:Permission . +ex:permission1a-control-1 odrl:action odrl:control . +ex:permission1a-control-1 odrl:target . +ex:permission1a-control-1 odrl:assignee . +ex:permission1a-control-1 odrl:assigner <${id}> . + +ex:usagePolicy1a odrl:permission ex:permission1a-control-2 . +ex:permission1a-control-2 a odrl:Permission . +ex:permission1a-control-2 odrl:action odrl:control . +ex:permission1a-control-2 odrl:target . +ex:permission1a-control-2 odrl:assignee . +ex:permission1a-control-2 odrl:assigner <${id}> . + + a odrl:Set; + dct:description "A is data owner of resource X. ALICE may READ resource X."; + odrl:permission . + a odrl:Permission; + odrl:action odrl:read; + odrl:target ex:x; + odrl:assignee ex:alice; + odrl:assigner <${id}> . + + a odrl:Set; + odrl:permission . + a odrl:Permission; + odrl:action odrl:append; + odrl:target ex:x; + odrl:assignee ex:alice; + odrl:assigner <${id}> . + + a odrl:Set; + odrl:permission . + a odrl:Permission; + odrl:action odrl:write; + odrl:target ex:x; + odrl:assignee ex:alice; + odrl:assigner <${id}> . + +ex:usagePolicy3 a odrl:Agreement . +ex:usagePolicy3 odrl:permission ex:permission3-create . +ex:permission3-create a odrl:Permission . +ex:permission3-create odrl:action odrl:write . +ex:permission3-create odrl:target . +ex:permission3-create odrl:assignee . +ex:permission3-create odrl:assigner <${id}> . + +ex:usagePolicy3 odrl:permission ex:permission3b-create . +ex:permission3b-create a odrl:Permission . +ex:permission3b-create odrl:action odrl:read . +ex:permission3b-create odrl:target . +ex:permission3b-create odrl:assigner <${id}> . + +ex:usagePolicy3 odrl:permission ex:permission3b-read . +ex:permission3b-read a odrl:Permission . +ex:permission3b-read odrl:action odrl:read . +ex:permission3b-read odrl:target . +ex:permission3b-read odrl:assigner <${id}> . + +ex:usagePolicy3 odrl:permission ex:permission3b-read . +ex:permission3b-read a odrl:Permission . +ex:permission3b-read odrl:action odrl:read . +ex:permission3b-read odrl:target . +ex:permission3b-read odrl:assigner <${id}> . + + +ex:usagePolicy3 odrl:permission ex:permission3b-write . +ex:permission3b-write a odrl:Permission . +ex:permission3b-write odrl:action odrl:write . +ex:permission3b-write odrl:target . +ex:permission3b-write odrl:assigner <${id}> . +ex:permission3b-write odrl:assignee . + + +ex:usagePolicy3 odrl:permission ex:permission3b-control . +ex:permission3b-control a odrl:Permission . +ex:permission3b-control odrl:action odrl:control . +ex:permission3b-control odrl:target . +ex:permission3b-control odrl:assigner <${id}> . +` + +export const seedTestFetcher = ` +@prefix ex: . +@prefix odrl: . +@base . + + +ex:usagePolicy1 a odrl:Agreement . +ex:usagePolicy1 odrl:permission ex:permission1 . +ex:permission1 a odrl:Permission . +ex:permission1 odrl:action odrl:modify . +ex:permission1 odrl:target . +ex:permission1 odrl:assignee . +ex:permission1 odrl:assigner . + +ex:usagePolicy1a a odrl:Agreement . +ex:usagePolicy1a odrl:permission ex:permission1a . +ex:permission1a a odrl:Permission . +ex:permission1a odrl:action odrl:create . +ex:permission1a odrl:target . +ex:permission1a odrl:assignee . +ex:permission1a odrl:assigner . + +ex:usagePolicy2 a odrl:Agreement . +ex:usagePolicy2 odrl:permission ex:permission2a . +ex:permission2 a odrl:Permission . +ex:permission2 odrl:action odrl:modify . +ex:permission2 odrl:target . +ex:permission2 odrl:assignee . +ex:permission2 odrl:assigner . + +ex:usagePolicy2a a odrl:Agreement . +ex:usagePolicy2a odrl:permission ex:permission2 . +ex:permission2a a odrl:Permission . +ex:permission2a odrl:action odrl:create . +ex:permission2a odrl:target . +ex:permission2a odrl:assignee . +ex:permission2a odrl:assigner . + + +ex:usagePolicy3 a odrl:Agreement . +ex:usagePolicy3 odrl:permission ex:permission3 . +ex:permission3 a odrl:Permission . +ex:permission3 odrl:action odrl:read . +ex:permission3 odrl:target . +ex:permission3 odrl:assignee . +ex:permission3 odrl:assigner .` \ No newline at end of file diff --git a/test/integration/Base.test.ts b/test/integration/Base.test.ts new file mode 100644 index 00000000..2a5248a8 --- /dev/null +++ b/test/integration/Base.test.ts @@ -0,0 +1,175 @@ +import { App, setGlobalLoggerFactory, WinstonLoggerFactory } from '@solid/community-server'; +import * as path from 'node:path'; +import { getDefaultCssVariables, instantiateFromConfig } from '../util/ServerUtil'; + +const cssPort = 3001; +const umaPort = 4001; + +describe('A server setup', (): void => { + let umaApp: App; + let cssApp: App; + + beforeAll(async(): Promise => { + setGlobalLoggerFactory(new WinstonLoggerFactory('off')); + + umaApp = await instantiateFromConfig( + 'urn:uma:default:App', + path.join(__dirname, '../../packages/uma/config/default.json'), + { + 'urn:uma:variables:port': umaPort, + 'urn:uma:variables:baseUrl': `http://localhost:${umaPort}/uma`, + 'urn:uma:variables:policyBaseIRI': `http://localhost:${cssPort}/`, + 'urn:uma:variables:policyDir': path.join(__dirname, '../../packages/uma/config/rules/policy'), + 'urn:uma:variables:eyePath': 'eye', + } + ) as App; + + cssApp = await instantiateFromConfig( + 'urn:solid-server:default:App', + path.join(__dirname, '../../packages/css/config/default.json'), + { + ...getDefaultCssVariables(cssPort), + 'urn:solid-server:uma:variable:AuthorizationServer': `http://localhost:${umaPort}/`, + 'urn:solid-server:default:variable:seedConfig': path.join(__dirname, '../../packages/css/config/seed.json'), + }, + ) as App; + + await Promise.all([ umaApp.start(), cssApp.start() ]); + }); + + afterAll(async(): Promise => { + await Promise.all([ umaApp.stop(), cssApp.stop() ]); + }); + + describe('using public namespace authorization', (): void => { + const container = `http://localhost:${cssPort}/alice/public/`; + const slug = 'resource.txt'; + const body = 'This is a resource.'; + + it('RS: provides immediate read access.', async(): Promise => { + const publicResource = `http://localhost:${cssPort}/alice/profile/card`; + + const publicResponse = await fetch(publicResource); + + expect(publicResponse.status).toBe(200); + expect(publicResponse.headers.get('content-type')).toBe('text/turtle'); + }); + + it('RS: provides immediate create access to the container', async(): Promise => { + const containerResponse = await fetch(container, { + method: 'PUT', + }); + expect(containerResponse.status).toBe(201); + expect(containerResponse.headers.get('location')).toBe(container); + }); + + it('RS: provides immediate create access to the contents', async(): Promise => { + const createResponse = await fetch(container, { + method: 'POST', + headers: { slug }, + body + }); + expect(createResponse.status).toBe(201); + expect(createResponse.headers.get('location')).toBe(`${container}${slug}`); + }); + + it('RS: provides immediate read access to the contents', async(): Promise => { + const readResponse = await fetch(`${container}${slug}`); + expect(readResponse.status).toBe(200); + await expect(readResponse.text()).resolves.toBe(body); + }); + + it('RS: provides immediate delete access to the contents', async(): Promise => { + const deleteResponse = await fetch(`${container}${slug}`, { + method: 'DELETE', + }) + expect(deleteResponse.status).toBe(205); + + const readResponse = await fetch(`${container}${slug}`); + expect(readResponse.status).toBe(404); + }); + }); + + describe('using ODRL authorization', (): void => { + const privateResource = `http://localhost:${cssPort}/alice/private/resource.txt`; + let wwwAuthenticateHeader: string; + let ticket: string; + let tokenEndpoint: string; + let jsonResponse: { access_token: string, token_type: string }; + + it('RS: sends a WWW-Authenticate response when access is private.', async(): Promise => { + const noTokenResponse = await fetch(privateResource, { + method: 'PUT', + body: 'Some text ...' , + }); + + expect(noTokenResponse.status).toBe(401); + wwwAuthenticateHeader = noTokenResponse.headers.get('WWW-Authenticate'); + expect(typeof wwwAuthenticateHeader).toBe('string'); + }); + + it('AS: returns the token endpoint from the configuration.', async(): Promise => { + const parsedHeader = Object.fromEntries( + wwwAuthenticateHeader + .replace(/^UMA /,'') + .split(', ') + .map(param => param.split('=').map(s => s.replace(/"/g,''))) + ); + expect(typeof parsedHeader.as_uri).toBe('string'); + expect(typeof parsedHeader.ticket).toBe('string'); + ticket = parsedHeader.ticket; + + const configurationUrl = parsedHeader.as_uri + '/.well-known/uma2-configuration'; + const response = await fetch(configurationUrl); + expect(response.status).toBe(200); + const configuration = await response.json(); + expect(typeof configuration.token_endpoint).toBe('string'); + tokenEndpoint = configuration.token_endpoint; + }); + + it('AS: responds with a token when receiving the ticket.', async(): Promise => { + const claim_token = 'https://woslabbi.pod.knows.idlab.ugent.be/profile/card#me'; + + const content = { + grant_type: 'urn:ietf:params:oauth:grant-type:uma-ticket', + ticket, + claim_token: encodeURIComponent(claim_token), + claim_token_format: 'urn:solidlab:uma:claims:formats:webid', + }; + + const asRequestResponse = await fetch(tokenEndpoint, { + method: 'POST', + headers: { 'content-type': 'application/json' }, + body: JSON.stringify(content), + }); + + expect(asRequestResponse.status).toBe(200); + expect(asRequestResponse.headers.get('content-type')).toBe('application/json'); + jsonResponse = await asRequestResponse.json(); + expect(typeof jsonResponse.access_token).toBe('string'); + expect(jsonResponse.token_type).toBe('Bearer'); + const token = JSON.parse(Buffer.from(jsonResponse.access_token.split('.')[1], 'base64').toString()); + expect(Array.isArray(token.permissions)).toBe(true); + expect(token.permissions).toHaveLength(2); + expect(token.permissions).toContainEqual({ + resource_id: `http://localhost:${cssPort}/alice/private/resource.txt`, + resource_scopes: [ 'urn:example:css:modes:append', 'urn:example:css:modes:create' ] + }); + expect(token.permissions).toContainEqual({ + resource_id: `http://localhost:${cssPort}/alice/private/`, + resource_scopes: [ 'urn:example:css:modes:create' ] + } + ); + }); + + it('RS: provides access when receiving a valid token.', async(): Promise => { + const response = await fetch(privateResource, { + method: 'PUT', + headers: { 'Authorization': `${jsonResponse.token_type} ${jsonResponse.access_token}` }, + body: 'Some text ...' , + }); + + expect(response.status).toBe(201); + }); + }); +}); diff --git a/test/integration/Demo.test.ts b/test/integration/Demo.test.ts new file mode 100644 index 00000000..15ca1f48 --- /dev/null +++ b/test/integration/Demo.test.ts @@ -0,0 +1,334 @@ +import { App, setGlobalLoggerFactory, WinstonLoggerFactory } from '@solid/community-server'; +import { DialogOutput } from '@solidlab/uma'; +import { Parser, Store } from 'n3'; +import * as path from 'node:path'; +import { getDefaultCssVariables, instantiateFromConfig } from '../util/ServerUtil'; + +const cssPort = 3003; +const umaPort = 4003; + +const terms = { + solid: { + umaServer: 'http://www.w3.org/ns/solid/terms#umaServer', + }, + resources: { + smartwatch: `http://localhost:${cssPort}/ruben/medical/smartwatch.ttl` + }, + agents: { + ruben: `http://localhost:${cssPort}/ruben/profile/card#me`, + alice: `http://localhost:${cssPort}/alice/profile/card#me`, + } +} + +async function noTokenFetch(input: string | URL | globalThis.Request, init?: RequestInit): Promise<{ as_uri: string, ticket: string }> { + const noTokenResponse = await fetch(input, init); + + expect(noTokenResponse.status).toBe(401); + + const wwwAuthenticateHeader = noTokenResponse.headers.get('WWW-Authenticate'); + expect(typeof wwwAuthenticateHeader).toBe('string'); + + const parsedHeader = Object.fromEntries( + wwwAuthenticateHeader + .replace(/^UMA /,'') + .split(', ') + .map(param => param.split('=').map(s => s.replace(/"/g,''))) + ); + expect(typeof parsedHeader.as_uri).toBe('string'); + expect(typeof parsedHeader.ticket).toBe('string'); + return parsedHeader; +} + +async function findTokenEndpoint(uri: string): Promise { + // TODO: cache this + const configurationUrl = uri + '/.well-known/uma2-configuration'; + const configResponse = await fetch(configurationUrl); + expect(configResponse.status).toBe(200); + const configuration = await configResponse.json(); + expect(typeof configuration.token_endpoint).toBe('string'); + return configuration.token_endpoint; +} + +async function getToken(ticket: string, endpoint: string, webId?: string): Promise { + const content: Record = { + grant_type: 'urn:ietf:params:oauth:grant-type:uma-ticket', + ticket: ticket, + }; + if (webId) { + content.claim_token = encodeURIComponent(webId); + content.claim_token_format = 'urn:solidlab:uma:claims:formats:webid'; + } + + const response = await fetch(endpoint, { + method: 'POST', + headers: { 'content-type': 'application/json' }, + body: JSON.stringify(content), + }); + + expect(response.status).toBe(200); + expect(response.headers.get('content-type')).toBe('application/json'); + const jsonResponse: DialogOutput = await response.json(); + + expect(typeof jsonResponse.access_token).toBe('string'); + expect(jsonResponse.token_type).toBe('Bearer'); + const token = JSON.parse(Buffer.from(jsonResponse.access_token.split('.')[1], 'base64').toString()); + expect(Array.isArray(token.permissions)).toBe(true); + + return jsonResponse; +} + +async function tokenFetch(token: any, input: string | URL | globalThis.Request, init?: RequestInit): Promise { + return fetch(input, { + ...init, + headers: { + ...init?.headers, + 'Authorization': `${token.token_type} ${token.access_token}` + }, + }); +} + +// TODO: only call this function if you know there will be a 401 +async function umaFetch(input: string | URL | globalThis.Request, init?: RequestInit, webId?: string): Promise { + // Parse ticket and UMA server URL from header + const parsedHeader = await noTokenFetch(input, init); + + // Find UMA server token endpoint + const tokenEndpoint = await findTokenEndpoint(parsedHeader.as_uri); + + // Send ticket request to UMA server and extract token from response + const token = await getToken(parsedHeader.ticket, tokenEndpoint, webId); + + // Perform new call with token + return tokenFetch(token, input, init); +} + +describe('A demo server setup', (): void => { + let umaApp: App; + let cssApp: App; + const policyContainer = `http://localhost:${cssPort}/ruben/settings/policies/`; + + beforeAll(async(): Promise => { + setGlobalLoggerFactory(new WinstonLoggerFactory('off')); + + umaApp = await instantiateFromConfig( + 'urn:uma:default:App', + path.join(__dirname, '../../packages/uma/config/demo.json'), + { + 'urn:uma:variables:port': umaPort, + 'urn:uma:variables:baseUrl': `http://localhost:${umaPort}/uma`, + 'urn:uma:variables:eyePath': 'eye', + 'urn:uma:variables:policyContainer': policyContainer, + } + ) as App; + + cssApp = await instantiateFromConfig( + 'urn:solid-server:default:App', + // Not using the demo config as that one writes to disk, this is the same but in memory + path.join(__dirname, '../../packages/css/config/default.json'), + { + ...getDefaultCssVariables(cssPort), + 'urn:solid-server:uma:variable:AuthorizationServer': `http://localhost:${umaPort}/`, + 'urn:solid-server:default:variable:seedConfig': path.join(__dirname, '../../demo/seed.json'), + }, + ) as App; + + await Promise.all([umaApp.start(), cssApp.start()]); + }); + + afterAll(async(): Promise => { + await Promise.all([ umaApp.stop(), cssApp.stop() ]); + }); + + it('sets up the initial data.', async(): Promise => { + // Policy that allows the creation of all the initial resources + const policy = ` + @prefix ex: . + @prefix odrl: . + + ex:usagePolicy a odrl:Agreement ; + odrl:permission ex:permission . + ex:permission a odrl:Permission ; + odrl:action odrl:create, odrl:append ; + odrl:target , + , + , + ; + odrl:assignee <${terms.agents.ruben}> ; + odrl:assigner <${terms.agents.ruben}> . + `; + + // Create policies container + let response = await fetch(`http://localhost:${cssPort}/ruben/settings/policies/policy`, { + method: 'PUT', + headers: { 'content-type': 'text/turtle' }, + body: policy, + }); + expect(response.status).toBe(201); + + // Create smartwatch data + response = await umaFetch(`http://localhost:${cssPort}/ruben/medical/smartwatch.ttl`, { + method: 'PUT', + headers: { 'content-type': 'application/trig' }, + body: ' .', + }, terms.agents.ruben); + expect(response.status).toBe(201); + + // Create private data + response = await umaFetch(`http://localhost:${cssPort}/ruben/private/data`, { + method: 'PUT', + headers: { 'content-type': 'text/turtle' }, + body: ` +@prefix dbo: . +@prefix xsd: . + + dbo:birthDate "1987-02-28"^^xsd:date .`, + }, terms.agents.ruben); + expect(response.status).toBe(201); + + // Create derived resources. + // This is outdated and not actually needed for the test, + // but this did cause a bug about auxiliary resources to be discovered, + // so it should stay until there is a specific test for those. + response = await umaFetch(`http://localhost:${cssPort}/ruben/private/.meta`, { + method: 'PATCH', + headers: { 'content-type': 'text/n3' }, + body: ` +@prefix solid: . +@prefix ex: . +@prefix derived: . + +_:rename a solid:InsertDeletePatch; + solid:inserts { + derived:derivedResource ex:bday. + ex:bday derived:template "derived/bday"; + derived:selector ; + derived:filter . + + derived:derivedResource ex:age. + ex:age derived:template "derived/age"; + derived:selector ; + derived:filter . + }.`, + }, terms.agents.ruben); + expect(response.status).toBe(205); + + // TODO: Do I need this though + // Add necessary triples to WebID + response = await fetch(terms.agents.ruben, { + method: 'PATCH', + headers: { 'content-type': 'text/n3' }, + body: ` +@prefix solid: . + +_:rename a solid:InsertDeletePatch; + solid:inserts { + <${terms.agents.ruben}> solid:umaServer + }.`, + }); + expect(response.status).toBe(205); + }); + + it('finds the UMA server of the user in their WebID.', async(): Promise => { + // TODO: what is the point of any of this? the as_uri response should have this data? + // TODO: find out why it doesn't work though as the term does get added at the end of the previous test + const response = await fetch(terms.agents.ruben, { + headers: { 'accept': 'text/turtle' }, + }); + expect(response.status).toBe(200); + const parser = new Parser({ baseIRI: terms.agents.ruben }); + const store = new Store(parser.parse(await response.text())); + expect(store.countQuads(terms.agents.ruben, terms.solid.umaServer, null, null)).toBe(1); + const umaServer = store.getObjects(terms.agents.ruben, terms.solid.umaServer, null)[0].value; + }); + + it('can add a healthcare policy to the server.', async(): Promise => { + const healthcare_patient_policy = + `PREFIX dcterms: +PREFIX eu-gdpr: +PREFIX oac: +PREFIX odrl: +PREFIX xsd: + +PREFIX ex: + + a odrl:Agreement ; + odrl:uid ex:HCPX-agreement ; + odrl:profile oac: ; + odrl:permission . + + a odrl:Permission ; + odrl:action odrl:read ; + odrl:target <${terms.resources.smartwatch}> ; + odrl:assigner <${terms.agents.ruben}> ; + odrl:assignee <${terms.agents.alice}> ; + odrl:constraint , + . + + a odrl:Constraint ; + odrl:leftOperand odrl:purpose ; # can also be oac:Purpose, to conform with OAC profile + odrl:operator odrl:eq ; + odrl:rightOperand ex:bariatric-care . + + a odrl:Constraint ; + odrl:leftOperand oac:LegalBasis ; + odrl:operator odrl:eq ; + odrl:rightOperand eu-gdpr:A9-2-a .` + + const medicalPolicyCreationResponse = await fetch(policyContainer, { + method: 'POST', + headers: { 'content-type': 'text/turtle' }, + body: healthcare_patient_policy, + }); + expect(medicalPolicyCreationResponse.status).toBe(201); + }); + + it('requires authorized access for patient data.', async(): Promise => { + // TODO: should do the steps individually here so we can check the contents of the tokens/tickets + // Parse ticket and UMA server URL from header + const parsedHeader = await noTokenFetch(terms.resources.smartwatch); + + // Find UMA server token endpoint + const tokenEndpoint = await findTokenEndpoint(parsedHeader.as_uri); + + // Send ticket request to UMA server and extract token from response + const token = await getToken(parsedHeader.ticket, tokenEndpoint, terms.agents.alice); + const accessToken = JSON.parse(Buffer.from(token.access_token.split('.')[1], 'base64').toString()); + expect(accessToken).toMatchObject({ + permissions:[{ + resource_id: terms.resources.smartwatch, + resource_scopes: [ 'urn:example:css:modes:read' ] + }], + contract:{ + '@context': 'http://www.w3.org/ns/odrl.jsonld', + '@type': 'Agreement', + uid: expect.any(String), + 'http://purl.org/dc/terms/description': 'Agreement for HCP X to read Alice\'s health data for bariatric care.', + 'https://w3id.org/dpv#hasLegalBasis': { + '@id': 'https://w3id.org/dpv/legal/eu/gdpr#eu-gdpr:A9-2-a' + }, + permission:[{ + '@type': 'Permission', + action: 'https://w3id.org/oac#read', + target: terms.resources.smartwatch, + assigner: 'http://localhost:3000/ruben/profile/card#me', + assignee: 'http://localhost:3000/alice/profile/card#me', + constraint: [{ + '@type': 'Constraint', + leftOperand: 'purpose', + operator: 'eq', + rightOperand: { '@id':'http://example.org/bariatric-care' } + }] + }] + }, + iat: expect.any(Number), + iss: `http://localhost:${umaPort}/uma`, + aud: 'solid', + exp: expect.any(Number), + jti: expect.any(String), + }) + + // Perform new call with token + const response = await tokenFetch(token, terms.resources.smartwatch); + expect(response.status).toBe(200); + }); +}); diff --git a/test/integration/Odrl.test.ts b/test/integration/Odrl.test.ts new file mode 100644 index 00000000..6c47280b --- /dev/null +++ b/test/integration/Odrl.test.ts @@ -0,0 +1,196 @@ +import { App, setGlobalLoggerFactory, WinstonLoggerFactory } from '@solid/community-server'; +import * as path from 'node:path'; +import { getDefaultCssVariables, instantiateFromConfig } from '../util/ServerUtil'; + +const cssPort = 3002; +const umaPort = 4002; + +describe('An ODRL server setup', (): void => { + let umaApp: App; + let cssApp: App; + + const resource = `http://localhost:${cssPort}/alice/other/resource.txt`; + + beforeAll(async(): Promise => { + setGlobalLoggerFactory(new WinstonLoggerFactory('off')); + + umaApp = await instantiateFromConfig( + 'urn:uma:default:App', + path.join(__dirname, '../../packages/uma/config/odrl.json'), + { + 'urn:uma:variables:port': umaPort, + 'urn:uma:variables:baseUrl': `http://localhost:${umaPort}/uma`, + 'urn:uma:variables:policyBaseIRI': `http://localhost:${cssPort}/`, + 'urn:uma:variables:policyDir': path.join(__dirname, '../../packages/uma/config/rules/odrl'), + 'urn:uma:variables:eyePath': 'eye', + } + ) as App; + + cssApp = await instantiateFromConfig( + 'urn:solid-server:default:App', + path.join(__dirname, '../../packages/css/config/default.json'), + { + ...getDefaultCssVariables(cssPort), + 'urn:solid-server:uma:variable:AuthorizationServer': `http://localhost:${umaPort}/`, + 'urn:solid-server:default:variable:seedConfig': path.join(__dirname, '../../packages/css/config/seed.json'), + }, + ) as App; + + await Promise.all([umaApp.start(), cssApp.start()]); + }); + + describe('creating a resource', (): void => { + let wwwAuthenticateHeader: string; + let ticket: string; + let tokenEndpoint: string; + let jsonResponse: { access_token: string, token_type: string }; + + it('RS: sends a WWW-Authenticate response when access is private.', async(): Promise => { + const noTokenResponse = await fetch(resource, { + method: "PUT", + body: 'some text' , + }); + + expect(noTokenResponse.status).toBe(401); + wwwAuthenticateHeader = noTokenResponse.headers.get("WWW-Authenticate"); + expect(typeof wwwAuthenticateHeader).toBe('string'); + }); + + it('AS: returns the token endpoint from the configuration.', async(): Promise => { + const parsedHeader = Object.fromEntries( + wwwAuthenticateHeader + .replace(/^UMA /,'') + .split(', ') + .map(param => param.split('=').map(s => s.replace(/"/g,''))) + ); + expect(typeof parsedHeader.as_uri).toBe('string'); + expect(typeof parsedHeader.ticket).toBe('string'); + ticket = parsedHeader.ticket; + + const configurationUrl = parsedHeader.as_uri + '/.well-known/uma2-configuration'; + const response = await fetch(configurationUrl); + expect(response.status).toBe(200); + const configuration = await response.json(); + expect(typeof configuration.token_endpoint).toBe('string'); + tokenEndpoint = configuration.token_endpoint; + }); + + it('AS: responds with a token when receiving the ticket.', async(): Promise => { + const claim_token = 'https://woslabbi.pod.knows.idlab.ugent.be/profile/card#me'; + + const content = { + grant_type: 'urn:ietf:params:oauth:grant-type:uma-ticket', + ticket, + claim_token: encodeURIComponent(claim_token), + claim_token_format: 'urn:solidlab:uma:claims:formats:webid', + }; + + const asRequestResponse = await fetch(tokenEndpoint, { + method: 'POST', + headers: { 'content-type': 'application/json' }, + body: JSON.stringify(content), + }); + + expect(asRequestResponse.status).toBe(200); + expect(asRequestResponse.headers.get('content-type')).toBe('application/json'); + jsonResponse = await asRequestResponse.json(); + expect(typeof jsonResponse.access_token).toBe('string'); + expect(jsonResponse.token_type).toBe('Bearer'); + const token = JSON.parse(Buffer.from(jsonResponse.access_token.split('.')[1], 'base64').toString()); + expect(Array.isArray(token.permissions)).toBe(true); + expect(token.permissions).toHaveLength(2); + expect(token.permissions).toContainEqual({ + resource_id: resource, + resource_scopes: [ 'urn:example:css:modes:append', 'urn:example:css:modes:create' ] + }); + expect(token.permissions).toContainEqual({ + resource_id: `http://localhost:${cssPort}/alice/other/`, + resource_scopes: [ 'urn:example:css:modes:create' ] + } + ); + }); + + it('RS: provides access when receiving a valid token.', async(): Promise => { + const response = await fetch(resource, { + method: "PUT", + headers: { 'Authorization': `${jsonResponse.token_type} ${jsonResponse.access_token}` }, + body: 'Some text ...' , + }); + + expect(response.status).toBe(201); + }); + }); + + describe('reading a resource', (): void => { + let wwwAuthenticateHeader: string; + let ticket: string; + let tokenEndpoint: string; + let jsonResponse: { access_token: string, token_type: string }; + + it('RS: sends a WWW-Authenticate response when access is private.', async(): Promise => { + const noTokenResponse = await fetch(resource); + + expect(noTokenResponse.status).toBe(401); + wwwAuthenticateHeader = noTokenResponse.headers.get("WWW-Authenticate"); + expect(typeof wwwAuthenticateHeader).toBe('string'); + }); + + it('AS: returns the token endpoint from the configuration.', async(): Promise => { + const parsedHeader = Object.fromEntries( + wwwAuthenticateHeader + .replace(/^UMA /,'') + .split(', ') + .map(param => param.split('=').map(s => s.replace(/"/g,''))) + ); + expect(typeof parsedHeader.as_uri).toBe('string'); + expect(typeof parsedHeader.ticket).toBe('string'); + ticket = parsedHeader.ticket; + + const configurationUrl = parsedHeader.as_uri + '/.well-known/uma2-configuration'; + const response = await fetch(configurationUrl); + expect(response.status).toBe(200); + const configuration = await response.json(); + expect(typeof configuration.token_endpoint).toBe('string'); + tokenEndpoint = configuration.token_endpoint; + }); + + it('AS: responds with a token when receiving the ticket.', async(): Promise => { + const claim_token = 'https://woslabbi.pod.knows.idlab.ugent.be/profile/card#me'; + + const content = { + grant_type: 'urn:ietf:params:oauth:grant-type:uma-ticket', + ticket, + claim_token: encodeURIComponent(claim_token), + claim_token_format: 'urn:solidlab:uma:claims:formats:webid', + }; + + const asRequestResponse = await fetch(tokenEndpoint, { + method: 'POST', + headers: { 'content-type': 'application/json' }, + body: JSON.stringify(content), + }); + + expect(asRequestResponse.status).toBe(200); + expect(asRequestResponse.headers.get('content-type')).toBe('application/json'); + jsonResponse = await asRequestResponse.json(); + expect(typeof jsonResponse.access_token).toBe('string'); + expect(jsonResponse.token_type).toBe('Bearer'); + const token = JSON.parse(Buffer.from(jsonResponse.access_token.split('.')[1], 'base64').toString()); + expect(Array.isArray(token.permissions)).toBe(true); + expect(token.permissions).toHaveLength(1); + expect(token.permissions).toContainEqual({ + resource_id: resource, + resource_scopes: [ 'urn:example:css:modes:read' ], + }); + }); + + it('RS: provides access when receiving a valid token.', async(): Promise => { + const response = await fetch(resource, { + headers: { 'Authorization': `${jsonResponse.token_type} ${jsonResponse.access_token}` }, + }); + + expect(response.status).toBe(200); + await expect(response.text()).resolves.toBe('Some text ...'); + }); + }); +}); diff --git a/test/util/ServerUtil.ts b/test/util/ServerUtil.ts new file mode 100644 index 00000000..f488d673 --- /dev/null +++ b/test/util/ServerUtil.ts @@ -0,0 +1,46 @@ +import { ComponentsManager, IModuleState } from 'componentsjs'; +import * as path from 'node:path'; + +let cachedModuleState: IModuleState; + +/** + * Returns a component instantiated from a Components.js configuration. + */ +export async function instantiateFromConfig( + componentUrl: string, + configPaths: string | string[], + variables?: Record, +): Promise { + // Initialize the Components.js loader + const mainModulePath = path.join(__dirname, '../../'); + const manager = await ComponentsManager.build({ + mainModulePath, + logLevel: 'error', + moduleState: cachedModuleState, + typeChecking: false, + }); + cachedModuleState = manager.moduleState; + + if (!Array.isArray(configPaths)) { + configPaths = [ configPaths ]; + } + + // Instantiate the component from the config(s) + for (const configPath of configPaths) { + await manager.configRegistry.register(configPath); + } + return manager.instantiate(componentUrl, { variables }); +} + +export function getDefaultCssVariables(port: number, baseUrl?: string): Record { + return { + 'urn:solid-server:default:variable:baseUrl': baseUrl ?? `http://localhost:${port}/`, + 'urn:solid-server:default:variable:port': port, + 'urn:solid-server:default:variable:socket': null, + 'urn:solid-server:default:variable:loggingLevel': 'off', + 'urn:solid-server:default:variable:showStackTrace': true, + 'urn:solid-server:default:variable:seedConfig': null, + 'urn:solid-server:default:variable:workers': 1, + 'urn:solid-server:default:variable:confirmMigration': false, + }; +} diff --git a/vitest.config.mts b/vitest.config.mts new file mode 100644 index 00000000..4a280afd --- /dev/null +++ b/vitest.config.mts @@ -0,0 +1,12 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + globals: true, + // TODO: prolly want to put integration tests in separate package/folder/something + // projects: [ 'packages/*' ], + include: [ '**/test/(unit|integration)/**/*.test.ts' ], + hookTimeout: 60000, + testTimeout: 60000, + }, +}); diff --git a/yarn.lock b/yarn.lock index e0b71c5b..395e78df 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12,17 +12,7 @@ __metadata: languageName: node linkType: hard -"@ampproject/remapping@npm:^2.2.0": - version: 2.2.1 - resolution: "@ampproject/remapping@npm:2.2.1" - dependencies: - "@jridgewell/gen-mapping": "npm:^0.3.0" - "@jridgewell/trace-mapping": "npm:^0.3.9" - checksum: 10c0/92ce5915f8901d8c7cd4f4e6e2fe7b9fd335a29955b400caa52e0e5b12ca3796ada7c2f10e78c9c5b0f9c2539dff0ffea7b19850a56e1487aa083531e1e46d43 - languageName: node - linkType: hard - -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.22.13, @babel/code-frame@npm:^7.23.4": +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.12.13": version: 7.23.4 resolution: "@babel/code-frame@npm:7.23.4" dependencies: @@ -32,143 +22,6 @@ __metadata: languageName: node linkType: hard -"@babel/compat-data@npm:^7.22.9": - version: 7.23.3 - resolution: "@babel/compat-data@npm:7.23.3" - checksum: 10c0/c6af331753c34ee8a5678bc94404320826cb56b1dda3efc1311ec8fb0774e78225132f3c1acc988440ace667f14a838e297a822692b95758aa63da406e1f97a1 - languageName: node - linkType: hard - -"@babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3": - version: 7.23.3 - resolution: "@babel/core@npm:7.23.3" - dependencies: - "@ampproject/remapping": "npm:^2.2.0" - "@babel/code-frame": "npm:^7.22.13" - "@babel/generator": "npm:^7.23.3" - "@babel/helper-compilation-targets": "npm:^7.22.15" - "@babel/helper-module-transforms": "npm:^7.23.3" - "@babel/helpers": "npm:^7.23.2" - "@babel/parser": "npm:^7.23.3" - "@babel/template": "npm:^7.22.15" - "@babel/traverse": "npm:^7.23.3" - "@babel/types": "npm:^7.23.3" - convert-source-map: "npm:^2.0.0" - debug: "npm:^4.1.0" - gensync: "npm:^1.0.0-beta.2" - json5: "npm:^2.2.3" - semver: "npm:^6.3.1" - checksum: 10c0/08d43b749e24052d12713a7fb1f0c0d1275d4fb056d00846faeb8da79ecf6d0ba91a11b6afec407b8b0f9388d00e2c2f485f282bef0ade4d6d0a17de191a4287 - languageName: node - linkType: hard - -"@babel/generator@npm:^7.23.3, @babel/generator@npm:^7.23.4, @babel/generator@npm:^7.7.2": - version: 7.23.4 - resolution: "@babel/generator@npm:7.23.4" - dependencies: - "@babel/types": "npm:^7.23.4" - "@jridgewell/gen-mapping": "npm:^0.3.2" - "@jridgewell/trace-mapping": "npm:^0.3.17" - jsesc: "npm:^2.5.1" - checksum: 10c0/79b87ef49c4af1b4356b2fcab80ed92dfcad7927c3d6d89c4f749fd947768de3ec129467fb8eee0fe53cf8fc38b4d34d44487f714a9c23bee981c9cba3a670e4 - languageName: node - linkType: hard - -"@babel/helper-compilation-targets@npm:^7.22.15": - version: 7.22.15 - resolution: "@babel/helper-compilation-targets@npm:7.22.15" - dependencies: - "@babel/compat-data": "npm:^7.22.9" - "@babel/helper-validator-option": "npm:^7.22.15" - browserslist: "npm:^4.21.9" - lru-cache: "npm:^5.1.1" - semver: "npm:^6.3.1" - checksum: 10c0/45b9286861296e890f674a3abb199efea14a962a27d9b8adeb44970a9fd5c54e73a9e342e8414d2851cf4f98d5994537352fbce7b05ade32e9849bbd327f9ff1 - languageName: node - linkType: hard - -"@babel/helper-environment-visitor@npm:^7.22.20": - version: 7.22.20 - resolution: "@babel/helper-environment-visitor@npm:7.22.20" - checksum: 10c0/e762c2d8f5d423af89bd7ae9abe35bd4836d2eb401af868a63bbb63220c513c783e25ef001019418560b3fdc6d9a6fb67e6c0b650bcdeb3a2ac44b5c3d2bdd94 - languageName: node - linkType: hard - -"@babel/helper-function-name@npm:^7.23.0": - version: 7.23.0 - resolution: "@babel/helper-function-name@npm:7.23.0" - dependencies: - "@babel/template": "npm:^7.22.15" - "@babel/types": "npm:^7.23.0" - checksum: 10c0/d771dd1f3222b120518176733c52b7cadac1c256ff49b1889dbbe5e3fed81db855b8cc4e40d949c9d3eae0e795e8229c1c8c24c0e83f27cfa6ee3766696c6428 - languageName: node - linkType: hard - -"@babel/helper-hoist-variables@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/helper-hoist-variables@npm:7.22.5" - dependencies: - "@babel/types": "npm:^7.22.5" - checksum: 10c0/60a3077f756a1cd9f14eb89f0037f487d81ede2b7cfe652ea6869cd4ec4c782b0fb1de01b8494b9a2d2050e3d154d7d5ad3be24806790acfb8cbe2073bf1e208 - languageName: node - linkType: hard - -"@babel/helper-module-imports@npm:^7.22.15": - version: 7.22.15 - resolution: "@babel/helper-module-imports@npm:7.22.15" - dependencies: - "@babel/types": "npm:^7.22.15" - checksum: 10c0/4e0d7fc36d02c1b8c8b3006dfbfeedf7a367d3334a04934255de5128115ea0bafdeb3e5736a2559917f0653e4e437400d54542da0468e08d3cbc86d3bbfa8f30 - languageName: node - linkType: hard - -"@babel/helper-module-transforms@npm:^7.23.3": - version: 7.23.3 - resolution: "@babel/helper-module-transforms@npm:7.23.3" - dependencies: - "@babel/helper-environment-visitor": "npm:^7.22.20" - "@babel/helper-module-imports": "npm:^7.22.15" - "@babel/helper-simple-access": "npm:^7.22.5" - "@babel/helper-split-export-declaration": "npm:^7.22.6" - "@babel/helper-validator-identifier": "npm:^7.22.20" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 10c0/211e1399d0c4993671e8e5c2b25383f08bee40004ace5404ed4065f0e9258cc85d99c1b82fd456c030ce5cfd4d8f310355b54ef35de9924eabfc3dff1331d946 - languageName: node - linkType: hard - -"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.8.0": - version: 7.22.5 - resolution: "@babel/helper-plugin-utils@npm:7.22.5" - checksum: 10c0/d2c4bfe2fa91058bcdee4f4e57a3f4933aed7af843acfd169cd6179fab8d13c1d636474ecabb2af107dc77462c7e893199aa26632bac1c6d7e025a17cbb9d20d - languageName: node - linkType: hard - -"@babel/helper-simple-access@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/helper-simple-access@npm:7.22.5" - dependencies: - "@babel/types": "npm:^7.22.5" - checksum: 10c0/f0cf81a30ba3d09a625fd50e5a9069e575c5b6719234e04ee74247057f8104beca89ed03e9217b6e9b0493434cedc18c5ecca4cea6244990836f1f893e140369 - languageName: node - linkType: hard - -"@babel/helper-split-export-declaration@npm:^7.22.6": - version: 7.22.6 - resolution: "@babel/helper-split-export-declaration@npm:7.22.6" - dependencies: - "@babel/types": "npm:^7.22.5" - checksum: 10c0/d83e4b623eaa9622c267d3c83583b72f3aac567dc393dda18e559d79187961cb29ae9c57b2664137fc3d19508370b12ec6a81d28af73a50e0846819cb21c6e44 - languageName: node - linkType: hard - -"@babel/helper-string-parser@npm:^7.23.4": - version: 7.23.4 - resolution: "@babel/helper-string-parser@npm:7.23.4" - checksum: 10c0/f348d5637ad70b6b54b026d6544bd9040f78d24e7ec245a0fc42293968181f6ae9879c22d89744730d246ce8ec53588f716f102addd4df8bbc79b73ea10004ac - languageName: node - linkType: hard - "@babel/helper-validator-identifier@npm:^7.22.20": version: 7.22.20 resolution: "@babel/helper-validator-identifier@npm:7.22.20" @@ -176,24 +29,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-validator-option@npm:^7.22.15": - version: 7.22.15 - resolution: "@babel/helper-validator-option@npm:7.22.15" - checksum: 10c0/e9661bf80ba18e2dd978217b350fb07298e57ac417f4f1ab9fa011505e20e4857f2c3b4b538473516a9dc03af5ce3a831e5ed973311c28326f4c330b6be981c2 - languageName: node - linkType: hard - -"@babel/helpers@npm:^7.23.2": - version: 7.23.4 - resolution: "@babel/helpers@npm:7.23.4" - dependencies: - "@babel/template": "npm:^7.22.15" - "@babel/traverse": "npm:^7.23.4" - "@babel/types": "npm:^7.23.4" - checksum: 10c0/6bb552b3de530f5eaae99f5410826b5877bae38ccd95cb5809c9a0cef99bcdb9f5db373309c1cf873f5d68927993515323985bac0ff1b811f2437f2e3ae994b8 - languageName: node - linkType: hard - "@babel/highlight@npm:^7.23.4": version: 7.23.4 resolution: "@babel/highlight@npm:7.23.4" @@ -205,225 +40,6 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.22.15, @babel/parser@npm:^7.23.3, @babel/parser@npm:^7.23.4": - version: 7.23.4 - resolution: "@babel/parser@npm:7.23.4" - bin: - parser: ./bin/babel-parser.js - checksum: 10c0/9115cd9c5855a6c7a8dd246938b1316dc1014ad36e01240c1e94ada63218ca39aa63d953d1bff8074a2737933448bc50736eb3da52ffc5c11a256c66d0accc2b - languageName: node - linkType: hard - -"@babel/plugin-syntax-async-generators@npm:^7.8.4": - version: 7.8.4 - resolution: "@babel/plugin-syntax-async-generators@npm:7.8.4" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.8.0" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/d13efb282838481348c71073b6be6245b35d4f2f964a8f71e4174f235009f929ef7613df25f8d2338e2d3e44bc4265a9f8638c6aaa136d7a61fe95985f9725c8 - languageName: node - linkType: hard - -"@babel/plugin-syntax-bigint@npm:^7.8.3": - version: 7.8.3 - resolution: "@babel/plugin-syntax-bigint@npm:7.8.3" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.8.0" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/686891b81af2bc74c39013655da368a480f17dd237bf9fbc32048e5865cb706d5a8f65438030da535b332b1d6b22feba336da8fa931f663b6b34e13147d12dde - languageName: node - linkType: hard - -"@babel/plugin-syntax-class-properties@npm:^7.8.3": - version: 7.12.13 - resolution: "@babel/plugin-syntax-class-properties@npm:7.12.13" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.12.13" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/95168fa186416195280b1264fb18afcdcdcea780b3515537b766cb90de6ce042d42dd6a204a39002f794ae5845b02afb0fd4861a3308a861204a55e68310a120 - languageName: node - linkType: hard - -"@babel/plugin-syntax-import-meta@npm:^7.8.3": - version: 7.10.4 - resolution: "@babel/plugin-syntax-import-meta@npm:7.10.4" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.10.4" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/0b08b5e4c3128523d8e346f8cfc86824f0da2697b1be12d71af50a31aff7a56ceb873ed28779121051475010c28d6146a6bfea8518b150b71eeb4e46190172ee - languageName: node - linkType: hard - -"@babel/plugin-syntax-json-strings@npm:^7.8.3": - version: 7.8.3 - resolution: "@babel/plugin-syntax-json-strings@npm:7.8.3" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.8.0" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/e98f31b2ec406c57757d115aac81d0336e8434101c224edd9a5c93cefa53faf63eacc69f3138960c8b25401315af03df37f68d316c151c4b933136716ed6906e - languageName: node - linkType: hard - -"@babel/plugin-syntax-jsx@npm:^7.7.2": - version: 7.23.3 - resolution: "@babel/plugin-syntax-jsx@npm:7.23.3" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/563bb7599b868773f1c7c1d441ecc9bc53aeb7832775da36752c926fc402a1fa5421505b39e724f71eb217c13e4b93117e081cac39723b0e11dac4c897f33c3e - languageName: node - linkType: hard - -"@babel/plugin-syntax-logical-assignment-operators@npm:^7.8.3": - version: 7.10.4 - resolution: "@babel/plugin-syntax-logical-assignment-operators@npm:7.10.4" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.10.4" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/2594cfbe29411ad5bc2ad4058de7b2f6a8c5b86eda525a993959438615479e59c012c14aec979e538d60a584a1a799b60d1b8942c3b18468cb9d99b8fd34cd0b - languageName: node - linkType: hard - -"@babel/plugin-syntax-nullish-coalescing-operator@npm:^7.8.3": - version: 7.8.3 - resolution: "@babel/plugin-syntax-nullish-coalescing-operator@npm:7.8.3" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.8.0" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/2024fbb1162899094cfc81152449b12bd0cc7053c6d4bda8ac2852545c87d0a851b1b72ed9560673cbf3ef6248257262c3c04aabf73117215c1b9cc7dd2542ce - languageName: node - linkType: hard - -"@babel/plugin-syntax-numeric-separator@npm:^7.8.3": - version: 7.10.4 - resolution: "@babel/plugin-syntax-numeric-separator@npm:7.10.4" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.10.4" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/c55a82b3113480942c6aa2fcbe976ff9caa74b7b1109ff4369641dfbc88d1da348aceb3c31b6ed311c84d1e7c479440b961906c735d0ab494f688bf2fd5b9bb9 - languageName: node - linkType: hard - -"@babel/plugin-syntax-object-rest-spread@npm:^7.8.3": - version: 7.8.3 - resolution: "@babel/plugin-syntax-object-rest-spread@npm:7.8.3" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.8.0" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/ee1eab52ea6437e3101a0a7018b0da698545230015fc8ab129d292980ec6dff94d265e9e90070e8ae5fed42f08f1622c14c94552c77bcac784b37f503a82ff26 - languageName: node - linkType: hard - -"@babel/plugin-syntax-optional-catch-binding@npm:^7.8.3": - version: 7.8.3 - resolution: "@babel/plugin-syntax-optional-catch-binding@npm:7.8.3" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.8.0" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/27e2493ab67a8ea6d693af1287f7e9acec206d1213ff107a928e85e173741e1d594196f99fec50e9dde404b09164f39dec5864c767212154ffe1caa6af0bc5af - languageName: node - linkType: hard - -"@babel/plugin-syntax-optional-chaining@npm:^7.8.3": - version: 7.8.3 - resolution: "@babel/plugin-syntax-optional-chaining@npm:7.8.3" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.8.0" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/46edddf2faa6ebf94147b8e8540dfc60a5ab718e2de4d01b2c0bdf250a4d642c2bd47cbcbb739febcb2bf75514dbcefad3c52208787994b8d0f8822490f55e81 - languageName: node - linkType: hard - -"@babel/plugin-syntax-top-level-await@npm:^7.8.3": - version: 7.14.5 - resolution: "@babel/plugin-syntax-top-level-await@npm:7.14.5" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.14.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/14bf6e65d5bc1231ffa9def5f0ef30b19b51c218fcecaa78cd1bdf7939dfdf23f90336080b7f5196916368e399934ce5d581492d8292b46a2fb569d8b2da106f - languageName: node - linkType: hard - -"@babel/plugin-syntax-typescript@npm:^7.7.2": - version: 7.23.3 - resolution: "@babel/plugin-syntax-typescript@npm:7.23.3" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.22.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/4d6e9cdb9d0bfb9bd9b220fc951d937fce2ca69135ec121153572cebe81d86abc9a489208d6b69ee5f10cadcaeffa10d0425340a5029e40e14a6025021b90948 - languageName: node - linkType: hard - -"@babel/runtime@npm:^7.21.0": - version: 7.24.1 - resolution: "@babel/runtime@npm:7.24.1" - dependencies: - regenerator-runtime: "npm:^0.14.0" - checksum: 10c0/500c6a99ddd84f37c7bc5dbc84777af47b1372b20e879941670451d55484faf18a673c5ebee9ca2b0f36208a729417873b35b1b92e76f811620f6adf7b8cb0f1 - languageName: node - linkType: hard - -"@babel/template@npm:^7.22.15, @babel/template@npm:^7.3.3": - version: 7.22.15 - resolution: "@babel/template@npm:7.22.15" - dependencies: - "@babel/code-frame": "npm:^7.22.13" - "@babel/parser": "npm:^7.22.15" - "@babel/types": "npm:^7.22.15" - checksum: 10c0/9312edd37cf1311d738907003f2aa321a88a42ba223c69209abe4d7111db019d321805504f606c7fd75f21c6cf9d24d0a8223104cd21ebd207e241b6c551f454 - languageName: node - linkType: hard - -"@babel/traverse@npm:^7.23.3, @babel/traverse@npm:^7.23.4": - version: 7.23.4 - resolution: "@babel/traverse@npm:7.23.4" - dependencies: - "@babel/code-frame": "npm:^7.23.4" - "@babel/generator": "npm:^7.23.4" - "@babel/helper-environment-visitor": "npm:^7.22.20" - "@babel/helper-function-name": "npm:^7.23.0" - "@babel/helper-hoist-variables": "npm:^7.22.5" - "@babel/helper-split-export-declaration": "npm:^7.22.6" - "@babel/parser": "npm:^7.23.4" - "@babel/types": "npm:^7.23.4" - debug: "npm:^4.1.0" - globals: "npm:^11.1.0" - checksum: 10c0/a423d2b90934efe4ed423d67d91d6aa33ad035d6a175420fa9715376720584b4e7a7002be4bf55b085b7e675b7aba8c615e01560d6d9c47341427e1fe8039c68 - languageName: node - linkType: hard - -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.23.3, @babel/types@npm:^7.23.4, @babel/types@npm:^7.3.3, @babel/types@npm:^7.8.3": - version: 7.23.4 - resolution: "@babel/types@npm:7.23.4" - dependencies: - "@babel/helper-string-parser": "npm:^7.23.4" - "@babel/helper-validator-identifier": "npm:^7.22.20" - to-fast-properties: "npm:^2.0.0" - checksum: 10c0/231954418e0d052a8e69c9d84dde31baffd91d38d99624d18f160e14aa32b094b9e3e91c9c065ea88ea80c6e1589b17bb8b843b950c20c112f32c17482f7cf1f - languageName: node - linkType: hard - -"@bcoe/v8-coverage@npm:^0.2.3": - version: 0.2.3 - resolution: "@bcoe/v8-coverage@npm:0.2.3" - checksum: 10c0/6b80ae4cb3db53f486da2dc63b6e190a74c8c3cca16bb2733f234a0b6a9382b09b146488ae08e2b22cf00f6c83e20f3e040a2f7894f05c045c946d6a090b1d52 - languageName: node - linkType: hard - "@bergos/jsonparse@npm:^1.4.0, @bergos/jsonparse@npm:^1.4.1": version: 1.4.1 resolution: "@bergos/jsonparse@npm:1.4.1" @@ -2878,7 +2494,7 @@ __metadata: languageName: node linkType: hard -"@comunica/query-sparql@npm:^2.10.2, @comunica/query-sparql@npm:^2.9.0": +"@comunica/query-sparql@npm:^2.9.0": version: 2.10.2 resolution: "@comunica/query-sparql@npm:2.10.2" dependencies: @@ -3082,49 +2698,6 @@ __metadata: languageName: node linkType: hard -"@digitalbazaar/credentials-context@npm:^3.1.0": - version: 3.1.0 - resolution: "@digitalbazaar/credentials-context@npm:3.1.0" - checksum: 10c0/0fa22d00542450b3e0567511779dafcd943bcba75a2be83fa80b95c1f255f1b2f701ea64a0ab3959c8503a9f1682f724de0ffe8f5eea18b065d5074d61e52cb7 - languageName: node - linkType: hard - -"@digitalbazaar/ed25519-multikey@npm:^1.1.0": - version: 1.3.0 - resolution: "@digitalbazaar/ed25519-multikey@npm:1.3.0" - dependencies: - "@noble/ed25519": "npm:^1.6.0" - base58-universal: "npm:^2.0.0" - base64url-universal: "npm:^2.0.0" - checksum: 10c0/07cf6ea5591a269fca5b9709481e249b20cf83145ab56c25c8b75f668739163af95eae6742b50b8575522075e0933242343564d14d661f5bcae70fade13726b5 - languageName: node - linkType: hard - -"@digitalbazaar/ed25519-signature-2020@npm:^5.4.0": - version: 5.4.0 - resolution: "@digitalbazaar/ed25519-signature-2020@npm:5.4.0" - dependencies: - "@digitalbazaar/ed25519-multikey": "npm:^1.1.0" - "@digitalbazaar/ed25519-verification-key-2020": "npm:^4.1.0" - base58-universal: "npm:^2.0.0" - ed25519-signature-2020-context: "npm:^1.1.0" - jsonld-signatures: "npm:^11.3.0" - checksum: 10c0/7fcdd54c18d85dbbf937464ff8f330876de336d2607c944981fa8e69bcc2df59a5181441d364c27e269d1a6d2028217ed3f662028634c57ab55e739c3af42c16 - languageName: node - linkType: hard - -"@digitalbazaar/ed25519-verification-key-2020@npm:^4.1.0, @digitalbazaar/ed25519-verification-key-2020@npm:^4.2.0": - version: 4.2.0 - resolution: "@digitalbazaar/ed25519-verification-key-2020@npm:4.2.0" - dependencies: - "@noble/ed25519": "npm:^1.6.0" - base58-universal: "npm:^2.0.0" - base64url-universal: "npm:^2.0.0" - crypto-ld: "npm:^7.0.0" - checksum: 10c0/386b4be965e10b0253c5fd620c4e386c2f57587937c9215ed0127c3f42016d32e99844cc5eabbddc41642ade31760539e67e97d69cfdb0df6b3beb58737b9a01 - languageName: node - linkType: hard - "@digitalbazaar/http-client@npm:^3.4.1": version: 3.4.1 resolution: "@digitalbazaar/http-client@npm:3.4.1" @@ -3136,144 +2709,6 @@ __metadata: languageName: node linkType: hard -"@digitalbazaar/security-context@npm:^1.0.0": - version: 1.0.1 - resolution: "@digitalbazaar/security-context@npm:1.0.1" - checksum: 10c0/6d1444002958454be5dd70cc6ba4d0df952f90162756d6320d88501ff44fc7d48dcb2aa3452b77e8941a9da4e4c7d050d3510827db93637ff469b92391c63324 - languageName: node - linkType: hard - -"@digitalbazaar/vc@npm:^7.1.0": - version: 7.1.0 - resolution: "@digitalbazaar/vc@npm:7.1.0" - dependencies: - "@digitalbazaar/credentials-context": "npm:^3.1.0" - ed25519-signature-2018-context: "npm:^1.1.0" - jsonld: "npm:^8.3.1" - jsonld-signatures: "npm:^11.2.1" - checksum: 10c0/4914cd7bfc2556512b7b1b78b7032180fcd8a966d365ecd62f0534da2347fa43b9023f2460f15fd9c8029088af8ecc81481603fe9cf953e40393a956338356bb - languageName: node - linkType: hard - -"@digitalcredentials/base58-universal@npm:^1.0.1": - version: 1.0.1 - resolution: "@digitalcredentials/base58-universal@npm:1.0.1" - checksum: 10c0/2f92d8e49fa56bf40d297c668d2da1581c8f8d10d0907565d42b5414c829f1b7506d7e68b3dca74497d8113011685fdb916924c2dbffcbf77d32a06b1eab43a1 - languageName: node - linkType: hard - -"@digitalcredentials/credentials-v2-context@npm:~0.0.1-beta.0": - version: 0.0.1-beta.0 - resolution: "@digitalcredentials/credentials-v2-context@npm:0.0.1-beta.0" - checksum: 10c0/4e51299fda24c8433994a8fba2c8ce707fc96d57469e4e6a0577130c7ce39bca975b9c3dba4c9aecefbcc9d42c2b754ca6b4e5b46274d3c4d9e16d3c0e1fddad - languageName: node - linkType: hard - -"@digitalcredentials/ed25519-signature-2020@npm:^6.0.0": - version: 6.0.0 - resolution: "@digitalcredentials/ed25519-signature-2020@npm:6.0.0" - dependencies: - "@digitalcredentials/base58-universal": "npm:^1.0.1" - "@digitalcredentials/ed25519-verification-key-2020": "npm:^3.1.1" - "@digitalcredentials/jsonld-signatures": "npm:^12.0.0" - ed25519-signature-2018-context: "npm:^1.1.0" - ed25519-signature-2020-context: "npm:^1.0.1" - checksum: 10c0/9a81cbfb7e222720b223df5cff50cf291e1cbc015fb39d2ce299cc4efac51eb6b0958d2ace52e5dd14e3398f9c9f49a1005cb177aca95d123836bafb43823094 - languageName: node - linkType: hard - -"@digitalcredentials/ed25519-verification-key-2020@npm:^3.1.1": - version: 3.2.2 - resolution: "@digitalcredentials/ed25519-verification-key-2020@npm:3.2.2" - dependencies: - "@digitalcredentials/base58-universal": "npm:^1.0.1" - "@stablelib/ed25519": "npm:^1.0.1" - base64url-universal: "npm:^1.1.0" - crypto-ld: "npm:^6.0.0" - checksum: 10c0/a421b2097025ce70da131ae41323d31e18049c71daae8f6c922b34d3fd4ee5c1a2a249c0cbd4c16ed37de7054f617eccecfeb94a8126fe264e72b35611c54d00 - languageName: node - linkType: hard - -"@digitalcredentials/ed25519-verification-key-2020@npm:^4.0.0": - version: 4.0.0 - resolution: "@digitalcredentials/ed25519-verification-key-2020@npm:4.0.0" - dependencies: - "@digitalcredentials/keypair": "npm:^1.0.5" - "@noble/ed25519": "npm:^1.7.1" - base-x: "npm:^4.0.0" - checksum: 10c0/43e73b4dd928e32edbd901d8efbf0d4e1c456fd9a6df5e2239a73f4d1ff9abdf9ab706860e2822b9bd9c0de5421d781124b25198473cffd44d499cbb67b5fc44 - languageName: node - linkType: hard - -"@digitalcredentials/http-client@npm:^5.0.1": - version: 5.0.4 - resolution: "@digitalcredentials/http-client@npm:5.0.4" - dependencies: - ky: "npm:^1.0.1" - undici: "npm:^6.6.2" - checksum: 10c0/5d0edf0207844ef913a0841ac3715813488c336f282c9c11ba3be0061093d1ce04299886b64a10936b95a6faa5a5ec87cc1b1a9694460c99ced859471eb410ce - languageName: node - linkType: hard - -"@digitalcredentials/jsonld-signatures@npm:^12.0.0": - version: 12.0.1 - resolution: "@digitalcredentials/jsonld-signatures@npm:12.0.1" - dependencies: - "@digitalbazaar/security-context": "npm:^1.0.0" - "@digitalcredentials/jsonld": "npm:^9.0.0" - fast-text-encoding: "npm:^1.0.3" - serialize-error: "npm:^8.0.1" - checksum: 10c0/436317dfd0628d6aa9c63df13935f73c2e835d21d6444ff12f5e139b1256949607b9aa88cedc7a8d69522bb83b4d2b1a4f5341046fa1d95d1b1a5a75ee12b21c - languageName: node - linkType: hard - -"@digitalcredentials/jsonld@npm:^9.0.0": - version: 9.0.0 - resolution: "@digitalcredentials/jsonld@npm:9.0.0" - dependencies: - "@digitalcredentials/http-client": "npm:^5.0.1" - canonicalize: "npm:^1.0.1" - lru-cache: "npm:^6.0.0" - rdf-canonize: "npm:^3.4.0" - checksum: 10c0/3d3929ff7cdffd249746052ab1bdf53047b59c9fb3d316f642461bd77183d443f48ebe49ceaaf7164bc175c11b5bbeee0c33b37e951311b83fe9abf8735c5ed5 - languageName: node - linkType: hard - -"@digitalcredentials/keypair@npm:^1.0.5": - version: 1.0.5 - resolution: "@digitalcredentials/keypair@npm:1.0.5" - checksum: 10c0/693fb83f5043c7c61c0be0317aa633d49fc82faee791b3354a9dc033e2f63b4fd1890e35958b3d3e6fa767ad4f6315e7a82d01c4c1f5c076ea18663a7e910318 - languageName: node - linkType: hard - -"@digitalcredentials/open-badges-context@npm:^2.1.0": - version: 2.1.0 - resolution: "@digitalcredentials/open-badges-context@npm:2.1.0" - checksum: 10c0/faa298b29f8dc4cc157078fea2131b778eeb7d5a622fbce05624040a1ebbb3fa8a1c992e6044c61e39723dcdf399d1b4893b82e005bb47fce326ce8c8f9c298c - languageName: node - linkType: hard - -"@digitalcredentials/vc-data-model@npm:^2.0.0": - version: 2.0.0 - resolution: "@digitalcredentials/vc-data-model@npm:2.0.0" - checksum: 10c0/a1f23b9517615bb57d88e406606361f90f8ee2ce7303ed45f77d10043719f8949f72d3fc5dce8aafdd01ed7bc35fb3e0067145c720d6ffe967a9a7986d7b0cad - languageName: node - linkType: hard - -"@digitalcredentials/vc@npm:^9.0.1": - version: 9.0.1 - resolution: "@digitalcredentials/vc@npm:9.0.1" - dependencies: - "@digitalcredentials/credentials-v2-context": "npm:~0.0.1-beta.0" - "@digitalcredentials/jsonld": "npm:^9.0.0" - "@digitalcredentials/jsonld-signatures": "npm:^12.0.0" - "@digitalcredentials/open-badges-context": "npm:^2.1.0" - credentials-context: "npm:^2.0.0" - ed25519-signature-2018-context: "npm:^1.1.0" - checksum: 10c0/0624f8bba05750b18ab4ddc5185145753c7bc6ecb4c6d20ce101057982b34db1c68be390bb16948cfc364efbf25b160cb48239c5cb6883262ef3e575360bef3e - languageName: node - linkType: hard - "@effect/schema@npm:0.75.5": version: 0.75.5 resolution: "@effect/schema@npm:0.75.5" @@ -3285,170 +2720,177 @@ __metadata: languageName: node linkType: hard -"@esbuild/aix-ppc64@npm:0.23.1": - version: 0.23.1 - resolution: "@esbuild/aix-ppc64@npm:0.23.1" +"@esbuild/aix-ppc64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/aix-ppc64@npm:0.25.5" conditions: os=aix & cpu=ppc64 languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.23.1": - version: 0.23.1 - resolution: "@esbuild/android-arm64@npm:0.23.1" +"@esbuild/android-arm64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/android-arm64@npm:0.25.5" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@esbuild/android-arm@npm:0.23.1": - version: 0.23.1 - resolution: "@esbuild/android-arm@npm:0.23.1" +"@esbuild/android-arm@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/android-arm@npm:0.25.5" conditions: os=android & cpu=arm languageName: node linkType: hard -"@esbuild/android-x64@npm:0.23.1": - version: 0.23.1 - resolution: "@esbuild/android-x64@npm:0.23.1" +"@esbuild/android-x64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/android-x64@npm:0.25.5" conditions: os=android & cpu=x64 languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.23.1": - version: 0.23.1 - resolution: "@esbuild/darwin-arm64@npm:0.23.1" +"@esbuild/darwin-arm64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/darwin-arm64@npm:0.25.5" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.23.1": - version: 0.23.1 - resolution: "@esbuild/darwin-x64@npm:0.23.1" +"@esbuild/darwin-x64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/darwin-x64@npm:0.25.5" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.23.1": - version: 0.23.1 - resolution: "@esbuild/freebsd-arm64@npm:0.23.1" +"@esbuild/freebsd-arm64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/freebsd-arm64@npm:0.25.5" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.23.1": - version: 0.23.1 - resolution: "@esbuild/freebsd-x64@npm:0.23.1" +"@esbuild/freebsd-x64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/freebsd-x64@npm:0.25.5" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.23.1": - version: 0.23.1 - resolution: "@esbuild/linux-arm64@npm:0.23.1" +"@esbuild/linux-arm64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/linux-arm64@npm:0.25.5" conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.23.1": - version: 0.23.1 - resolution: "@esbuild/linux-arm@npm:0.23.1" +"@esbuild/linux-arm@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/linux-arm@npm:0.25.5" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.23.1": - version: 0.23.1 - resolution: "@esbuild/linux-ia32@npm:0.23.1" +"@esbuild/linux-ia32@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/linux-ia32@npm:0.25.5" conditions: os=linux & cpu=ia32 languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.23.1": - version: 0.23.1 - resolution: "@esbuild/linux-loong64@npm:0.23.1" +"@esbuild/linux-loong64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/linux-loong64@npm:0.25.5" conditions: os=linux & cpu=loong64 languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.23.1": - version: 0.23.1 - resolution: "@esbuild/linux-mips64el@npm:0.23.1" +"@esbuild/linux-mips64el@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/linux-mips64el@npm:0.25.5" conditions: os=linux & cpu=mips64el languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.23.1": - version: 0.23.1 - resolution: "@esbuild/linux-ppc64@npm:0.23.1" +"@esbuild/linux-ppc64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/linux-ppc64@npm:0.25.5" conditions: os=linux & cpu=ppc64 languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.23.1": - version: 0.23.1 - resolution: "@esbuild/linux-riscv64@npm:0.23.1" +"@esbuild/linux-riscv64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/linux-riscv64@npm:0.25.5" conditions: os=linux & cpu=riscv64 languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.23.1": - version: 0.23.1 - resolution: "@esbuild/linux-s390x@npm:0.23.1" +"@esbuild/linux-s390x@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/linux-s390x@npm:0.25.5" conditions: os=linux & cpu=s390x languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.23.1": - version: 0.23.1 - resolution: "@esbuild/linux-x64@npm:0.23.1" +"@esbuild/linux-x64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/linux-x64@npm:0.25.5" conditions: os=linux & cpu=x64 languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.23.1": - version: 0.23.1 - resolution: "@esbuild/netbsd-x64@npm:0.23.1" +"@esbuild/netbsd-arm64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/netbsd-arm64@npm:0.25.5" + conditions: os=netbsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/netbsd-x64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/netbsd-x64@npm:0.25.5" conditions: os=netbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/openbsd-arm64@npm:0.23.1": - version: 0.23.1 - resolution: "@esbuild/openbsd-arm64@npm:0.23.1" +"@esbuild/openbsd-arm64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/openbsd-arm64@npm:0.25.5" conditions: os=openbsd & cpu=arm64 languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.23.1": - version: 0.23.1 - resolution: "@esbuild/openbsd-x64@npm:0.23.1" +"@esbuild/openbsd-x64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/openbsd-x64@npm:0.25.5" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.23.1": - version: 0.23.1 - resolution: "@esbuild/sunos-x64@npm:0.23.1" +"@esbuild/sunos-x64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/sunos-x64@npm:0.25.5" conditions: os=sunos & cpu=x64 languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.23.1": - version: 0.23.1 - resolution: "@esbuild/win32-arm64@npm:0.23.1" +"@esbuild/win32-arm64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/win32-arm64@npm:0.25.5" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.23.1": - version: 0.23.1 - resolution: "@esbuild/win32-ia32@npm:0.23.1" +"@esbuild/win32-ia32@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/win32-ia32@npm:0.25.5" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.23.1": - version: 0.23.1 - resolution: "@esbuild/win32-x64@npm:0.23.1" +"@esbuild/win32-x64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/win32-x64@npm:0.25.5" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -3549,39 +2991,9 @@ __metadata: languageName: node linkType: hard -"@inrupt/solid-client-authn-core@npm:^2.1.0": - version: 2.1.0 - resolution: "@inrupt/solid-client-authn-core@npm:2.1.0" - dependencies: - events: "npm:^3.3.0" - jose: "npm:^5.1.3" - uuid: "npm:^9.0.1" - checksum: 10c0/44290be694cdc076d39bd232d3d6a3d06cd9d3f963fb582f6e5a919befa4030597f1335f372d402a5a073ff788c1db08346bbd44af877d172f0d614eb41de2dc - languageName: node - linkType: hard - -"@inrupt/solid-client@npm:^2.0.1": - version: 2.0.1 - resolution: "@inrupt/solid-client@npm:2.0.1" - dependencies: - "@rdfjs/dataset": "npm:^1.1.1" - buffer: "npm:^6.0.3" - fsevents: "npm:^2.3.3" - http-link-header: "npm:^1.1.1" - jsonld-context-parser: "npm:^2.4.0" - jsonld-streaming-parser: "npm:^3.3.0" - n3: "npm:^1.17.2" - uuid: "npm:^9.0.1" - dependenciesMeta: - fsevents: - optional: true - checksum: 10c0/53ff9eaa1eae126dcef52562dbbcbf8d15db23b23d86575d203deaa071da89d2799507036a13f3e624e39a15e07f16c8415832042cc8a3136d31afbde6a247c0 - languageName: node - linkType: hard - -"@inrupt/universal-fetch@npm:^1.0.3": - version: 1.0.3 - resolution: "@inrupt/universal-fetch@npm:1.0.3" +"@inrupt/universal-fetch@npm:^1.0.3": + version: 1.0.3 + resolution: "@inrupt/universal-fetch@npm:1.0.3" dependencies: node-fetch: "npm:^2.6.7" undici: "npm:^5.19.1" @@ -3617,93 +3029,6 @@ __metadata: languageName: node linkType: hard -"@istanbuljs/load-nyc-config@npm:^1.0.0": - version: 1.1.0 - resolution: "@istanbuljs/load-nyc-config@npm:1.1.0" - dependencies: - camelcase: "npm:^5.3.1" - find-up: "npm:^4.1.0" - get-package-type: "npm:^0.1.0" - js-yaml: "npm:^3.13.1" - resolve-from: "npm:^5.0.0" - checksum: 10c0/dd2a8b094887da5a1a2339543a4933d06db2e63cbbc2e288eb6431bd832065df0c099d091b6a67436e71b7d6bf85f01ce7c15f9253b4cbebcc3b9a496165ba42 - languageName: node - linkType: hard - -"@istanbuljs/schema@npm:^0.1.2": - version: 0.1.3 - resolution: "@istanbuljs/schema@npm:0.1.3" - checksum: 10c0/61c5286771676c9ca3eb2bd8a7310a9c063fb6e0e9712225c8471c582d157392c88f5353581c8c9adbe0dff98892317d2fdfc56c3499aa42e0194405206a963a - languageName: node - linkType: hard - -"@jest/console@npm:^29.7.0": - version: 29.7.0 - resolution: "@jest/console@npm:29.7.0" - dependencies: - "@jest/types": "npm:^29.6.3" - "@types/node": "npm:*" - chalk: "npm:^4.0.0" - jest-message-util: "npm:^29.7.0" - jest-util: "npm:^29.7.0" - slash: "npm:^3.0.0" - checksum: 10c0/7be408781d0a6f657e969cbec13b540c329671819c2f57acfad0dae9dbfe2c9be859f38fe99b35dba9ff1536937dc6ddc69fdcd2794812fa3c647a1619797f6c - languageName: node - linkType: hard - -"@jest/core@npm:^29.7.0": - version: 29.7.0 - resolution: "@jest/core@npm:29.7.0" - dependencies: - "@jest/console": "npm:^29.7.0" - "@jest/reporters": "npm:^29.7.0" - "@jest/test-result": "npm:^29.7.0" - "@jest/transform": "npm:^29.7.0" - "@jest/types": "npm:^29.6.3" - "@types/node": "npm:*" - ansi-escapes: "npm:^4.2.1" - chalk: "npm:^4.0.0" - ci-info: "npm:^3.2.0" - exit: "npm:^0.1.2" - graceful-fs: "npm:^4.2.9" - jest-changed-files: "npm:^29.7.0" - jest-config: "npm:^29.7.0" - jest-haste-map: "npm:^29.7.0" - jest-message-util: "npm:^29.7.0" - jest-regex-util: "npm:^29.6.3" - jest-resolve: "npm:^29.7.0" - jest-resolve-dependencies: "npm:^29.7.0" - jest-runner: "npm:^29.7.0" - jest-runtime: "npm:^29.7.0" - jest-snapshot: "npm:^29.7.0" - jest-util: "npm:^29.7.0" - jest-validate: "npm:^29.7.0" - jest-watcher: "npm:^29.7.0" - micromatch: "npm:^4.0.4" - pretty-format: "npm:^29.7.0" - slash: "npm:^3.0.0" - strip-ansi: "npm:^6.0.0" - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - checksum: 10c0/934f7bf73190f029ac0f96662c85cd276ec460d407baf6b0dbaec2872e157db4d55a7ee0b1c43b18874602f662b37cb973dda469a4e6d88b4e4845b521adeeb2 - languageName: node - linkType: hard - -"@jest/environment@npm:^29.7.0": - version: 29.7.0 - resolution: "@jest/environment@npm:29.7.0" - dependencies: - "@jest/fake-timers": "npm:^29.7.0" - "@jest/types": "npm:^29.6.3" - "@types/node": "npm:*" - jest-mock: "npm:^29.7.0" - checksum: 10c0/c7b1b40c618f8baf4d00609022d2afa086d9c6acc706f303a70bb4b67275868f620ad2e1a9efc5edd418906157337cce50589a627a6400bbdf117d351b91ef86 - languageName: node - linkType: hard - "@jest/expect-utils@npm:^29.7.0": version: 29.7.0 resolution: "@jest/expect-utils@npm:29.7.0" @@ -3713,79 +3038,6 @@ __metadata: languageName: node linkType: hard -"@jest/expect@npm:^29.7.0": - version: 29.7.0 - resolution: "@jest/expect@npm:29.7.0" - dependencies: - expect: "npm:^29.7.0" - jest-snapshot: "npm:^29.7.0" - checksum: 10c0/b41f193fb697d3ced134349250aed6ccea075e48c4f803159db102b826a4e473397c68c31118259868fd69a5cba70e97e1c26d2c2ff716ca39dc73a2ccec037e - languageName: node - linkType: hard - -"@jest/fake-timers@npm:^29.7.0": - version: 29.7.0 - resolution: "@jest/fake-timers@npm:29.7.0" - dependencies: - "@jest/types": "npm:^29.6.3" - "@sinonjs/fake-timers": "npm:^10.0.2" - "@types/node": "npm:*" - jest-message-util: "npm:^29.7.0" - jest-mock: "npm:^29.7.0" - jest-util: "npm:^29.7.0" - checksum: 10c0/cf0a8bcda801b28dc2e2b2ba36302200ee8104a45ad7a21e6c234148932f826cb3bc57c8df3b7b815aeea0861d7b6ca6f0d4778f93b9219398ef28749e03595c - languageName: node - linkType: hard - -"@jest/globals@npm:^29.7.0": - version: 29.7.0 - resolution: "@jest/globals@npm:29.7.0" - dependencies: - "@jest/environment": "npm:^29.7.0" - "@jest/expect": "npm:^29.7.0" - "@jest/types": "npm:^29.6.3" - jest-mock: "npm:^29.7.0" - checksum: 10c0/a385c99396878fe6e4460c43bd7bb0a5cc52befb462cc6e7f2a3810f9e7bcce7cdeb51908fd530391ee452dc856c98baa2c5f5fa8a5b30b071d31ef7f6955cea - languageName: node - linkType: hard - -"@jest/reporters@npm:^29.7.0": - version: 29.7.0 - resolution: "@jest/reporters@npm:29.7.0" - dependencies: - "@bcoe/v8-coverage": "npm:^0.2.3" - "@jest/console": "npm:^29.7.0" - "@jest/test-result": "npm:^29.7.0" - "@jest/transform": "npm:^29.7.0" - "@jest/types": "npm:^29.6.3" - "@jridgewell/trace-mapping": "npm:^0.3.18" - "@types/node": "npm:*" - chalk: "npm:^4.0.0" - collect-v8-coverage: "npm:^1.0.0" - exit: "npm:^0.1.2" - glob: "npm:^7.1.3" - graceful-fs: "npm:^4.2.9" - istanbul-lib-coverage: "npm:^3.0.0" - istanbul-lib-instrument: "npm:^6.0.0" - istanbul-lib-report: "npm:^3.0.0" - istanbul-lib-source-maps: "npm:^4.0.0" - istanbul-reports: "npm:^3.1.3" - jest-message-util: "npm:^29.7.0" - jest-util: "npm:^29.7.0" - jest-worker: "npm:^29.7.0" - slash: "npm:^3.0.0" - string-length: "npm:^4.0.1" - strip-ansi: "npm:^6.0.0" - v8-to-istanbul: "npm:^9.0.1" - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - checksum: 10c0/a754402a799541c6e5aff2c8160562525e2a47e7d568f01ebfc4da66522de39cbb809bbb0a841c7052e4270d79214e70aec3c169e4eae42a03bc1a8a20cb9fa2 - languageName: node - linkType: hard - "@jest/schemas@npm:^29.6.3": version: 29.6.3 resolution: "@jest/schemas@npm:29.6.3" @@ -3795,64 +3047,6 @@ __metadata: languageName: node linkType: hard -"@jest/source-map@npm:^29.6.3": - version: 29.6.3 - resolution: "@jest/source-map@npm:29.6.3" - dependencies: - "@jridgewell/trace-mapping": "npm:^0.3.18" - callsites: "npm:^3.0.0" - graceful-fs: "npm:^4.2.9" - checksum: 10c0/a2f177081830a2e8ad3f2e29e20b63bd40bade294880b595acf2fc09ec74b6a9dd98f126a2baa2bf4941acd89b13a4ade5351b3885c224107083a0059b60a219 - languageName: node - linkType: hard - -"@jest/test-result@npm:^29.7.0": - version: 29.7.0 - resolution: "@jest/test-result@npm:29.7.0" - dependencies: - "@jest/console": "npm:^29.7.0" - "@jest/types": "npm:^29.6.3" - "@types/istanbul-lib-coverage": "npm:^2.0.0" - collect-v8-coverage: "npm:^1.0.0" - checksum: 10c0/7de54090e54a674ca173470b55dc1afdee994f2d70d185c80236003efd3fa2b753fff51ffcdda8e2890244c411fd2267529d42c4a50a8303755041ee493e6a04 - languageName: node - linkType: hard - -"@jest/test-sequencer@npm:^29.7.0": - version: 29.7.0 - resolution: "@jest/test-sequencer@npm:29.7.0" - dependencies: - "@jest/test-result": "npm:^29.7.0" - graceful-fs: "npm:^4.2.9" - jest-haste-map: "npm:^29.7.0" - slash: "npm:^3.0.0" - checksum: 10c0/593a8c4272797bb5628984486080cbf57aed09c7cfdc0a634e8c06c38c6bef329c46c0016e84555ee55d1cd1f381518cf1890990ff845524c1123720c8c1481b - languageName: node - linkType: hard - -"@jest/transform@npm:^29.7.0": - version: 29.7.0 - resolution: "@jest/transform@npm:29.7.0" - dependencies: - "@babel/core": "npm:^7.11.6" - "@jest/types": "npm:^29.6.3" - "@jridgewell/trace-mapping": "npm:^0.3.18" - babel-plugin-istanbul: "npm:^6.1.1" - chalk: "npm:^4.0.0" - convert-source-map: "npm:^2.0.0" - fast-json-stable-stringify: "npm:^2.1.0" - graceful-fs: "npm:^4.2.9" - jest-haste-map: "npm:^29.7.0" - jest-regex-util: "npm:^29.6.3" - jest-util: "npm:^29.7.0" - micromatch: "npm:^4.0.4" - pirates: "npm:^4.0.4" - slash: "npm:^3.0.0" - write-file-atomic: "npm:^4.0.2" - checksum: 10c0/7f4a7f73dcf45dfdf280c7aa283cbac7b6e5a904813c3a93ead7e55873761fc20d5c4f0191d2019004fac6f55f061c82eb3249c2901164ad80e362e7a7ede5a6 - languageName: node - linkType: hard - "@jest/types@npm:^29.6.3": version: 29.6.3 resolution: "@jest/types@npm:29.6.3" @@ -3880,35 +3074,17 @@ __metadata: languageName: node linkType: hard -"@jridgewell/gen-mapping@npm:^0.3.0, @jridgewell/gen-mapping@npm:^0.3.2": - version: 0.3.3 - resolution: "@jridgewell/gen-mapping@npm:0.3.3" - dependencies: - "@jridgewell/set-array": "npm:^1.0.1" - "@jridgewell/sourcemap-codec": "npm:^1.4.10" - "@jridgewell/trace-mapping": "npm:^0.3.9" - checksum: 10c0/376fc11cf5a967318ba3ddd9d8e91be528eab6af66810a713c49b0c3f8dc67e9949452c51c38ab1b19aa618fb5e8594da5a249977e26b1e7fea1ee5a1fcacc74 - languageName: node - linkType: hard - -"@jridgewell/resolve-uri@npm:^3.0.3, @jridgewell/resolve-uri@npm:^3.1.0": +"@jridgewell/resolve-uri@npm:^3.0.3": version: 3.1.1 resolution: "@jridgewell/resolve-uri@npm:3.1.1" checksum: 10c0/0dbc9e29bc640bbbdc5b9876d2859c69042bfcf1423c1e6421bcca53e826660bff4e41c7d4bcb8dbea696404231a6f902f76ba41835d049e20f2dd6cffb713bf languageName: node linkType: hard -"@jridgewell/set-array@npm:^1.0.1": - version: 1.1.2 - resolution: "@jridgewell/set-array@npm:1.1.2" - checksum: 10c0/bc7ab4c4c00470de4e7562ecac3c0c84f53e7ee8a711e546d67c47da7febe7c45cd67d4d84ee3c9b2c05ae8e872656cdded8a707a283d30bd54fbc65aef821ab - languageName: node - linkType: hard - -"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14": - version: 1.4.15 - resolution: "@jridgewell/sourcemap-codec@npm:1.4.15" - checksum: 10c0/0c6b5ae663087558039052a626d2d7ed5208da36cfd707dcc5cea4a07cfc918248403dcb5989a8f7afaf245ce0573b7cc6fd94c4a30453bd10e44d9363940ba5 +"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.5.0": + version: 1.5.0 + resolution: "@jridgewell/sourcemap-codec@npm:1.5.0" + checksum: 10c0/2eb864f276eb1096c3c11da3e9bb518f6d9fc0023c78344cdc037abadc725172c70314bdb360f2d4b7bffec7f5d657ce006816bc5d4ecb35e61b66132db00c18 languageName: node linkType: hard @@ -3922,16 +3098,6 @@ __metadata: languageName: node linkType: hard -"@jridgewell/trace-mapping@npm:^0.3.12, @jridgewell/trace-mapping@npm:^0.3.17, @jridgewell/trace-mapping@npm:^0.3.18, @jridgewell/trace-mapping@npm:^0.3.9": - version: 0.3.20 - resolution: "@jridgewell/trace-mapping@npm:0.3.20" - dependencies: - "@jridgewell/resolve-uri": "npm:^3.1.0" - "@jridgewell/sourcemap-codec": "npm:^1.4.14" - checksum: 10c0/0ea0b2675cf513ec44dc25605616a3c9b808b9832e74b5b63c44260d66b58558bba65764f81928fc1033ead911f8718dca1134049c3e7a93937faf436671df31 - languageName: node - linkType: hard - "@koa/cors@npm:^5.0.0": version: 5.0.0 resolution: "@koa/cors@npm:5.0.0" @@ -3977,13 +3143,6 @@ __metadata: languageName: node linkType: hard -"@noble/ed25519@npm:^1.6.0, @noble/ed25519@npm:^1.7.1": - version: 1.7.3 - resolution: "@noble/ed25519@npm:1.7.3" - checksum: 10c0/dc162c3be5ae5a3cc0e6aff8209c8d175f24bba22f2b473aa849e102471193c83664b06f0ba2b5e01e9aa1a67a44daf313f478adb9f38768408a8bcad6145a48 - languageName: node - linkType: hard - "@nodelib/fs.scandir@npm:2.1.5": version: 2.1.5 resolution: "@nodelib/fs.scandir@npm:2.1.5" @@ -4087,7 +3246,16 @@ __metadata: languageName: node linkType: hard -"@rdfjs/types@npm:*, @rdfjs/types@npm:>=1.0.1, @rdfjs/types@npm:^1.1.0": +"@rdfjs/types@npm:*, @rdfjs/types@npm:>=1.0.1, @rdfjs/types@npm:^2.0.0, @rdfjs/types@npm:^2.0.1": + version: 2.0.1 + resolution: "@rdfjs/types@npm:2.0.1" + dependencies: + "@types/node": "npm:*" + checksum: 10c0/81012b02e28737e15dfc27068664bbab7b989cc2ff82e0a6a341df492d9d97210b5e462d85bfb7882aa0ef5bf84e2c5e95647fb779b67b7b1910b1837d79c500 + languageName: node + linkType: hard + +"@rdfjs/types@npm:^1.1.0": version: 1.1.0 resolution: "@rdfjs/types@npm:1.1.0" dependencies: @@ -4096,12 +3264,143 @@ __metadata: languageName: node linkType: hard -"@rdfjs/types@npm:^2.0.0, @rdfjs/types@npm:^2.0.1": - version: 2.0.1 - resolution: "@rdfjs/types@npm:2.0.1" - dependencies: - "@types/node": "npm:*" - checksum: 10c0/81012b02e28737e15dfc27068664bbab7b989cc2ff82e0a6a341df492d9d97210b5e462d85bfb7882aa0ef5bf84e2c5e95647fb779b67b7b1910b1837d79c500 +"@rollup/rollup-android-arm-eabi@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.44.0" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@rollup/rollup-android-arm64@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-android-arm64@npm:4.44.0" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-darwin-arm64@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-darwin-arm64@npm:4.44.0" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-darwin-x64@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-darwin-x64@npm:4.44.0" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-freebsd-arm64@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-freebsd-arm64@npm:4.44.0" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-freebsd-x64@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-freebsd-x64@npm:4.44.0" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm-gnueabihf@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.44.0" + conditions: os=linux & cpu=arm & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm-musleabihf@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.44.0" + conditions: os=linux & cpu=arm & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm64-gnu@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.44.0" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm64-musl@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.44.0" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-loongarch64-gnu@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-linux-loongarch64-gnu@npm:4.44.0" + conditions: os=linux & cpu=loong64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-powerpc64le-gnu@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.44.0" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-riscv64-gnu@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.44.0" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-riscv64-musl@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.44.0" + conditions: os=linux & cpu=riscv64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-s390x-gnu@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.44.0" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-x64-gnu@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.44.0" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-x64-musl@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.44.0" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-win32-arm64-msvc@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.44.0" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-win32-ia32-msvc@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.44.0" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@rollup/rollup-win32-x64-msvc@npm:4.44.0": + version: 4.44.0 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.44.0" + conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -4135,24 +3434,6 @@ __metadata: languageName: node linkType: hard -"@sinonjs/commons@npm:^3.0.0": - version: 3.0.0 - resolution: "@sinonjs/commons@npm:3.0.0" - dependencies: - type-detect: "npm:4.0.8" - checksum: 10c0/1df9cd257942f4e4960dfb9fd339d9e97b6a3da135f3d5b8646562918e863809cb8e00268535f4f4723535d2097881c8fc03d545c414d8555183376cfc54ee84 - languageName: node - linkType: hard - -"@sinonjs/fake-timers@npm:^10.0.2": - version: 10.3.0 - resolution: "@sinonjs/fake-timers@npm:10.3.0" - dependencies: - "@sinonjs/commons": "npm:^3.0.0" - checksum: 10c0/2e2fb6cc57f227912814085b7b01fede050cd4746ea8d49a1e44d5a0e56a804663b0340ae2f11af7559ea9bf4d087a11f2f646197a660ea3cb04e19efc04aa63 - languageName: node - linkType: hard - "@smessie/readable-web-to-node-stream@npm:^3.0.3": version: 3.0.3 resolution: "@smessie/readable-web-to-node-stream@npm:3.0.3" @@ -4196,7 +3477,7 @@ __metadata: languageName: node linkType: hard -"@solid/community-server@npm:^7.0.3, @solid/community-server@npm:^7.1.7": +"@solid/community-server@npm:^7.1.7": version: 7.1.7 resolution: "@solid/community-server@npm:7.1.7" dependencies: @@ -4275,20 +3556,6 @@ __metadata: languageName: node linkType: hard -"@solidlab/derived-resources-component@npm:^1.0.2": - version: 1.0.2 - resolution: "@solidlab/derived-resources-component@npm:1.0.2" - dependencies: - "@comunica/query-sparql": "npm:^2.10.2" - "@rdfjs/types": "npm:^1.1.0" - "@solid/community-server": "npm:^7.0.3" - asynciterator: "npm:^3.8.1" - n3: "npm:^1.17.2" - uri-template-lite: "npm:^23.4.0" - checksum: 10c0/f57f57253cf9d8099ad3651eae09c7291b37911d08b28e76e8a011f0793619eaca46fa315ace36a0dc012da936ce528b130e7a55a6f31ddaa1d4e37c5cf4953f - languageName: node - linkType: hard - "@solidlab/ucp@workspace:^, @solidlab/ucp@workspace:packages/ucp": version: 0.0.0-use.local resolution: "@solidlab/ucp@workspace:packages/ucp" @@ -4307,7 +3574,6 @@ __metadata: resolution: "@solidlab/uma-css@workspace:packages/css" dependencies: "@solid/community-server": "npm:^7.1.7" - "@solidlab/derived-resources-component": "npm:^1.0.2" "@solidlab/uma": "workspace:^" "@types/n3": "npm:^1.16.4" componentsjs: "npm:^5.5.1" @@ -4331,11 +3597,9 @@ __metadata: get-jwks: "npm:^9.0.1" http-message-signatures: "npm:^1.0.4" jose: "npm:^5.2.2" - koreografeye: "npm:^0.4.8" logform: "npm:^2.6.0" n3: "npm:^1.17.2" odrl-evaluator: "npm:^0.3.0" - ts-node: "npm:^10.9.2" uri-template-lite: "npm:^23.4.0" winston: "npm:^3.11.0" languageName: unknown @@ -4347,99 +3611,23 @@ __metadata: dependencies: "@commitlint/cli": "npm:^16.1.0" "@commitlint/config-conventional": "npm:^16.0.0" - "@digitalbazaar/ed25519-signature-2020": "npm:^5.4.0" - "@digitalbazaar/ed25519-verification-key-2020": "npm:^4.2.0" - "@digitalbazaar/vc": "npm:^7.1.0" - "@digitalcredentials/ed25519-signature-2020": "npm:^6.0.0" - "@digitalcredentials/ed25519-verification-key-2020": "npm:^4.0.0" - "@digitalcredentials/vc": "npm:^9.0.1" - "@digitalcredentials/vc-data-model": "npm:^2.0.0" - "@inrupt/solid-client": "npm:^2.0.1" - "@inrupt/solid-client-authn-core": "npm:^2.1.0" - "@solidlab/ucp": "workspace:^" "@types/jest": "npm:^29.5.12" - "@types/node": "npm:^20.11.25" + "@types/node": "npm:^20.19.1" "@typescript-eslint/eslint-plugin": "npm:^5.12.1" "@typescript-eslint/parser": "npm:^5.12.1" chalk: "npm:^5.4.1" componentsjs-generator: "npm:^3.1.2" - concurrently: "npm:^8.2.2" eslint: "npm:^8.10.0" - jest: "npm:^29.7.0" jest-rdf: "npm:^1.8.1" - jsonld: "npm:^8.3.3" - koreografeye: "npm:^0.4.8" shx: "npm:^0.3.4" syncpack: "npm:^13.0.2" - ts-jest: "npm:^29.1.2" - ts-node: "npm:^10.9.2" tsx: "npm:^4.19.2" - typescript: "npm:^5.3.3" + typescript: "npm:^5.8.3" + vite: "npm:^6.3.5" + vitest: "npm:^3.2.3" languageName: unknown linkType: soft -"@stablelib/binary@npm:^1.0.1": - version: 1.0.1 - resolution: "@stablelib/binary@npm:1.0.1" - dependencies: - "@stablelib/int": "npm:^1.0.1" - checksum: 10c0/154cb558d8b7c20ca5dc2e38abca2a3716ce36429bf1b9c298939cea0929766ed954feb8a9c59245ac64c923d5d3466bb7d99f281debd3a9d561e1279b11cd35 - languageName: node - linkType: hard - -"@stablelib/ed25519@npm:^1.0.1": - version: 1.0.3 - resolution: "@stablelib/ed25519@npm:1.0.3" - dependencies: - "@stablelib/random": "npm:^1.0.2" - "@stablelib/sha512": "npm:^1.0.1" - "@stablelib/wipe": "npm:^1.0.1" - checksum: 10c0/b4a05e3c24dabd8a9e0b5bd72dea761bfb4b5c66404308e9f0529ef898e75d6f588234920762d5372cb920d9d47811250160109f02d04b6eed53835fb6916eb9 - languageName: node - linkType: hard - -"@stablelib/hash@npm:^1.0.1": - version: 1.0.1 - resolution: "@stablelib/hash@npm:1.0.1" - checksum: 10c0/58b5572a4067820b77a1606ed2d4a6dc4068c5475f68ba0918860a5f45adf60b33024a0cea9532dcd8b7345c53b3c9636a23723f5f8ae83e0c3648f91fb5b5cc - languageName: node - linkType: hard - -"@stablelib/int@npm:^1.0.1": - version: 1.0.1 - resolution: "@stablelib/int@npm:1.0.1" - checksum: 10c0/e1a6a7792fc2146d65de56e4ef42e8bc385dd5157eff27019b84476f564a1a6c43413235ed0e9f7c9bb8907dbdab24679467aeb10f44c92e6b944bcd864a7ee0 - languageName: node - linkType: hard - -"@stablelib/random@npm:^1.0.2": - version: 1.0.2 - resolution: "@stablelib/random@npm:1.0.2" - dependencies: - "@stablelib/binary": "npm:^1.0.1" - "@stablelib/wipe": "npm:^1.0.1" - checksum: 10c0/ebb217cfb76db97d98ec07bd7ce03a650fa194b91f0cb12382738161adff1830f405de0e9bad22bbc352422339ff85f531873b6a874c26ea9b59cfcc7ea787e0 - languageName: node - linkType: hard - -"@stablelib/sha512@npm:^1.0.1": - version: 1.0.1 - resolution: "@stablelib/sha512@npm:1.0.1" - dependencies: - "@stablelib/binary": "npm:^1.0.1" - "@stablelib/hash": "npm:^1.0.1" - "@stablelib/wipe": "npm:^1.0.1" - checksum: 10c0/84549070a383f4daf23d9065230eb81bc8f590c68bf5f7968f1b78901236b3bb387c14f63773dc6c3dc78e823b1c15470d2a04d398a2506391f466c16ba29b58 - languageName: node - linkType: hard - -"@stablelib/wipe@npm:^1.0.1": - version: 1.0.1 - resolution: "@stablelib/wipe@npm:1.0.1" - checksum: 10c0/c5a54f769c286a5b3ecff979471dfccd4311f2e84a959908e8c0e3aa4eed1364bd9707f7b69d1384b757e62cc295c221fa27286c7f782410eb8a690f30cfd796 - languageName: node - linkType: hard - "@szmarczak/http-timer@npm:^5.0.1": version: 5.0.1 resolution: "@szmarczak/http-timer@npm:5.0.1" @@ -4505,47 +3693,6 @@ __metadata: languageName: node linkType: hard -"@types/babel__core@npm:^7.1.14": - version: 7.20.5 - resolution: "@types/babel__core@npm:7.20.5" - dependencies: - "@babel/parser": "npm:^7.20.7" - "@babel/types": "npm:^7.20.7" - "@types/babel__generator": "npm:*" - "@types/babel__template": "npm:*" - "@types/babel__traverse": "npm:*" - checksum: 10c0/bdee3bb69951e833a4b811b8ee9356b69a61ed5b7a23e1a081ec9249769117fa83aaaf023bb06562a038eb5845155ff663e2d5c75dd95c1d5ccc91db012868ff - languageName: node - linkType: hard - -"@types/babel__generator@npm:*": - version: 7.6.7 - resolution: "@types/babel__generator@npm:7.6.7" - dependencies: - "@babel/types": "npm:^7.0.0" - checksum: 10c0/2427203864ef231857e102eeb32b731a419164863983119cdd4dac9f1503c2831eb4262d05ade95d4574aa410b94c16e54e36a616758452f685a34881f4596d9 - languageName: node - linkType: hard - -"@types/babel__template@npm:*": - version: 7.4.4 - resolution: "@types/babel__template@npm:7.4.4" - dependencies: - "@babel/parser": "npm:^7.1.0" - "@babel/types": "npm:^7.0.0" - checksum: 10c0/cc84f6c6ab1eab1427e90dd2b76ccee65ce940b778a9a67be2c8c39e1994e6f5bbc8efa309f6cea8dc6754994524cd4d2896558df76d92e7a1f46ecffee7112b - languageName: node - linkType: hard - -"@types/babel__traverse@npm:*, @types/babel__traverse@npm:^7.0.6": - version: 7.20.4 - resolution: "@types/babel__traverse@npm:7.20.4" - dependencies: - "@babel/types": "npm:^7.20.7" - checksum: 10c0/e76cb4974c7740fd61311152dc497e7b05c1c46ba554aab875544ab0a7457f343cafcad34ba8fb2ff543ab0e012ef2d3fa0c13f1a4e9a4cd9c4c703c7a2a8d62 - languageName: node - linkType: hard - "@types/bcryptjs@npm:^2.4.4": version: 2.4.6 resolution: "@types/bcryptjs@npm:2.4.6" @@ -4563,6 +3710,15 @@ __metadata: languageName: node linkType: hard +"@types/chai@npm:^5.2.2": + version: 5.2.2 + resolution: "@types/chai@npm:5.2.2" + dependencies: + "@types/deep-eql": "npm:*" + checksum: 10c0/49282bf0e8246800ebb36f17256f97bd3a8c4fb31f92ad3c0eaa7623518d7e87f1eaad4ad206960fcaf7175854bdff4cb167e4fe96811e0081b4ada83dd533ec + languageName: node + linkType: hard + "@types/clownface@npm:*": version: 2.0.5 resolution: "@types/clownface@npm:2.0.5" @@ -4616,6 +3772,13 @@ __metadata: languageName: node linkType: hard +"@types/deep-eql@npm:*": + version: 4.0.2 + resolution: "@types/deep-eql@npm:4.0.2" + checksum: 10c0/bf3f811843117900d7084b9d0c852da9a044d12eb40e6de73b552598a6843c21291a8a381b0532644574beecd5e3491c5ff3a0365ab86b15d59862c025384844 + languageName: node + linkType: hard + "@types/ejs@npm:^3.1.3": version: 3.1.5 resolution: "@types/ejs@npm:3.1.5" @@ -4639,6 +3802,13 @@ __metadata: languageName: node linkType: hard +"@types/estree@npm:1.0.8, @types/estree@npm:^1.0.0": + version: 1.0.8 + resolution: "@types/estree@npm:1.0.8" + checksum: 10c0/39d34d1afaa338ab9763f37ad6066e3f349444f9052b9676a7cc0252ef9485a41c6d81c9c4e0d26e9077993354edf25efc853f3224dd4b447175ef62bdcc86a5 + languageName: node + linkType: hard + "@types/express-serve-static-core@npm:^4.17.33": version: 4.17.41 resolution: "@types/express-serve-static-core@npm:4.17.41" @@ -4673,15 +3843,6 @@ __metadata: languageName: node linkType: hard -"@types/graceful-fs@npm:^4.1.3": - version: 4.1.9 - resolution: "@types/graceful-fs@npm:4.1.9" - dependencies: - "@types/node": "npm:*" - checksum: 10c0/235d2fc69741448e853333b7c3d1180a966dd2b8972c8cbcd6b2a0c6cd7f8d582ab2b8e58219dbc62cce8f1b40aa317ff78ea2201cdd8249da5025adebed6f0b - languageName: node - linkType: hard - "@types/http-assert@npm:*": version: 1.5.5 resolution: "@types/http-assert@npm:1.5.5" @@ -4712,7 +3873,7 @@ __metadata: languageName: node linkType: hard -"@types/istanbul-lib-coverage@npm:*, @types/istanbul-lib-coverage@npm:^2.0.0, @types/istanbul-lib-coverage@npm:^2.0.1": +"@types/istanbul-lib-coverage@npm:*, @types/istanbul-lib-coverage@npm:^2.0.0": version: 2.0.6 resolution: "@types/istanbul-lib-coverage@npm:2.0.6" checksum: 10c0/3948088654f3eeb45363f1db158354fb013b362dba2a5c2c18c559484d5eb9f6fd85b23d66c0a7c2fcfab7308d0a585b14dadaca6cc8bf89ebfdc7f8f5102fb7 @@ -4853,17 +4014,7 @@ __metadata: languageName: node linkType: hard -"@types/n3@npm:^1.10.4, @types/n3@npm:^1.16.3, @types/n3@npm:^1.16.4": - version: 1.16.4 - resolution: "@types/n3@npm:1.16.4" - dependencies: - "@rdfjs/types": "npm:^1.1.0" - "@types/node": "npm:*" - checksum: 10c0/34486916aca38ea90a40da5c2dba9326ed8e7784bf986fc3231976334a3fb2b7080e05a0f4f29780b33d81f7349b472c24561e8fbe0630e299dfda116bdb30c6 - languageName: node - linkType: hard - -"@types/n3@npm:^1.21.1": +"@types/n3@npm:^1.10.4, @types/n3@npm:^1.16.3, @types/n3@npm:^1.16.4, @types/n3@npm:^1.21.1": version: 1.24.2 resolution: "@types/n3@npm:1.24.2" dependencies: @@ -4873,12 +4024,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^20.11.25": - version: 20.17.17 - resolution: "@types/node@npm:20.17.17" +"@types/node@npm:^20.19.1": + version: 20.19.1 + resolution: "@types/node@npm:20.19.1" dependencies: - undici-types: "npm:~6.19.2" - checksum: 10c0/6aebc8053b96f1b6d82c3a3fe5fc20d9f7eeb507d79d967221bbecaa2b26665fa1c9efe460be2a2f4aaae4e98f37797df7d5a4189f2b6edf8abf9f82f7fd8b1f + undici-types: "npm:~6.21.0" + checksum: 10c0/4f1c3c8ec24c79af6802b376fa307904abf19accb9ac291de0bfc02220494c8b027d3ef733dbf64cc09b37594f22f679a15eabb30f3785bcfcc13bd9bbd8c0e2 languageName: node linkType: hard @@ -5221,6 +4372,89 @@ __metadata: languageName: node linkType: hard +"@vitest/expect@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/expect@npm:3.2.4" + dependencies: + "@types/chai": "npm:^5.2.2" + "@vitest/spy": "npm:3.2.4" + "@vitest/utils": "npm:3.2.4" + chai: "npm:^5.2.0" + tinyrainbow: "npm:^2.0.0" + checksum: 10c0/7586104e3fd31dbe1e6ecaafb9a70131e4197dce2940f727b6a84131eee3decac7b10f9c7c72fa5edbdb68b6f854353bd4c0fa84779e274207fb7379563b10db + languageName: node + linkType: hard + +"@vitest/mocker@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/mocker@npm:3.2.4" + dependencies: + "@vitest/spy": "npm:3.2.4" + estree-walker: "npm:^3.0.3" + magic-string: "npm:^0.30.17" + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + checksum: 10c0/f7a4aea19bbbf8f15905847ee9143b6298b2c110f8b64789224cb0ffdc2e96f9802876aa2ca83f1ec1b6e1ff45e822abb34f0054c24d57b29ab18add06536ccd + languageName: node + linkType: hard + +"@vitest/pretty-format@npm:3.2.4, @vitest/pretty-format@npm:^3.2.4": + version: 3.2.4 + resolution: "@vitest/pretty-format@npm:3.2.4" + dependencies: + tinyrainbow: "npm:^2.0.0" + checksum: 10c0/5ad7d4278e067390d7d633e307fee8103958806a419ca380aec0e33fae71b44a64415f7a9b4bc11635d3c13d4a9186111c581d3cef9c65cc317e68f077456887 + languageName: node + linkType: hard + +"@vitest/runner@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/runner@npm:3.2.4" + dependencies: + "@vitest/utils": "npm:3.2.4" + pathe: "npm:^2.0.3" + strip-literal: "npm:^3.0.0" + checksum: 10c0/e8be51666c72b3668ae3ea348b0196656a4a5adb836cb5e270720885d9517421815b0d6c98bfdf1795ed02b994b7bfb2b21566ee356a40021f5bf4f6ed4e418a + languageName: node + linkType: hard + +"@vitest/snapshot@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/snapshot@npm:3.2.4" + dependencies: + "@vitest/pretty-format": "npm:3.2.4" + magic-string: "npm:^0.30.17" + pathe: "npm:^2.0.3" + checksum: 10c0/f8301a3d7d1559fd3d59ed51176dd52e1ed5c2d23aa6d8d6aa18787ef46e295056bc726a021698d8454c16ed825ecba163362f42fa90258bb4a98cfd2c9424fc + languageName: node + linkType: hard + +"@vitest/spy@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/spy@npm:3.2.4" + dependencies: + tinyspy: "npm:^4.0.3" + checksum: 10c0/6ebf0b4697dc238476d6b6a60c76ba9eb1dd8167a307e30f08f64149612fd50227682b876420e4c2e09a76334e73f72e3ebf0e350714dc22474258292e202024 + languageName: node + linkType: hard + +"@vitest/utils@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/utils@npm:3.2.4" + dependencies: + "@vitest/pretty-format": "npm:3.2.4" + loupe: "npm:^3.1.4" + tinyrainbow: "npm:^2.0.0" + checksum: 10c0/024a9b8c8bcc12cf40183c246c244b52ecff861c6deb3477cbf487ac8781ad44c68a9c5fd69f8c1361878e55b97c10d99d511f2597f1f7244b5e5101d028ba64 + languageName: node + linkType: hard + "JSONStream@npm:^1.0.4": version: 1.3.5 resolution: "JSONStream@npm:1.3.5" @@ -5322,15 +4556,6 @@ __metadata: languageName: node linkType: hard -"ansi-escapes@npm:^4.2.1": - version: 4.3.2 - resolution: "ansi-escapes@npm:4.3.2" - dependencies: - type-fest: "npm:^0.21.3" - checksum: 10c0/da917be01871525a3dfcf925ae2977bc59e8c513d4423368645634bf5d4ceba5401574eb705c1e92b79f7292af5a656f78c5725a4b0e1cec97c4b413705c1d50 - languageName: node - linkType: hard - "ansi-regex@npm:^5.0.1": version: 5.0.1 resolution: "ansi-regex@npm:5.0.1" @@ -5377,16 +4602,6 @@ __metadata: languageName: node linkType: hard -"anymatch@npm:^3.0.3": - version: 3.1.3 - resolution: "anymatch@npm:3.1.3" - dependencies: - normalize-path: "npm:^3.0.0" - picomatch: "npm:^2.0.4" - checksum: 10c0/57b06ae984bc32a0d22592c87384cd88fe4511b1dd7581497831c56d41939c8a001b28e7b853e1450f2bf61992dfcaa8ae2d0d161a0a90c4fb631ef07098fbac - languageName: node - linkType: hard - "arg@npm:^4.1.0": version: 4.1.3 resolution: "arg@npm:4.1.3" @@ -5394,15 +4609,6 @@ __metadata: languageName: node linkType: hard -"argparse@npm:^1.0.7": - version: 1.0.10 - resolution: "argparse@npm:1.0.10" - dependencies: - sprintf-js: "npm:~1.0.2" - checksum: 10c0/b2972c5c23c63df66bca144dbc65d180efa74f25f8fd9b7d9a0a6c88ae839db32df3d54770dcb6460cf840d232b60695d1a6b1053f599d84e73f7437087712de - languageName: node - linkType: hard - "argparse@npm:^2.0.1": version: 2.0.1 resolution: "argparse@npm:2.0.1" @@ -5450,6 +4656,13 @@ __metadata: languageName: node linkType: hard +"assertion-error@npm:^2.0.1": + version: 2.0.1 + resolution: "assertion-error@npm:2.0.1" + checksum: 10c0/bbbcb117ac6480138f8c93cf7f535614282dea9dc828f540cdece85e3c665e8f78958b96afac52f29ff883c72638e6a87d469ecc9fe5bc902df03ed24a55dba8 + languageName: node + linkType: hard + "async-lock@npm:^1.4.0": version: 1.4.1 resolution: "async-lock@npm:1.4.1" @@ -5480,82 +4693,6 @@ __metadata: languageName: node linkType: hard -"babel-jest@npm:^29.7.0": - version: 29.7.0 - resolution: "babel-jest@npm:29.7.0" - dependencies: - "@jest/transform": "npm:^29.7.0" - "@types/babel__core": "npm:^7.1.14" - babel-plugin-istanbul: "npm:^6.1.1" - babel-preset-jest: "npm:^29.6.3" - chalk: "npm:^4.0.0" - graceful-fs: "npm:^4.2.9" - slash: "npm:^3.0.0" - peerDependencies: - "@babel/core": ^7.8.0 - checksum: 10c0/2eda9c1391e51936ca573dd1aedfee07b14c59b33dbe16ef347873ddd777bcf6e2fc739681e9e9661ab54ef84a3109a03725be2ac32cd2124c07ea4401cbe8c1 - languageName: node - linkType: hard - -"babel-plugin-istanbul@npm:^6.1.1": - version: 6.1.1 - resolution: "babel-plugin-istanbul@npm:6.1.1" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.0.0" - "@istanbuljs/load-nyc-config": "npm:^1.0.0" - "@istanbuljs/schema": "npm:^0.1.2" - istanbul-lib-instrument: "npm:^5.0.4" - test-exclude: "npm:^6.0.0" - checksum: 10c0/1075657feb705e00fd9463b329921856d3775d9867c5054b449317d39153f8fbcebd3e02ebf00432824e647faff3683a9ca0a941325ef1afe9b3c4dd51b24beb - languageName: node - linkType: hard - -"babel-plugin-jest-hoist@npm:^29.6.3": - version: 29.6.3 - resolution: "babel-plugin-jest-hoist@npm:29.6.3" - dependencies: - "@babel/template": "npm:^7.3.3" - "@babel/types": "npm:^7.3.3" - "@types/babel__core": "npm:^7.1.14" - "@types/babel__traverse": "npm:^7.0.6" - checksum: 10c0/7e6451caaf7dce33d010b8aafb970e62f1b0c0b57f4978c37b0d457bbcf0874d75a395a102daf0bae0bd14eafb9f6e9a165ee5e899c0a4f1f3bb2e07b304ed2e - languageName: node - linkType: hard - -"babel-preset-current-node-syntax@npm:^1.0.0": - version: 1.0.1 - resolution: "babel-preset-current-node-syntax@npm:1.0.1" - dependencies: - "@babel/plugin-syntax-async-generators": "npm:^7.8.4" - "@babel/plugin-syntax-bigint": "npm:^7.8.3" - "@babel/plugin-syntax-class-properties": "npm:^7.8.3" - "@babel/plugin-syntax-import-meta": "npm:^7.8.3" - "@babel/plugin-syntax-json-strings": "npm:^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators": "npm:^7.8.3" - "@babel/plugin-syntax-nullish-coalescing-operator": "npm:^7.8.3" - "@babel/plugin-syntax-numeric-separator": "npm:^7.8.3" - "@babel/plugin-syntax-object-rest-spread": "npm:^7.8.3" - "@babel/plugin-syntax-optional-catch-binding": "npm:^7.8.3" - "@babel/plugin-syntax-optional-chaining": "npm:^7.8.3" - "@babel/plugin-syntax-top-level-await": "npm:^7.8.3" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 10c0/5ba39a3a0e6c37d25e56a4fb843be632dac98d54706d8a0933f9bcb1a07987a96d55c2b5a6c11788a74063fb2534fe68c1f1dbb6c93626850c785e0938495627 - languageName: node - linkType: hard - -"babel-preset-jest@npm:^29.6.3": - version: 29.6.3 - resolution: "babel-preset-jest@npm:29.6.3" - dependencies: - babel-plugin-jest-hoist: "npm:^29.6.3" - babel-preset-current-node-syntax: "npm:^1.0.0" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 10c0/ec5fd0276b5630b05f0c14bb97cc3815c6b31600c683ebb51372e54dcb776cff790bdeeabd5b8d01ede375a040337ccbf6a3ccd68d3a34219125945e167ad943 - languageName: node - linkType: hard - "balanced-match@npm:^1.0.0": version: 1.0.2 resolution: "balanced-match@npm:1.0.2" @@ -5563,20 +4700,6 @@ __metadata: languageName: node linkType: hard -"base-x@npm:^4.0.0": - version: 4.0.0 - resolution: "base-x@npm:4.0.0" - checksum: 10c0/0cb47c94535144ab138f70bb5aa7e6e03049ead88615316b62457f110fc204f2c3baff5c64a1c1b33aeb068d79a68092c08a765c7ccfa133eee1e70e4c6eb903 - languageName: node - linkType: hard - -"base58-universal@npm:^2.0.0": - version: 2.0.0 - resolution: "base58-universal@npm:2.0.0" - checksum: 10c0/f21fd50904e1f2d083832e39269058ffbd95592ad27fc2acc53ad3d9d7eacfa82c4e655181e0fd8a817619f4c925a42baca877276dd73e755d30f52def748ab6 - languageName: node - linkType: hard - "base64-js@npm:^1.3.1": version: 1.5.1 resolution: "base64-js@npm:1.5.1" @@ -5584,31 +4707,6 @@ __metadata: languageName: node linkType: hard -"base64url-universal@npm:^1.1.0": - version: 1.1.0 - resolution: "base64url-universal@npm:1.1.0" - dependencies: - base64url: "npm:^3.0.0" - checksum: 10c0/d1408b3062c7a73cca75c6cc47eaefc47089ca20e019f5b6c3ab4641d7a87caec3e8e1fb17165b63380bef924f62f59dc7f257586490d5718c8c352f1dfc98e2 - languageName: node - linkType: hard - -"base64url-universal@npm:^2.0.0": - version: 2.0.0 - resolution: "base64url-universal@npm:2.0.0" - dependencies: - base64url: "npm:^3.0.1" - checksum: 10c0/6143326c1b5011d987d410a7451fcacad33af9282f9e7d06a21e1d4d7ed9d884e6c09a8f0d178f6c9ef3b11f8cda10ece4c84768e43dc9cb4dc47d1b5056de40 - languageName: node - linkType: hard - -"base64url@npm:^3.0.0, base64url@npm:^3.0.1": - version: 3.0.1 - resolution: "base64url@npm:3.0.1" - checksum: 10c0/5ca9d6064e9440a2a45749558dddd2549ca439a305793d4f14a900b7256b5f4438ef1b7a494e1addc66ced5d20f5c010716d353ed267e4b769e6c78074991241 - languageName: node - linkType: hard - "bcryptjs@npm:^2.4.3": version: 2.4.3 resolution: "bcryptjs@npm:2.4.3" @@ -5665,45 +4763,6 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:^4.21.9": - version: 4.22.1 - resolution: "browserslist@npm:4.22.1" - dependencies: - caniuse-lite: "npm:^1.0.30001541" - electron-to-chromium: "npm:^1.4.535" - node-releases: "npm:^2.0.13" - update-browserslist-db: "npm:^1.0.13" - bin: - browserslist: cli.js - checksum: 10c0/6810f2d63f171d0b7b8d38cf091708e00cb31525501810a507839607839320d66e657293b0aa3d7f051ecbc025cb07390a90c037682c1d05d12604991e41050b - languageName: node - linkType: hard - -"bs-logger@npm:0.x": - version: 0.2.6 - resolution: "bs-logger@npm:0.2.6" - dependencies: - fast-json-stable-stringify: "npm:2.x" - checksum: 10c0/80e89aaaed4b68e3374ce936f2eb097456a0dddbf11f75238dbd53140b1e39259f0d248a5089ed456f1158984f22191c3658d54a713982f676709fbe1a6fa5a0 - languageName: node - linkType: hard - -"bser@npm:2.1.1": - version: 2.1.1 - resolution: "bser@npm:2.1.1" - dependencies: - node-int64: "npm:^0.4.0" - checksum: 10c0/24d8dfb7b6d457d73f32744e678a60cc553e4ec0e9e1a01cf614b44d85c3c87e188d3cc78ef0442ce5032ee6818de20a0162ba1074725c0d08908f62ea979227 - languageName: node - linkType: hard - -"buffer-from@npm:^1.0.0": - version: 1.1.2 - resolution: "buffer-from@npm:1.1.2" - checksum: 10c0/124fff9d66d691a86d3b062eff4663fe437a9d9ee4b47b1b9e97f5a5d14f6d5399345db80f796827be7c95e70a8e765dd404b7c3ff3b3324f98e9b0c8826cc34 - languageName: node - linkType: hard - "buffer@npm:^6.0.3": version: 6.0.3 resolution: "buffer@npm:6.0.3" @@ -5721,6 +4780,13 @@ __metadata: languageName: node linkType: hard +"cac@npm:^6.7.14": + version: 6.7.14 + resolution: "cac@npm:6.7.14" + checksum: 10c0/4ee06aaa7bab8981f0d54e5f5f9d4adcd64058e9697563ce336d8a3878ed018ee18ebe5359b2430eceae87e0758e62ea2019c3f52ae6e211b1bd2e133856cd10 + languageName: node + linkType: hard + "cacache@npm:^18.0.0": version: 18.0.0 resolution: "cacache@npm:18.0.0" @@ -5798,20 +4864,6 @@ __metadata: languageName: node linkType: hard -"camelcase@npm:^6.2.0": - version: 6.3.0 - resolution: "camelcase@npm:6.3.0" - checksum: 10c0/0d701658219bd3116d12da3eab31acddb3f9440790c0792e0d398f0a520a6a4058018e546862b6fba89d7ae990efaeb97da71e1913e9ebf5a8b5621a3d55c710 - languageName: node - linkType: hard - -"caniuse-lite@npm:^1.0.30001541": - version: 1.0.30001563 - resolution: "caniuse-lite@npm:1.0.30001563" - checksum: 10c0/a8b367d43e0307ec243d8df8515d563fa3de895e9698eec4539037aed400da81e0df737164da2a6b7104ab6e75b4ea63db0adebcaabe326f2792841980259256 - languageName: node - linkType: hard - "canonicalize@npm:^1.0.1": version: 1.0.8 resolution: "canonicalize@npm:1.0.8" @@ -5826,6 +4878,19 @@ __metadata: languageName: node linkType: hard +"chai@npm:^5.2.0": + version: 5.2.0 + resolution: "chai@npm:5.2.0" + dependencies: + assertion-error: "npm:^2.0.1" + check-error: "npm:^2.1.1" + deep-eql: "npm:^5.0.1" + loupe: "npm:^3.1.0" + pathval: "npm:^2.0.0" + checksum: 10c0/dfd1cb719c7cebb051b727672d382a35338af1470065cb12adb01f4ee451bbf528e0e0f9ab2016af5fc1eea4df6e7f4504dc8443f8f00bd8fb87ad32dc516f7d + languageName: node + linkType: hard + "chalk-template@npm:1.1.0": version: 1.1.0 resolution: "chalk-template@npm:1.1.0" @@ -5853,7 +4918,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^4.0.0, chalk@npm:^4.0.2, chalk@npm:^4.1.2": +"chalk@npm:^4.0.0, chalk@npm:^4.0.2": version: 4.1.2 resolution: "chalk@npm:4.1.2" dependencies: @@ -5863,10 +4928,10 @@ __metadata: languageName: node linkType: hard -"char-regex@npm:^1.0.2": - version: 1.0.2 - resolution: "char-regex@npm:1.0.2" - checksum: 10c0/57a09a86371331e0be35d9083ba429e86c4f4648ecbe27455dbfb343037c16ee6fdc7f6b61f433a57cc5ded5561d71c56a150e018f40c2ffb7bc93a26dae341e +"check-error@npm:^2.1.1": + version: 2.1.1 + resolution: "check-error@npm:2.1.1" + checksum: 10c0/979f13eccab306cf1785fa10941a590b4e7ea9916ea2a4f8c87f0316fc3eab07eabefb6e587424ef0f88cbcd3805791f172ea739863ca3d7ce2afc54641c7f0e languageName: node linkType: hard @@ -5884,13 +4949,6 @@ __metadata: languageName: node linkType: hard -"cjs-module-lexer@npm:^1.0.0": - version: 1.2.3 - resolution: "cjs-module-lexer@npm:1.2.3" - checksum: 10c0/0de9a9c3fad03a46804c0d38e7b712fb282584a9c7ef1ed44cae22fb71d9bb600309d66a9711ac36a596fd03422f5bb03e021e8f369c12a39fa1786ae531baab - languageName: node - linkType: hard - "clean-stack@npm:^2.0.0": version: 2.2.0 resolution: "clean-stack@npm:2.2.0" @@ -5949,13 +5007,6 @@ __metadata: languageName: node linkType: hard -"collect-v8-coverage@npm:^1.0.0": - version: 1.0.2 - resolution: "collect-v8-coverage@npm:1.0.2" - checksum: 10c0/ed7008e2e8b6852c5483b444a3ae6e976e088d4335a85aa0a9db2861c5f1d31bd2d7ff97a60469b3388deeba661a619753afbe201279fb159b4b9548ab8269a1 - languageName: node - linkType: hard - "color-convert@npm:^1.9.0, color-convert@npm:^1.9.3": version: 1.9.3 resolution: "color-convert@npm:1.9.3" @@ -6100,26 +5151,6 @@ __metadata: languageName: node linkType: hard -"concurrently@npm:^8.2.2": - version: 8.2.2 - resolution: "concurrently@npm:8.2.2" - dependencies: - chalk: "npm:^4.1.2" - date-fns: "npm:^2.30.0" - lodash: "npm:^4.17.21" - rxjs: "npm:^7.8.1" - shell-quote: "npm:^1.8.1" - spawn-command: "npm:0.0.2" - supports-color: "npm:^8.1.1" - tree-kill: "npm:^1.2.2" - yargs: "npm:^17.7.2" - bin: - conc: dist/bin/concurrently.js - concurrently: dist/bin/concurrently.js - checksum: 10c0/0e9683196fe9c071d944345d21d8f34aa6c0cc50c0dd897e95619f2f1c9eb4871dca851b2569da17888235b7335b4c821ca19deed35bebcd9a131ee5d247f34c - languageName: node - linkType: hard - "content-disposition@npm:~0.5.2": version: 0.5.4 resolution: "content-disposition@npm:0.5.4" @@ -6173,13 +5204,6 @@ __metadata: languageName: node linkType: hard -"convert-source-map@npm:^2.0.0": - version: 2.0.0 - resolution: "convert-source-map@npm:2.0.0" - checksum: 10c0/8f2f7a27a1a011cc6cc88cc4da2d7d0cfa5ee0369508baae3d98c260bb3ac520691464e5bbe4ae7cdf09860c1d69ecc6f70c63c6e7c7f7e3f18ec08484dc7d9b - languageName: node - linkType: hard - "cookie@npm:^0.7.0": version: 0.7.2 resolution: "cookie@npm:0.7.2" @@ -6251,23 +5275,6 @@ __metadata: languageName: node linkType: hard -"create-jest@npm:^29.7.0": - version: 29.7.0 - resolution: "create-jest@npm:29.7.0" - dependencies: - "@jest/types": "npm:^29.6.3" - chalk: "npm:^4.0.0" - exit: "npm:^0.1.2" - graceful-fs: "npm:^4.2.9" - jest-config: "npm:^29.7.0" - jest-util: "npm:^29.7.0" - prompts: "npm:^2.0.1" - bin: - create-jest: bin/create-jest.js - checksum: 10c0/e7e54c280692470d3398f62a6238fd396327e01c6a0757002833f06d00afc62dd7bfe04ff2b9cd145264460e6b4d1eb8386f2925b7e567f97939843b7b0e812f - languageName: node - linkType: hard - "create-require@npm:^1.1.0": version: 1.1.1 resolution: "create-require@npm:1.1.1" @@ -6275,13 +5282,6 @@ __metadata: languageName: node linkType: hard -"credentials-context@npm:^2.0.0": - version: 2.0.0 - resolution: "credentials-context@npm:2.0.0" - checksum: 10c0/bdafba13fdbef62bb48402af6637e81b8f18ee380ea246ee2153a00842d8876e3b6aea0bf4526fd80346e6403d1b8cbc0bfe3c80e5813a29e5dc5bf4091374f7 - languageName: node - linkType: hard - "cross-fetch@npm:^3.0.6, cross-fetch@npm:^3.1.5": version: 3.1.8 resolution: "cross-fetch@npm:3.1.8" @@ -6311,20 +5311,6 @@ __metadata: languageName: node linkType: hard -"crypto-ld@npm:^6.0.0": - version: 6.0.0 - resolution: "crypto-ld@npm:6.0.0" - checksum: 10c0/af8bd8483bdf845d0b57e8e7ea30c7ba22f1b3a927dc683b267af663d9ec204ebc329525fd99ff212807e82140e89800c63e28ce56ed0e817a372507005af0a7 - languageName: node - linkType: hard - -"crypto-ld@npm:^7.0.0": - version: 7.0.0 - resolution: "crypto-ld@npm:7.0.0" - checksum: 10c0/67fac3bf5c52d71e02ae436a305f223376746cb43d2aa6550764d2885e15e8802267c8fd6a451c4255b90b58eeab1c036b6ee6e88f21425620a3d5ecc8b36d92 - languageName: node - linkType: hard - "dargs@npm:^7.0.0": version: 7.0.0 resolution: "dargs@npm:7.0.0" @@ -6339,15 +5325,6 @@ __metadata: languageName: node linkType: hard -"date-fns@npm:^2.30.0": - version: 2.30.0 - resolution: "date-fns@npm:2.30.0" - dependencies: - "@babel/runtime": "npm:^7.21.0" - checksum: 10c0/e4b521fbf22bc8c3db332bbfb7b094fd3e7627de0259a9d17c7551e2d2702608a7307a449206065916538e384f37b181565447ce2637ae09828427aed9cb5581 - languageName: node - linkType: hard - "date-format@npm:^4.0.14": version: 4.0.14 resolution: "date-format@npm:4.0.14" @@ -6355,15 +5332,15 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.2, debug@npm:^4.3.4": - version: 4.3.4 - resolution: "debug@npm:4.3.4" +"debug@npm:4, debug@npm:^4.1.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.4.1": + version: 4.4.1 + resolution: "debug@npm:4.4.1" dependencies: - ms: "npm:2.1.2" + ms: "npm:^2.1.3" peerDependenciesMeta: supports-color: optional: true - checksum: 10c0/cedbec45298dd5c501d01b92b119cd3faebe5438c3917ff11ae1bff86a6c722930ac9c8659792824013168ba6db7c4668225d845c633fbdafbbf902a6389f736 + checksum: 10c0/d2b44bc1afd912b49bb7ebb0d50a860dc93a4dd7d946e8de94abc957bb63726b7dd5aa48c18c2386c379ec024c46692e15ed3ed97d481729f929201e671fcd55 languageName: node linkType: hard @@ -6393,15 +5370,10 @@ __metadata: languageName: node linkType: hard -"dedent@npm:^1.0.0": - version: 1.5.1 - resolution: "dedent@npm:1.5.1" - peerDependencies: - babel-plugin-macros: ^3.1.0 - peerDependenciesMeta: - babel-plugin-macros: - optional: true - checksum: 10c0/f8612cd5b00aab58b18bb95572dca08dc2d49720bfa7201a444c3dae430291e8a06d4928614a6ec8764d713927f44bce9c990d3b8238fca2f430990ddc17c070 +"deep-eql@npm:^5.0.1": + version: 5.0.2 + resolution: "deep-eql@npm:5.0.2" + checksum: 10c0/7102cf3b7bb719c6b9c0db2e19bf0aa9318d141581befe8c7ce8ccd39af9eaa4346e5e05adef7f9bd7015da0f13a3a25dcfe306ef79dc8668aedbecb658dd247 languageName: node linkType: hard @@ -6419,13 +5391,6 @@ __metadata: languageName: node linkType: hard -"deepmerge@npm:^4.2.2": - version: 4.3.1 - resolution: "deepmerge@npm:4.3.1" - checksum: 10c0/e53481aaf1aa2c4082b5342be6b6d8ad9dfe387bc92ce197a66dea08bd4265904a087e75e464f14d1347cf2ac8afe1e4c16b266e0561cc5df29382d3c5f80044 - languageName: node - linkType: hard - "defer-to-connect@npm:^2.0.1": version: 2.0.1 resolution: "defer-to-connect@npm:2.0.1" @@ -6468,13 +5433,6 @@ __metadata: languageName: node linkType: hard -"detect-newline@npm:^3.0.0": - version: 3.1.0 - resolution: "detect-newline@npm:3.1.0" - checksum: 10c0/c38cfc8eeb9fda09febb44bcd85e467c970d4e3bf526095394e5a4f18bc26dd0cf6b22c69c1fa9969261521c593836db335c2795218f6d781a512aea2fb8209d - languageName: node - linkType: hard - "diff-sequences@npm:^29.6.3": version: 29.6.3 resolution: "diff-sequences@npm:29.6.3" @@ -6561,20 +5519,6 @@ __metadata: languageName: node linkType: hard -"ed25519-signature-2018-context@npm:^1.1.0": - version: 1.1.0 - resolution: "ed25519-signature-2018-context@npm:1.1.0" - checksum: 10c0/c0fb62dd448de59f9cb45ac55f026b793b8da9c0dbe83014d0ddf73d50ea78e37e6bf88b9445f2301a6ead3a42031ef5839f625e3186169d07897e19a056de7c - languageName: node - linkType: hard - -"ed25519-signature-2020-context@npm:^1.0.1, ed25519-signature-2020-context@npm:^1.1.0": - version: 1.1.0 - resolution: "ed25519-signature-2020-context@npm:1.1.0" - checksum: 10c0/7e5fba0ad8c1979412c45439654c0e1ac05372305760ad7c53e6b8d9a8106ed2f109e57ef19a7f0b23ea0efd69fee9c045d38280d18be11ef3dd68a433e55c46 - languageName: node - linkType: hard - "ee-first@npm:1.1.1": version: 1.1.1 resolution: "ee-first@npm:1.1.1" @@ -6602,13 +5546,6 @@ __metadata: languageName: node linkType: hard -"electron-to-chromium@npm:^1.4.535": - version: 1.4.589 - resolution: "electron-to-chromium@npm:1.4.589" - checksum: 10c0/6d632d8367c7fae10d4ba68bc255305b676c2f5924035f29a6e6ea818a1f1e92d0aee3ac210ad097e7de0fcd248f932c12638c1e458144de9340c5889cad2ceb - languageName: node - linkType: hard - "elliptic@npm:^6.5.4": version: 6.5.5 resolution: "elliptic@npm:6.5.5" @@ -6624,13 +5561,6 @@ __metadata: languageName: node linkType: hard -"emittery@npm:^0.13.1": - version: 0.13.1 - resolution: "emittery@npm:0.13.1" - checksum: 10c0/1573d0ae29ab34661b6c63251ff8f5facd24ccf6a823f19417ae8ba8c88ea450325788c67f16c99edec8de4b52ce93a10fe441ece389fd156e88ee7dab9bfa35 - languageName: node - linkType: hard - "emoji-regex@npm:^10.3.0": version: 10.4.0 resolution: "emoji-regex@npm:10.4.0" @@ -6724,34 +5654,42 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:~0.23.0": - version: 0.23.1 - resolution: "esbuild@npm:0.23.1" - dependencies: - "@esbuild/aix-ppc64": "npm:0.23.1" - "@esbuild/android-arm": "npm:0.23.1" - "@esbuild/android-arm64": "npm:0.23.1" - "@esbuild/android-x64": "npm:0.23.1" - "@esbuild/darwin-arm64": "npm:0.23.1" - "@esbuild/darwin-x64": "npm:0.23.1" - "@esbuild/freebsd-arm64": "npm:0.23.1" - "@esbuild/freebsd-x64": "npm:0.23.1" - "@esbuild/linux-arm": "npm:0.23.1" - "@esbuild/linux-arm64": "npm:0.23.1" - "@esbuild/linux-ia32": "npm:0.23.1" - "@esbuild/linux-loong64": "npm:0.23.1" - "@esbuild/linux-mips64el": "npm:0.23.1" - "@esbuild/linux-ppc64": "npm:0.23.1" - "@esbuild/linux-riscv64": "npm:0.23.1" - "@esbuild/linux-s390x": "npm:0.23.1" - "@esbuild/linux-x64": "npm:0.23.1" - "@esbuild/netbsd-x64": "npm:0.23.1" - "@esbuild/openbsd-arm64": "npm:0.23.1" - "@esbuild/openbsd-x64": "npm:0.23.1" - "@esbuild/sunos-x64": "npm:0.23.1" - "@esbuild/win32-arm64": "npm:0.23.1" - "@esbuild/win32-ia32": "npm:0.23.1" - "@esbuild/win32-x64": "npm:0.23.1" +"es-module-lexer@npm:^1.7.0": + version: 1.7.0 + resolution: "es-module-lexer@npm:1.7.0" + checksum: 10c0/4c935affcbfeba7fb4533e1da10fa8568043df1e3574b869385980de9e2d475ddc36769891936dbb07036edb3c3786a8b78ccf44964cd130dedc1f2c984b6c7b + languageName: node + linkType: hard + +"esbuild@npm:^0.25.0, esbuild@npm:~0.25.0": + version: 0.25.5 + resolution: "esbuild@npm:0.25.5" + dependencies: + "@esbuild/aix-ppc64": "npm:0.25.5" + "@esbuild/android-arm": "npm:0.25.5" + "@esbuild/android-arm64": "npm:0.25.5" + "@esbuild/android-x64": "npm:0.25.5" + "@esbuild/darwin-arm64": "npm:0.25.5" + "@esbuild/darwin-x64": "npm:0.25.5" + "@esbuild/freebsd-arm64": "npm:0.25.5" + "@esbuild/freebsd-x64": "npm:0.25.5" + "@esbuild/linux-arm": "npm:0.25.5" + "@esbuild/linux-arm64": "npm:0.25.5" + "@esbuild/linux-ia32": "npm:0.25.5" + "@esbuild/linux-loong64": "npm:0.25.5" + "@esbuild/linux-mips64el": "npm:0.25.5" + "@esbuild/linux-ppc64": "npm:0.25.5" + "@esbuild/linux-riscv64": "npm:0.25.5" + "@esbuild/linux-s390x": "npm:0.25.5" + "@esbuild/linux-x64": "npm:0.25.5" + "@esbuild/netbsd-arm64": "npm:0.25.5" + "@esbuild/netbsd-x64": "npm:0.25.5" + "@esbuild/openbsd-arm64": "npm:0.25.5" + "@esbuild/openbsd-x64": "npm:0.25.5" + "@esbuild/sunos-x64": "npm:0.25.5" + "@esbuild/win32-arm64": "npm:0.25.5" + "@esbuild/win32-ia32": "npm:0.25.5" + "@esbuild/win32-x64": "npm:0.25.5" dependenciesMeta: "@esbuild/aix-ppc64": optional: true @@ -6787,6 +5725,8 @@ __metadata: optional: true "@esbuild/linux-x64": optional: true + "@esbuild/netbsd-arm64": + optional: true "@esbuild/netbsd-x64": optional: true "@esbuild/openbsd-arm64": @@ -6803,7 +5743,7 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 10c0/08c2ed1105cc3c5e3a24a771e35532fe6089dd24a39c10097899072cef4a99f20860e41e9294e000d86380f353b04d8c50af482483d7f69f5208481cce61eec7 + checksum: 10c0/aba8cbc11927fa77562722ed5e95541ce2853f67ad7bdc40382b558abc2e0ec57d92ffb820f082ba2047b4ef9f3bc3da068cdebe30dfd3850cfa3827a78d604e languageName: node linkType: hard @@ -6935,16 +5875,6 @@ __metadata: languageName: node linkType: hard -"esprima@npm:^4.0.0": - version: 4.0.1 - resolution: "esprima@npm:4.0.1" - bin: - esparse: ./bin/esparse.js - esvalidate: ./bin/esvalidate.js - checksum: 10c0/ad4bab9ead0808cf56501750fd9d3fb276f6b105f987707d059005d57e182d18a7c9ec7f3a01794ebddcca676773e42ca48a32d67a250c9d35e009ca613caba3 - languageName: node - linkType: hard - "esquery@npm:^1.4.2": version: 1.5.0 resolution: "esquery@npm:1.5.0" @@ -6977,6 +5907,15 @@ __metadata: languageName: node linkType: hard +"estree-walker@npm:^3.0.3": + version: 3.0.3 + resolution: "estree-walker@npm:3.0.3" + dependencies: + "@types/estree": "npm:^1.0.0" + checksum: 10c0/c12e3c2b2642d2bcae7d5aa495c60fa2f299160946535763969a1c83fc74518ffa9c2cd3a8b69ac56aea547df6a8aac25f729a342992ef0bbac5f1c73e78995d + languageName: node + linkType: hard + "esutils@npm:^2.0.2": version: 2.0.3 resolution: "esutils@npm:2.0.3" @@ -7022,14 +5961,14 @@ __metadata: languageName: node linkType: hard -"exit@npm:^0.1.2": - version: 0.1.2 - resolution: "exit@npm:0.1.2" - checksum: 10c0/71d2ad9b36bc25bb8b104b17e830b40a08989be7f7d100b13269aaae7c3784c3e6e1e88a797e9e87523993a25ba27c8958959a554535370672cfb4d824af8989 +"expect-type@npm:^1.2.1": + version: 1.2.1 + resolution: "expect-type@npm:1.2.1" + checksum: 10c0/b775c9adab3c190dd0d398c722531726cdd6022849b4adba19dceab58dda7e000a7c6c872408cd73d665baa20d381eca36af4f7b393a4ba60dd10232d1fb8898 languageName: node linkType: hard -"expect@npm:^29.0.0, expect@npm:^29.7.0": +"expect@npm:^29.0.0": version: 29.7.0 resolution: "expect@npm:29.7.0" dependencies: @@ -7106,7 +6045,7 @@ __metadata: languageName: node linkType: hard -"fast-json-stable-stringify@npm:2.x, fast-json-stable-stringify@npm:^2.0.0, fast-json-stable-stringify@npm:^2.1.0": +"fast-json-stable-stringify@npm:^2.0.0": version: 2.1.0 resolution: "fast-json-stable-stringify@npm:2.1.0" checksum: 10c0/7f081eb0b8a64e0057b3bb03f974b3ef00135fbf36c1c710895cd9300f13c94ba809bb3a81cf4e1b03f6e5285610a61abbd7602d0652de423144dfee5a389c9b @@ -7120,13 +6059,6 @@ __metadata: languageName: node linkType: hard -"fast-text-encoding@npm:^1.0.3": - version: 1.0.6 - resolution: "fast-text-encoding@npm:1.0.6" - checksum: 10c0/e1d0381bda229c92c7906f63308f3b9caca8c78b732768b1ee16f560089ed21bc159bbe1434138ccd3815931ec8d4785bdade1ad1c45accfdf27ac6606ac67d2 - languageName: node - linkType: hard - "fastq@npm:^1.6.0": version: 1.15.0 resolution: "fastq@npm:1.15.0" @@ -7136,12 +6068,15 @@ __metadata: languageName: node linkType: hard -"fb-watchman@npm:^2.0.0": - version: 2.0.2 - resolution: "fb-watchman@npm:2.0.2" - dependencies: - bser: "npm:2.1.1" - checksum: 10c0/feae89ac148adb8f6ae8ccd87632e62b13563e6fb114cacb5265c51f585b17e2e268084519fb2edd133872f1d47a18e6bfd7e5e08625c0d41b93149694187581 +"fdir@npm:^6.4.4": + version: 6.4.6 + resolution: "fdir@npm:6.4.6" + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + checksum: 10c0/45b559cff889934ebb8bc498351e5acba40750ada7e7d6bde197768d2fa67c149be8ae7f8ff34d03f4e1eb20f2764116e56440aaa2f6689e9a4aa7ef06acafe9 languageName: node linkType: hard @@ -7220,7 +6155,7 @@ __metadata: languageName: node linkType: hard -"find-up@npm:^4.0.0, find-up@npm:^4.1.0": +"find-up@npm:^4.1.0": version: 4.1.0 resolution: "find-up@npm:4.1.0" dependencies: @@ -7356,7 +6291,7 @@ __metadata: languageName: node linkType: hard -"fsevents@npm:^2.3.2, fsevents@npm:^2.3.3, fsevents@npm:~2.3.3": +"fsevents@npm:^2.3.2, fsevents@npm:~2.3.2, fsevents@npm:~2.3.3": version: 2.3.3 resolution: "fsevents@npm:2.3.3" dependencies: @@ -7366,7 +6301,7 @@ __metadata: languageName: node linkType: hard -"fsevents@patch:fsevents@npm%3A^2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A^2.3.3#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.3#optional!builtin": +"fsevents@patch:fsevents@npm%3A^2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.3#optional!builtin": version: 2.3.3 resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1" dependencies: @@ -7382,13 +6317,6 @@ __metadata: languageName: node linkType: hard -"gensync@npm:^1.0.0-beta.2": - version: 1.0.0-beta.2 - resolution: "gensync@npm:1.0.0-beta.2" - checksum: 10c0/782aba6cba65b1bb5af3b095d96249d20edbe8df32dbf4696fd49be2583faf676173bf4809386588828e4dd76a3354fcbeb577bab1c833ccd9fc4577f26103f8 - languageName: node - linkType: hard - "get-caller-file@npm:^2.0.5": version: 2.0.5 resolution: "get-caller-file@npm:2.0.5" @@ -7414,13 +6342,6 @@ __metadata: languageName: node linkType: hard -"get-package-type@npm:^0.1.0": - version: 0.1.0 - resolution: "get-package-type@npm:0.1.0" - checksum: 10c0/e34cdf447fdf1902a1f6d5af737eaadf606d2ee3518287abde8910e04159368c268568174b2e71102b87b26c2020486f126bfca9c4fb1ceb986ff99b52ecd1be - languageName: node - linkType: hard - "get-stream@npm:^6.0.0, get-stream@npm:^6.0.1": version: 6.0.1 resolution: "get-stream@npm:6.0.1" @@ -7429,11 +6350,11 @@ __metadata: linkType: hard "get-tsconfig@npm:^4.7.5": - version: 4.10.0 - resolution: "get-tsconfig@npm:4.10.0" + version: 4.10.1 + resolution: "get-tsconfig@npm:4.10.1" dependencies: resolve-pkg-maps: "npm:^1.0.0" - checksum: 10c0/c9b5572c5118923c491c04285c73bd55b19e214992af957c502a3be0fc0043bb421386ffd45ca3433c0a7fba81221ca300479e8393960acf15d0ed4563f38a86 + checksum: 10c0/7f8e3dabc6a49b747920a800fb88e1952fef871cdf51b79e98db48275a5de6cdaf499c55ee67df5fa6fe7ce65f0063e26de0f2e53049b408c585aa74d39ffa21 languageName: node linkType: hard @@ -7485,7 +6406,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^7.0.0, glob@npm:^7.1.3, glob@npm:^7.1.4": +"glob@npm:^7.0.0, glob@npm:^7.1.3": version: 7.2.3 resolution: "glob@npm:7.2.3" dependencies: @@ -7508,13 +6429,6 @@ __metadata: languageName: node linkType: hard -"globals@npm:^11.1.0": - version: 11.12.0 - resolution: "globals@npm:11.12.0" - checksum: 10c0/758f9f258e7b19226bd8d4af5d3b0dcf7038780fb23d82e6f98932c44e239f884847f1766e8fa9cc5635ccb3204f7fa7314d4408dd4002a5e8ea827b4018f0a1 - languageName: node - linkType: hard - "globals@npm:^13.19.0": version: 13.23.0 resolution: "globals@npm:13.23.0" @@ -7718,13 +6632,6 @@ __metadata: languageName: node linkType: hard -"html-escaper@npm:^2.0.0": - version: 2.0.2 - resolution: "html-escaper@npm:2.0.2" - checksum: 10c0/208e8a12de1a6569edbb14544f4567e6ce8ecc30b9394fcaa4e7bb1e60c12a7c9a1ed27e31290817157e8626f3a4f29e76c8747030822eb84a6abb15c255f0a0 - languageName: node - linkType: hard - "htmlparser2@npm:^8.0.0": version: 8.0.2 resolution: "htmlparser2@npm:8.0.2" @@ -7792,7 +6699,7 @@ __metadata: languageName: node linkType: hard -"http-link-header@npm:^1.0.2, http-link-header@npm:^1.1.1": +"http-link-header@npm:^1.0.2": version: 1.1.3 resolution: "http-link-header@npm:1.1.3" checksum: 10c0/56698a9d3aee4d5319d1cdfe62ef5d7179f179ec1e6432d23c9e6a0c896be642ba47a4985a45419cff91008032aef920aca9df94ff9e763e646c83bf54b7243d @@ -7894,18 +6801,6 @@ __metadata: languageName: node linkType: hard -"import-local@npm:^3.0.2": - version: 3.1.0 - resolution: "import-local@npm:3.1.0" - dependencies: - pkg-dir: "npm:^4.2.0" - resolve-cwd: "npm:^3.0.0" - bin: - import-local-fixture: fixtures/cli.js - checksum: 10c0/c67ecea72f775fe8684ca3d057e54bdb2ae28c14bf261d2607c269c18ea0da7b730924c06262eca9aed4b8ab31e31d65bc60b50e7296c85908a56e2f7d41ecd2 - languageName: node - linkType: hard - "imurmurhash@npm:^0.1.4": version: 0.1.4 resolution: "imurmurhash@npm:0.1.4" @@ -8012,13 +6907,6 @@ __metadata: languageName: node linkType: hard -"is-generator-fn@npm:^2.0.0": - version: 2.1.0 - resolution: "is-generator-fn@npm:2.1.0" - checksum: 10c0/2957cab387997a466cd0bf5c1b6047bd21ecb32bdcfd8996b15747aa01002c1c88731802f1b3d34ac99f4f6874b626418bd118658cf39380fe5fff32a3af9c4d - languageName: node - linkType: hard - "is-generator-function@npm:^1.0.7": version: 1.0.10 resolution: "is-generator-function@npm:1.0.10" @@ -8097,330 +6985,93 @@ __metadata: languageName: node linkType: hard -"is-text-path@npm:^1.0.1": - version: 1.0.1 - resolution: "is-text-path@npm:1.0.1" - dependencies: - text-extensions: "npm:^1.0.0" - checksum: 10c0/61c8650c29548febb6bf69e9541fc11abbbb087a0568df7bc471ba264e95fb254def4e610631cbab4ddb0a1a07949d06416f4ebeaf37875023fb184cdb87ee84 - languageName: node - linkType: hard - -"is-unicode-supported@npm:^1.3.0": - version: 1.3.0 - resolution: "is-unicode-supported@npm:1.3.0" - checksum: 10c0/b8674ea95d869f6faabddc6a484767207058b91aea0250803cbf1221345cb0c56f466d4ecea375dc77f6633d248d33c47bd296fb8f4cdba0b4edba8917e83d8a - languageName: node - linkType: hard - -"is-unicode-supported@npm:^2.0.0": - version: 2.1.0 - resolution: "is-unicode-supported@npm:2.1.0" - checksum: 10c0/a0f53e9a7c1fdbcf2d2ef6e40d4736fdffff1c9f8944c75e15425118ff3610172c87bf7bc6c34d3903b04be59790bb2212ddbe21ee65b5a97030fc50370545a5 - languageName: node - linkType: hard - -"isexe@npm:^2.0.0": - version: 2.0.0 - resolution: "isexe@npm:2.0.0" - checksum: 10c0/228cfa503fadc2c31596ab06ed6aa82c9976eec2bfd83397e7eaf06d0ccf42cd1dfd6743bf9aeb01aebd4156d009994c5f76ea898d2832c1fe342da923ca457d - languageName: node - linkType: hard - -"isexe@npm:^3.1.1": - version: 3.1.1 - resolution: "isexe@npm:3.1.1" - checksum: 10c0/9ec257654093443eb0a528a9c8cbba9c0ca7616ccb40abd6dde7202734d96bb86e4ac0d764f0f8cd965856aacbff2f4ce23e730dc19dfb41e3b0d865ca6fdcc7 - languageName: node - linkType: hard - -"iso8601-duration@npm:^2.1.1": - version: 2.1.2 - resolution: "iso8601-duration@npm:2.1.2" - checksum: 10c0/6b19e0e2cdbb6f76608c74c2ac55de338ca52ca396d9c89278f33daf3894a17d31e188af26087634a55455fac5ba6f868b1a585e2a008df3731f2d77f91d3250 - languageName: node - linkType: hard - -"istanbul-lib-coverage@npm:^3.0.0, istanbul-lib-coverage@npm:^3.2.0": - version: 3.2.2 - resolution: "istanbul-lib-coverage@npm:3.2.2" - checksum: 10c0/6c7ff2106769e5f592ded1fb418f9f73b4411fd5a084387a5410538332b6567cd1763ff6b6cadca9b9eb2c443cce2f7ea7d7f1b8d315f9ce58539793b1e0922b - languageName: node - linkType: hard - -"istanbul-lib-instrument@npm:^5.0.4": - version: 5.2.1 - resolution: "istanbul-lib-instrument@npm:5.2.1" - dependencies: - "@babel/core": "npm:^7.12.3" - "@babel/parser": "npm:^7.14.7" - "@istanbuljs/schema": "npm:^0.1.2" - istanbul-lib-coverage: "npm:^3.2.0" - semver: "npm:^6.3.0" - checksum: 10c0/8a1bdf3e377dcc0d33ec32fe2b6ecacdb1e4358fd0eb923d4326bb11c67622c0ceb99600a680f3dad5d29c66fc1991306081e339b4d43d0b8a2ab2e1d910a6ee - languageName: node - linkType: hard - -"istanbul-lib-instrument@npm:^6.0.0": - version: 6.0.1 - resolution: "istanbul-lib-instrument@npm:6.0.1" - dependencies: - "@babel/core": "npm:^7.12.3" - "@babel/parser": "npm:^7.14.7" - "@istanbuljs/schema": "npm:^0.1.2" - istanbul-lib-coverage: "npm:^3.2.0" - semver: "npm:^7.5.4" - checksum: 10c0/313d61aca3f82a04ad9377841d05061d603ea3d4a4dd281fdda2479ec4ddbc86dc1792c73651f21c93480570d1ecadc5f63011e2df86f30ee662b62c0c00e3d8 - languageName: node - linkType: hard - -"istanbul-lib-report@npm:^3.0.0": - version: 3.0.1 - resolution: "istanbul-lib-report@npm:3.0.1" - dependencies: - istanbul-lib-coverage: "npm:^3.0.0" - make-dir: "npm:^4.0.0" - supports-color: "npm:^7.1.0" - checksum: 10c0/84323afb14392de8b6a5714bd7e9af845cfbd56cfe71ed276cda2f5f1201aea673c7111901227ee33e68e4364e288d73861eb2ed48f6679d1e69a43b6d9b3ba7 - languageName: node - linkType: hard - -"istanbul-lib-source-maps@npm:^4.0.0": - version: 4.0.1 - resolution: "istanbul-lib-source-maps@npm:4.0.1" - dependencies: - debug: "npm:^4.1.1" - istanbul-lib-coverage: "npm:^3.0.0" - source-map: "npm:^0.6.1" - checksum: 10c0/19e4cc405016f2c906dff271a76715b3e881fa9faeb3f09a86cb99b8512b3a5ed19cadfe0b54c17ca0e54c1142c9c6de9330d65506e35873994e06634eebeb66 - languageName: node - linkType: hard - -"istanbul-reports@npm:^3.1.3": - version: 3.1.6 - resolution: "istanbul-reports@npm:3.1.6" - dependencies: - html-escaper: "npm:^2.0.0" - istanbul-lib-report: "npm:^3.0.0" - checksum: 10c0/ec3f1bdbc51b3e0b325a5b9f4ad31a247697f31001df4e81075f7980413f14da1b5adfec574fd156efd3b0464023f61320f6718efc66ee72b32d89611cef99dd - languageName: node - linkType: hard - -"jackspeak@npm:^2.3.5": - version: 2.3.6 - resolution: "jackspeak@npm:2.3.6" - dependencies: - "@isaacs/cliui": "npm:^8.0.2" - "@pkgjs/parseargs": "npm:^0.11.0" - dependenciesMeta: - "@pkgjs/parseargs": - optional: true - checksum: 10c0/f01d8f972d894cd7638bc338e9ef5ddb86f7b208ce177a36d718eac96ec86638a6efa17d0221b10073e64b45edc2ce15340db9380b1f5d5c5d000cbc517dc111 - languageName: node - linkType: hard - -"jake@npm:^10.8.5": - version: 10.8.7 - resolution: "jake@npm:10.8.7" - dependencies: - async: "npm:^3.2.3" - chalk: "npm:^4.0.2" - filelist: "npm:^1.0.4" - minimatch: "npm:^3.1.2" - bin: - jake: bin/cli.js - checksum: 10c0/89326d01a8bc110d02d973729a66394c79a34b34461116f5c530a2a2dbc30265683fe6737928f75df9178e9d369ff1442f5753fb983d525e740eefdadc56a103 - languageName: node - linkType: hard - -"jest-changed-files@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-changed-files@npm:29.7.0" - dependencies: - execa: "npm:^5.0.0" - jest-util: "npm:^29.7.0" - p-limit: "npm:^3.1.0" - checksum: 10c0/e071384d9e2f6bb462231ac53f29bff86f0e12394c1b49ccafbad225ce2ab7da226279a8a94f421949920bef9be7ef574fd86aee22e8adfa149be73554ab828b - languageName: node - linkType: hard - -"jest-circus@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-circus@npm:29.7.0" - dependencies: - "@jest/environment": "npm:^29.7.0" - "@jest/expect": "npm:^29.7.0" - "@jest/test-result": "npm:^29.7.0" - "@jest/types": "npm:^29.6.3" - "@types/node": "npm:*" - chalk: "npm:^4.0.0" - co: "npm:^4.6.0" - dedent: "npm:^1.0.0" - is-generator-fn: "npm:^2.0.0" - jest-each: "npm:^29.7.0" - jest-matcher-utils: "npm:^29.7.0" - jest-message-util: "npm:^29.7.0" - jest-runtime: "npm:^29.7.0" - jest-snapshot: "npm:^29.7.0" - jest-util: "npm:^29.7.0" - p-limit: "npm:^3.1.0" - pretty-format: "npm:^29.7.0" - pure-rand: "npm:^6.0.0" - slash: "npm:^3.0.0" - stack-utils: "npm:^2.0.3" - checksum: 10c0/8d15344cf7a9f14e926f0deed64ed190c7a4fa1ed1acfcd81e4cc094d3cc5bf7902ebb7b874edc98ada4185688f90c91e1747e0dfd7ac12463b097968ae74b5e - languageName: node - linkType: hard - -"jest-cli@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-cli@npm:29.7.0" - dependencies: - "@jest/core": "npm:^29.7.0" - "@jest/test-result": "npm:^29.7.0" - "@jest/types": "npm:^29.6.3" - chalk: "npm:^4.0.0" - create-jest: "npm:^29.7.0" - exit: "npm:^0.1.2" - import-local: "npm:^3.0.2" - jest-config: "npm:^29.7.0" - jest-util: "npm:^29.7.0" - jest-validate: "npm:^29.7.0" - yargs: "npm:^17.3.1" - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - bin: - jest: bin/jest.js - checksum: 10c0/a658fd55050d4075d65c1066364595962ead7661711495cfa1dfeecf3d6d0a8ffec532f3dbd8afbb3e172dd5fd2fb2e813c5e10256e7cf2fea766314942fb43a - languageName: node - linkType: hard - -"jest-config@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-config@npm:29.7.0" - dependencies: - "@babel/core": "npm:^7.11.6" - "@jest/test-sequencer": "npm:^29.7.0" - "@jest/types": "npm:^29.6.3" - babel-jest: "npm:^29.7.0" - chalk: "npm:^4.0.0" - ci-info: "npm:^3.2.0" - deepmerge: "npm:^4.2.2" - glob: "npm:^7.1.3" - graceful-fs: "npm:^4.2.9" - jest-circus: "npm:^29.7.0" - jest-environment-node: "npm:^29.7.0" - jest-get-type: "npm:^29.6.3" - jest-regex-util: "npm:^29.6.3" - jest-resolve: "npm:^29.7.0" - jest-runner: "npm:^29.7.0" - jest-util: "npm:^29.7.0" - jest-validate: "npm:^29.7.0" - micromatch: "npm:^4.0.4" - parse-json: "npm:^5.2.0" - pretty-format: "npm:^29.7.0" - slash: "npm:^3.0.0" - strip-json-comments: "npm:^3.1.1" - peerDependencies: - "@types/node": "*" - ts-node: ">=9.0.0" - peerDependenciesMeta: - "@types/node": - optional: true - ts-node: - optional: true - checksum: 10c0/bab23c2eda1fff06e0d104b00d6adfb1d1aabb7128441899c9bff2247bd26710b050a5364281ce8d52b46b499153bf7e3ee88b19831a8f3451f1477a0246a0f1 +"is-text-path@npm:^1.0.1": + version: 1.0.1 + resolution: "is-text-path@npm:1.0.1" + dependencies: + text-extensions: "npm:^1.0.0" + checksum: 10c0/61c8650c29548febb6bf69e9541fc11abbbb087a0568df7bc471ba264e95fb254def4e610631cbab4ddb0a1a07949d06416f4ebeaf37875023fb184cdb87ee84 languageName: node linkType: hard -"jest-diff@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-diff@npm:29.7.0" - dependencies: - chalk: "npm:^4.0.0" - diff-sequences: "npm:^29.6.3" - jest-get-type: "npm:^29.6.3" - pretty-format: "npm:^29.7.0" - checksum: 10c0/89a4a7f182590f56f526443dde69acefb1f2f0c9e59253c61d319569856c4931eae66b8a3790c443f529267a0ddba5ba80431c585deed81827032b2b2a1fc999 +"is-unicode-supported@npm:^1.3.0": + version: 1.3.0 + resolution: "is-unicode-supported@npm:1.3.0" + checksum: 10c0/b8674ea95d869f6faabddc6a484767207058b91aea0250803cbf1221345cb0c56f466d4ecea375dc77f6633d248d33c47bd296fb8f4cdba0b4edba8917e83d8a languageName: node linkType: hard -"jest-docblock@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-docblock@npm:29.7.0" - dependencies: - detect-newline: "npm:^3.0.0" - checksum: 10c0/d932a8272345cf6b6142bb70a2bb63e0856cc0093f082821577ea5bdf4643916a98744dfc992189d2b1417c38a11fa42466f6111526bc1fb81366f56410f3be9 +"is-unicode-supported@npm:^2.0.0": + version: 2.1.0 + resolution: "is-unicode-supported@npm:2.1.0" + checksum: 10c0/a0f53e9a7c1fdbcf2d2ef6e40d4736fdffff1c9f8944c75e15425118ff3610172c87bf7bc6c34d3903b04be59790bb2212ddbe21ee65b5a97030fc50370545a5 languageName: node linkType: hard -"jest-each@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-each@npm:29.7.0" - dependencies: - "@jest/types": "npm:^29.6.3" - chalk: "npm:^4.0.0" - jest-get-type: "npm:^29.6.3" - jest-util: "npm:^29.7.0" - pretty-format: "npm:^29.7.0" - checksum: 10c0/f7f9a90ebee80cc688e825feceb2613627826ac41ea76a366fa58e669c3b2403d364c7c0a74d862d469b103c843154f8456d3b1c02b487509a12afa8b59edbb4 +"isexe@npm:^2.0.0": + version: 2.0.0 + resolution: "isexe@npm:2.0.0" + checksum: 10c0/228cfa503fadc2c31596ab06ed6aa82c9976eec2bfd83397e7eaf06d0ccf42cd1dfd6743bf9aeb01aebd4156d009994c5f76ea898d2832c1fe342da923ca457d languageName: node linkType: hard -"jest-environment-node@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-environment-node@npm:29.7.0" - dependencies: - "@jest/environment": "npm:^29.7.0" - "@jest/fake-timers": "npm:^29.7.0" - "@jest/types": "npm:^29.6.3" - "@types/node": "npm:*" - jest-mock: "npm:^29.7.0" - jest-util: "npm:^29.7.0" - checksum: 10c0/61f04fec077f8b1b5c1a633e3612fc0c9aa79a0ab7b05600683428f1e01a4d35346c474bde6f439f9fcc1a4aa9a2861ff852d079a43ab64b02105d1004b2592b +"isexe@npm:^3.1.1": + version: 3.1.1 + resolution: "isexe@npm:3.1.1" + checksum: 10c0/9ec257654093443eb0a528a9c8cbba9c0ca7616ccb40abd6dde7202734d96bb86e4ac0d764f0f8cd965856aacbff2f4ce23e730dc19dfb41e3b0d865ca6fdcc7 languageName: node linkType: hard -"jest-get-type@npm:^29.6.3": - version: 29.6.3 - resolution: "jest-get-type@npm:29.6.3" - checksum: 10c0/552e7a97a983d3c2d4e412a44eb7de0430ff773dd99f7500962c268d6dfbfa431d7d08f919c9d960530e5f7f78eb47f267ad9b318265e5092b3ff9ede0db7c2b +"iso8601-duration@npm:^2.1.1": + version: 2.1.2 + resolution: "iso8601-duration@npm:2.1.2" + checksum: 10c0/6b19e0e2cdbb6f76608c74c2ac55de338ca52ca396d9c89278f33daf3894a17d31e188af26087634a55455fac5ba6f868b1a585e2a008df3731f2d77f91d3250 languageName: node linkType: hard -"jest-haste-map@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-haste-map@npm:29.7.0" +"jackspeak@npm:^2.3.5": + version: 2.3.6 + resolution: "jackspeak@npm:2.3.6" dependencies: - "@jest/types": "npm:^29.6.3" - "@types/graceful-fs": "npm:^4.1.3" - "@types/node": "npm:*" - anymatch: "npm:^3.0.3" - fb-watchman: "npm:^2.0.0" - fsevents: "npm:^2.3.2" - graceful-fs: "npm:^4.2.9" - jest-regex-util: "npm:^29.6.3" - jest-util: "npm:^29.7.0" - jest-worker: "npm:^29.7.0" - micromatch: "npm:^4.0.4" - walker: "npm:^1.0.8" + "@isaacs/cliui": "npm:^8.0.2" + "@pkgjs/parseargs": "npm:^0.11.0" dependenciesMeta: - fsevents: + "@pkgjs/parseargs": optional: true - checksum: 10c0/2683a8f29793c75a4728787662972fedd9267704c8f7ef9d84f2beed9a977f1cf5e998c07b6f36ba5603f53cb010c911fe8cd0ac9886e073fe28ca66beefd30c + checksum: 10c0/f01d8f972d894cd7638bc338e9ef5ddb86f7b208ce177a36d718eac96ec86638a6efa17d0221b10073e64b45edc2ce15340db9380b1f5d5c5d000cbc517dc111 + languageName: node + linkType: hard + +"jake@npm:^10.8.5": + version: 10.8.7 + resolution: "jake@npm:10.8.7" + dependencies: + async: "npm:^3.2.3" + chalk: "npm:^4.0.2" + filelist: "npm:^1.0.4" + minimatch: "npm:^3.1.2" + bin: + jake: bin/cli.js + checksum: 10c0/89326d01a8bc110d02d973729a66394c79a34b34461116f5c530a2a2dbc30265683fe6737928f75df9178e9d369ff1442f5753fb983d525e740eefdadc56a103 languageName: node linkType: hard -"jest-leak-detector@npm:^29.7.0": +"jest-diff@npm:^29.7.0": version: 29.7.0 - resolution: "jest-leak-detector@npm:29.7.0" + resolution: "jest-diff@npm:29.7.0" dependencies: + chalk: "npm:^4.0.0" + diff-sequences: "npm:^29.6.3" jest-get-type: "npm:^29.6.3" pretty-format: "npm:^29.7.0" - checksum: 10c0/71bb9f77fc489acb842a5c7be030f2b9acb18574dc9fb98b3100fc57d422b1abc55f08040884bd6e6dbf455047a62f7eaff12aa4058f7cbdc11558718ca6a395 + checksum: 10c0/89a4a7f182590f56f526443dde69acefb1f2f0c9e59253c61d319569856c4931eae66b8a3790c443f529267a0ddba5ba80431c585deed81827032b2b2a1fc999 + languageName: node + linkType: hard + +"jest-get-type@npm:^29.6.3": + version: 29.6.3 + resolution: "jest-get-type@npm:29.6.3" + checksum: 10c0/552e7a97a983d3c2d4e412a44eb7de0430ff773dd99f7500962c268d6dfbfa431d7d08f919c9d960530e5f7f78eb47f267ad9b318265e5092b3ff9ede0db7c2b languageName: node linkType: hard @@ -8453,29 +7104,6 @@ __metadata: languageName: node linkType: hard -"jest-mock@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-mock@npm:29.7.0" - dependencies: - "@jest/types": "npm:^29.6.3" - "@types/node": "npm:*" - jest-util: "npm:^29.7.0" - checksum: 10c0/7b9f8349ee87695a309fe15c46a74ab04c853369e5c40952d68061d9dc3159a0f0ed73e215f81b07ee97a9faaf10aebe5877a9d6255068a0977eae6a9ff1d5ac - languageName: node - linkType: hard - -"jest-pnp-resolver@npm:^1.2.2": - version: 1.2.3 - resolution: "jest-pnp-resolver@npm:1.2.3" - peerDependencies: - jest-resolve: "*" - peerDependenciesMeta: - jest-resolve: - optional: true - checksum: 10c0/86eec0c78449a2de733a6d3e316d49461af6a858070e113c97f75fb742a48c2396ea94150cbca44159ffd4a959f743a47a8b37a792ef6fdad2cf0a5cba973fac - languageName: node - linkType: hard - "jest-rdf@npm:^1.8.1": version: 1.8.1 resolution: "jest-rdf@npm:1.8.1" @@ -8488,128 +7116,7 @@ __metadata: languageName: node linkType: hard -"jest-regex-util@npm:^29.6.3": - version: 29.6.3 - resolution: "jest-regex-util@npm:29.6.3" - checksum: 10c0/4e33fb16c4f42111159cafe26397118dcfc4cf08bc178a67149fb05f45546a91928b820894572679d62559839d0992e21080a1527faad65daaae8743a5705a3b - languageName: node - linkType: hard - -"jest-resolve-dependencies@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-resolve-dependencies@npm:29.7.0" - dependencies: - jest-regex-util: "npm:^29.6.3" - jest-snapshot: "npm:^29.7.0" - checksum: 10c0/b6e9ad8ae5b6049474118ea6441dfddd385b6d1fc471db0136f7c8fbcfe97137a9665e4f837a9f49f15a29a1deb95a14439b7aec812f3f99d08f228464930f0d - languageName: node - linkType: hard - -"jest-resolve@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-resolve@npm:29.7.0" - dependencies: - chalk: "npm:^4.0.0" - graceful-fs: "npm:^4.2.9" - jest-haste-map: "npm:^29.7.0" - jest-pnp-resolver: "npm:^1.2.2" - jest-util: "npm:^29.7.0" - jest-validate: "npm:^29.7.0" - resolve: "npm:^1.20.0" - resolve.exports: "npm:^2.0.0" - slash: "npm:^3.0.0" - checksum: 10c0/59da5c9c5b50563e959a45e09e2eace783d7f9ac0b5dcc6375dea4c0db938d2ebda97124c8161310082760e8ebbeff9f6b177c15ca2f57fb424f637a5d2adb47 - languageName: node - linkType: hard - -"jest-runner@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-runner@npm:29.7.0" - dependencies: - "@jest/console": "npm:^29.7.0" - "@jest/environment": "npm:^29.7.0" - "@jest/test-result": "npm:^29.7.0" - "@jest/transform": "npm:^29.7.0" - "@jest/types": "npm:^29.6.3" - "@types/node": "npm:*" - chalk: "npm:^4.0.0" - emittery: "npm:^0.13.1" - graceful-fs: "npm:^4.2.9" - jest-docblock: "npm:^29.7.0" - jest-environment-node: "npm:^29.7.0" - jest-haste-map: "npm:^29.7.0" - jest-leak-detector: "npm:^29.7.0" - jest-message-util: "npm:^29.7.0" - jest-resolve: "npm:^29.7.0" - jest-runtime: "npm:^29.7.0" - jest-util: "npm:^29.7.0" - jest-watcher: "npm:^29.7.0" - jest-worker: "npm:^29.7.0" - p-limit: "npm:^3.1.0" - source-map-support: "npm:0.5.13" - checksum: 10c0/2194b4531068d939f14c8d3274fe5938b77fa73126aedf9c09ec9dec57d13f22c72a3b5af01ac04f5c1cf2e28d0ac0b4a54212a61b05f10b5d6b47f2a1097bb4 - languageName: node - linkType: hard - -"jest-runtime@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-runtime@npm:29.7.0" - dependencies: - "@jest/environment": "npm:^29.7.0" - "@jest/fake-timers": "npm:^29.7.0" - "@jest/globals": "npm:^29.7.0" - "@jest/source-map": "npm:^29.6.3" - "@jest/test-result": "npm:^29.7.0" - "@jest/transform": "npm:^29.7.0" - "@jest/types": "npm:^29.6.3" - "@types/node": "npm:*" - chalk: "npm:^4.0.0" - cjs-module-lexer: "npm:^1.0.0" - collect-v8-coverage: "npm:^1.0.0" - glob: "npm:^7.1.3" - graceful-fs: "npm:^4.2.9" - jest-haste-map: "npm:^29.7.0" - jest-message-util: "npm:^29.7.0" - jest-mock: "npm:^29.7.0" - jest-regex-util: "npm:^29.6.3" - jest-resolve: "npm:^29.7.0" - jest-snapshot: "npm:^29.7.0" - jest-util: "npm:^29.7.0" - slash: "npm:^3.0.0" - strip-bom: "npm:^4.0.0" - checksum: 10c0/7cd89a1deda0bda7d0941835434e44f9d6b7bd50b5c5d9b0fc9a6c990b2d4d2cab59685ab3cb2850ed4cc37059f6de903af5a50565d7f7f1192a77d3fd6dd2a6 - languageName: node - linkType: hard - -"jest-snapshot@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-snapshot@npm:29.7.0" - dependencies: - "@babel/core": "npm:^7.11.6" - "@babel/generator": "npm:^7.7.2" - "@babel/plugin-syntax-jsx": "npm:^7.7.2" - "@babel/plugin-syntax-typescript": "npm:^7.7.2" - "@babel/types": "npm:^7.3.3" - "@jest/expect-utils": "npm:^29.7.0" - "@jest/transform": "npm:^29.7.0" - "@jest/types": "npm:^29.6.3" - babel-preset-current-node-syntax: "npm:^1.0.0" - chalk: "npm:^4.0.0" - expect: "npm:^29.7.0" - graceful-fs: "npm:^4.2.9" - jest-diff: "npm:^29.7.0" - jest-get-type: "npm:^29.6.3" - jest-matcher-utils: "npm:^29.7.0" - jest-message-util: "npm:^29.7.0" - jest-util: "npm:^29.7.0" - natural-compare: "npm:^1.4.0" - pretty-format: "npm:^29.7.0" - semver: "npm:^7.5.3" - checksum: 10c0/6e9003c94ec58172b4a62864a91c0146513207bedf4e0a06e1e2ac70a4484088a2683e3a0538d8ea913bcfd53dc54a9b98a98cdfa562e7fe1d1339aeae1da570 - languageName: node - linkType: hard - -"jest-util@npm:^29.0.0, jest-util@npm:^29.7.0": +"jest-util@npm:^29.7.0": version: 29.7.0 resolution: "jest-util@npm:29.7.0" dependencies: @@ -8623,67 +7130,6 @@ __metadata: languageName: node linkType: hard -"jest-validate@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-validate@npm:29.7.0" - dependencies: - "@jest/types": "npm:^29.6.3" - camelcase: "npm:^6.2.0" - chalk: "npm:^4.0.0" - jest-get-type: "npm:^29.6.3" - leven: "npm:^3.1.0" - pretty-format: "npm:^29.7.0" - checksum: 10c0/a20b930480c1ed68778c739f4739dce39423131bc070cd2505ddede762a5570a256212e9c2401b7ae9ba4d7b7c0803f03c5b8f1561c62348213aba18d9dbece2 - languageName: node - linkType: hard - -"jest-watcher@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-watcher@npm:29.7.0" - dependencies: - "@jest/test-result": "npm:^29.7.0" - "@jest/types": "npm:^29.6.3" - "@types/node": "npm:*" - ansi-escapes: "npm:^4.2.1" - chalk: "npm:^4.0.0" - emittery: "npm:^0.13.1" - jest-util: "npm:^29.7.0" - string-length: "npm:^4.0.1" - checksum: 10c0/ec6c75030562fc8f8c727cb8f3b94e75d831fc718785abfc196e1f2a2ebc9a2e38744a15147170039628a853d77a3b695561ce850375ede3a4ee6037a2574567 - languageName: node - linkType: hard - -"jest-worker@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-worker@npm:29.7.0" - dependencies: - "@types/node": "npm:*" - jest-util: "npm:^29.7.0" - merge-stream: "npm:^2.0.0" - supports-color: "npm:^8.0.0" - checksum: 10c0/5570a3a005b16f46c131968b8a5b56d291f9bbb85ff4217e31c80bd8a02e7de799e59a54b95ca28d5c302f248b54cbffde2d177c2f0f52ffcee7504c6eabf660 - languageName: node - linkType: hard - -"jest@npm:^29.7.0": - version: 29.7.0 - resolution: "jest@npm:29.7.0" - dependencies: - "@jest/core": "npm:^29.7.0" - "@jest/types": "npm:^29.6.3" - import-local: "npm:^3.0.2" - jest-cli: "npm:^29.7.0" - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - bin: - jest: bin/jest.js - checksum: 10c0/f40eb8171cf147c617cc6ada49d062fbb03b4da666cb8d39cdbfb739a7d75eea4c3ca150fb072d0d273dce0c753db4d0467d54906ad0293f59c54f9db4a09d8b - languageName: node - linkType: hard - "jose@npm:^4.15.2, jose@npm:^4.7.0": version: 4.15.4 resolution: "jose@npm:4.15.4" @@ -8705,15 +7151,10 @@ __metadata: languageName: node linkType: hard -"js-yaml@npm:^3.13.1": - version: 3.14.1 - resolution: "js-yaml@npm:3.14.1" - dependencies: - argparse: "npm:^1.0.7" - esprima: "npm:^4.0.0" - bin: - js-yaml: bin/js-yaml.js - checksum: 10c0/6746baaaeac312c4db8e75fa22331d9a04cccb7792d126ed8ce6a0bbcfef0cedaddd0c5098fade53db067c09fe00aa1c957674b4765610a8b06a5a189e46433b +"js-tokens@npm:^9.0.1": + version: 9.0.1 + resolution: "js-tokens@npm:9.0.1" + checksum: 10c0/68dcab8f233dde211a6b5fd98079783cbcd04b53617c1250e3553ee16ab3e6134f5e65478e41d82f6d351a052a63d71024553933808570f04dbf828d7921e80e languageName: node linkType: hard @@ -8728,15 +7169,6 @@ __metadata: languageName: node linkType: hard -"jsesc@npm:^2.5.1": - version: 2.5.2 - resolution: "jsesc@npm:2.5.2" - bin: - jsesc: bin/jsesc - checksum: 10c0/dbf59312e0ebf2b4405ef413ec2b25abb5f8f4d9bc5fb8d9f90381622ebca5f2af6a6aa9a8578f65903f9e33990a6dc798edd0ce5586894bf0e9e31803a1de88 - languageName: node - linkType: hard - "jsesc@npm:^3.0.2": version: 3.0.2 resolution: "jsesc@npm:3.0.2" @@ -8774,15 +7206,6 @@ __metadata: languageName: node linkType: hard -"json5@npm:^2.2.3": - version: 2.2.3 - resolution: "json5@npm:2.2.3" - bin: - json5: lib/cli.js - checksum: 10c0/5a04eed94810fa55c5ea138b2f7a5c12b97c3750bc63d11e511dcecbfef758003861522a070c2272764ee0f4e3e323862f386945aeb5b85b87ee43f084ba586c - languageName: node - linkType: hard - "jsonc-parser@npm:3.3.1": version: 3.3.1 resolution: "jsonc-parser@npm:3.3.1" @@ -8830,19 +7253,7 @@ __metadata: languageName: node linkType: hard -"jsonld-signatures@npm:^11.2.1, jsonld-signatures@npm:^11.3.0": - version: 11.5.0 - resolution: "jsonld-signatures@npm:11.5.0" - dependencies: - "@digitalbazaar/security-context": "npm:^1.0.0" - jsonld: "npm:^8.0.0" - rdf-canonize: "npm:^4.0.1" - serialize-error: "npm:^8.1.0" - checksum: 10c0/a624ef4706c91064ba19dd3f1bb2a43f40cabd68f38e1c3e57fb0cea830b5ff4763364a00197313ccf704f571295803220d5c20d40df371562d84de98c5df9a0 - languageName: node - linkType: hard - -"jsonld-streaming-parser@npm:^3.0.1, jsonld-streaming-parser@npm:^3.3.0": +"jsonld-streaming-parser@npm:^3.0.1": version: 3.4.0 resolution: "jsonld-streaming-parser@npm:3.4.0" dependencies: @@ -8873,7 +7284,7 @@ __metadata: languageName: node linkType: hard -"jsonld@npm:^8.0.0, jsonld@npm:^8.3.1, jsonld@npm:^8.3.3, jsonld@npm:^8.x.x": +"jsonld@npm:^8.x.x": version: 8.3.3 resolution: "jsonld@npm:8.3.3" dependencies: @@ -9042,20 +7453,6 @@ __metadata: languageName: node linkType: hard -"ky@npm:^1.0.1": - version: 1.7.4 - resolution: "ky@npm:1.7.4" - checksum: 10c0/8b28b85cbee6d3e073ff796b92661f4bf155ec9b9a131411de1c34fb2f89f8507e67ff3df369e3c6d18714134774e8735e88cba72b19d005a09112b800d14474 - languageName: node - linkType: hard - -"leven@npm:^3.1.0": - version: 3.1.0 - resolution: "leven@npm:3.1.0" - checksum: 10c0/cd778ba3fbab0f4d0500b7e87d1f6e1f041507c56fdcd47e8256a3012c98aaee371d4c15e0a76e0386107af2d42e2b7466160a2d80688aaa03e66e49949f42df - languageName: node - linkType: hard - "levn@npm:^0.4.1": version: 0.4.1 resolution: "levn@npm:0.4.1" @@ -9105,13 +7502,6 @@ __metadata: languageName: node linkType: hard -"lodash.memoize@npm:4.x": - version: 4.1.2 - resolution: "lodash.memoize@npm:4.1.2" - checksum: 10c0/c8713e51eccc650422716a14cece1809cfe34bc5ab5e242b7f8b4e2241c2483697b971a604252807689b9dd69bfe3a98852e19a5b89d506b000b4187a1285df8 - languageName: node - linkType: hard - "lodash.merge@npm:^4.6.2": version: 4.6.2 resolution: "lodash.merge@npm:4.6.2" @@ -9126,7 +7516,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:^4.17.15, lodash@npm:^4.17.19, lodash@npm:^4.17.21": +"lodash@npm:^4.17.15, lodash@npm:^4.17.19": version: 4.17.21 resolution: "lodash@npm:4.17.21" checksum: 10c0/d8cbea072bb08655bb4c989da418994b073a608dffa608b09ac04b43a791b12aeae7cd7ad919aa4c925f33b48490b5cfe6c1f71d827956071dae2e7bb3a6b74c @@ -9184,6 +7574,13 @@ __metadata: languageName: node linkType: hard +"loupe@npm:^3.1.0, loupe@npm:^3.1.4": + version: 3.1.4 + resolution: "loupe@npm:3.1.4" + checksum: 10c0/5c2e6aefaad25f812d361c750b8cf4ff91d68de289f141d7c85c2ce9bb79eeefa06a93c85f7b87cba940531ed8f15e492f32681d47eed23842ad1963eb3a154d + languageName: node + linkType: hard + "lowercase-keys@npm:^3.0.0": version: 3.0.0 resolution: "lowercase-keys@npm:3.0.0" @@ -9198,15 +7595,6 @@ __metadata: languageName: node linkType: hard -"lru-cache@npm:^5.1.1": - version: 5.1.1 - resolution: "lru-cache@npm:5.1.1" - dependencies: - yallist: "npm:^3.0.2" - checksum: 10c0/89b2ef2ef45f543011e38737b8a8622a2f8998cddf0e5437174ef8f1f70a8b9d14a918ab3e232cb3ba343b7abddffa667f0b59075b2b80e6b4d63c3de6127482 - languageName: node - linkType: hard - "lru-cache@npm:^6.0.0": version: 6.0.0 resolution: "lru-cache@npm:6.0.0" @@ -9216,16 +7604,16 @@ __metadata: languageName: node linkType: hard -"make-dir@npm:^4.0.0": - version: 4.0.0 - resolution: "make-dir@npm:4.0.0" +"magic-string@npm:^0.30.17": + version: 0.30.17 + resolution: "magic-string@npm:0.30.17" dependencies: - semver: "npm:^7.5.3" - checksum: 10c0/69b98a6c0b8e5c4fe9acb61608a9fbcfca1756d910f51e5dbe7a9e5cfb74fca9b8a0c8a0ffdf1294a740826c1ab4871d5bf3f62f72a3049e5eac6541ddffed68 + "@jridgewell/sourcemap-codec": "npm:^1.5.0" + checksum: 10c0/16826e415d04b88378f200fe022b53e638e3838b9e496edda6c0e086d7753a44a6ed187adc72d19f3623810589bf139af1a315541cd6a26ae0771a0193eaf7b8 languageName: node linkType: hard -"make-error@npm:1.x, make-error@npm:^1.1.1": +"make-error@npm:^1.1.1": version: 1.3.6 resolution: "make-error@npm:1.3.6" checksum: 10c0/171e458d86854c6b3fc46610cfacf0b45149ba043782558c6875d9f42f222124384ad0b468c92e996d815a8a2003817a710c0a160e49c1c394626f76fa45396f @@ -9251,15 +7639,6 @@ __metadata: languageName: node linkType: hard -"makeerror@npm:1.0.12": - version: 1.0.12 - resolution: "makeerror@npm:1.0.12" - dependencies: - tmpl: "npm:1.0.5" - checksum: 10c0/b0e6e599780ce6bab49cc413eba822f7d1f0dfebd1c103eaa3785c59e43e22c59018323cf9e1708f0ef5329e94a745d163fcbb6bff8e4c6742f9be9e86f3500c - languageName: node - linkType: hard - "map-obj@npm:^1.0.0": version: 1.0.1 resolution: "map-obj@npm:1.0.1" @@ -9427,7 +7806,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": +"minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": version: 3.1.2 resolution: "minimatch@npm:3.1.2" dependencies: @@ -9556,31 +7935,14 @@ __metadata: languageName: node linkType: hard -"ms@npm:2.1.2": - version: 2.1.2 - resolution: "ms@npm:2.1.2" - checksum: 10c0/a437714e2f90dbf881b5191d35a6db792efbca5badf112f87b9e1c712aace4b4b9b742dd6537f3edf90fd6f684de897cec230abde57e87883766712ddda297cc - languageName: node - linkType: hard - -"ms@npm:^2.1.1": +"ms@npm:^2.1.1, ms@npm:^2.1.3": version: 2.1.3 resolution: "ms@npm:2.1.3" checksum: 10c0/d924b57e7312b3b63ad21fc5b3dc0af5e78d61a1fc7cfb5457edaf26326bf62be5307cc87ffb6862ef1c2b33b0233cdb5d4f01c4c958cc0d660948b65a287a48 languageName: node linkType: hard -"n3@npm:^1.16.1, n3@npm:^1.16.3, n3@npm:^1.16.4, n3@npm:^1.17.0, n3@npm:^1.17.1, n3@npm:^1.17.2, n3@npm:^1.20.4, n3@npm:^1.6.3": - version: 1.25.1 - resolution: "n3@npm:1.25.1" - dependencies: - buffer: "npm:^6.0.3" - readable-stream: "npm:^4.0.0" - checksum: 10c0/0a4efc3151d79c7200b57f78bb5d4411f6746d7f2d63ccc7fe068fa9a4d20afc03001957d9216ce2da62f2de266452713f9867112e9b3170307eb4ac059d5d1d - languageName: node - linkType: hard - -"n3@npm:^1.23.1": +"n3@npm:^1.16.1, n3@npm:^1.16.3, n3@npm:^1.16.4, n3@npm:^1.17.0, n3@npm:^1.17.1, n3@npm:^1.17.2, n3@npm:^1.20.4, n3@npm:^1.23.1, n3@npm:^1.6.3": version: 1.25.2 resolution: "n3@npm:1.25.2" dependencies: @@ -9590,6 +7952,15 @@ __metadata: languageName: node linkType: hard +"nanoid@npm:^3.3.11": + version: 3.3.11 + resolution: "nanoid@npm:3.3.11" + bin: + nanoid: bin/nanoid.cjs + checksum: 10c0/40e7f70b3d15f725ca072dfc4f74e81fcf1fbb02e491cf58ac0c79093adc9b0a73b152bcde57df4b79cd097e13023d7504acb38404a4da7bc1cd8e887b82fe0b + languageName: node + linkType: hard + "nanoid@npm:^5.0.4": version: 5.0.4 resolution: "nanoid@npm:5.0.4" @@ -9686,20 +8057,6 @@ __metadata: languageName: node linkType: hard -"node-int64@npm:^0.4.0": - version: 0.4.0 - resolution: "node-int64@npm:0.4.0" - checksum: 10c0/a6a4d8369e2f2720e9c645255ffde909c0fbd41c92ea92a5607fc17055955daac99c1ff589d421eee12a0d24e99f7bfc2aabfeb1a4c14742f6c099a51863f31a - languageName: node - linkType: hard - -"node-releases@npm:^2.0.13": - version: 2.0.13 - resolution: "node-releases@npm:2.0.13" - checksum: 10c0/2fb44bf70fc949d27f3a48a7fd1a9d1d603ddad4ccd091f26b3fb8b1da976605d919330d7388ccd55ca2ade0dc8b2e12841ba19ef249c8bb29bf82532d401af7 - languageName: node - linkType: hard - "nodemailer@npm:^6.9.9": version: 6.10.0 resolution: "nodemailer@npm:6.10.0" @@ -9742,13 +8099,6 @@ __metadata: languageName: node linkType: hard -"normalize-path@npm:^3.0.0": - version: 3.0.0 - resolution: "normalize-path@npm:3.0.0" - checksum: 10c0/e008c8142bcc335b5e38cf0d63cfd39d6cf2d97480af9abdbe9a439221fd4d749763bab492a8ee708ce7a194bb00c9da6d0a115018672310850489137b3da046 - languageName: node - linkType: hard - "normalize-url@npm:^8.0.0": version: 8.0.0 resolution: "normalize-url@npm:8.0.0" @@ -9945,7 +8295,7 @@ __metadata: languageName: node linkType: hard -"p-limit@npm:^3.0.2, p-limit@npm:^3.1.0": +"p-limit@npm:^3.0.2": version: 3.1.0 resolution: "p-limit@npm:3.1.0" dependencies: @@ -10075,33 +8425,49 @@ __metadata: languageName: node linkType: hard -"picocolors@npm:^1.0.0": - version: 1.0.0 - resolution: "picocolors@npm:1.0.0" - checksum: 10c0/20a5b249e331c14479d94ec6817a182fd7a5680debae82705747b2db7ec50009a5f6648d0621c561b0572703f84dbef0858abcbd5856d3c5511426afcb1961f7 +"pathe@npm:^2.0.3": + version: 2.0.3 + resolution: "pathe@npm:2.0.3" + checksum: 10c0/c118dc5a8b5c4166011b2b70608762e260085180bb9e33e80a50dcdb1e78c010b1624f4280c492c92b05fc276715a4c357d1f9edc570f8f1b3d90b6839ebaca1 languageName: node linkType: hard -"picomatch@npm:^2.0.4, picomatch@npm:^2.2.3, picomatch@npm:^2.3.1": +"pathval@npm:^2.0.0": + version: 2.0.0 + resolution: "pathval@npm:2.0.0" + checksum: 10c0/602e4ee347fba8a599115af2ccd8179836a63c925c23e04bd056d0674a64b39e3a081b643cc7bc0b84390517df2d800a46fcc5598d42c155fe4977095c2f77c5 + languageName: node + linkType: hard + +"picocolors@npm:^1.1.1": + version: 1.1.1 + resolution: "picocolors@npm:1.1.1" + checksum: 10c0/e2e3e8170ab9d7c7421969adaa7e1b31434f789afb9b3f115f6b96d91945041ac3ceb02e9ec6fe6510ff036bcc0bf91e69a1772edc0b707e12b19c0f2d6bcf58 + languageName: node + linkType: hard + +"picomatch@npm:^2.2.3, picomatch@npm:^2.3.1": version: 2.3.1 resolution: "picomatch@npm:2.3.1" checksum: 10c0/26c02b8d06f03206fc2ab8d16f19960f2ff9e81a658f831ecb656d8f17d9edc799e8364b1f4a7873e89d9702dff96204be0fa26fe4181f6843f040f819dac4be languageName: node linkType: hard -"pirates@npm:^4.0.4": - version: 4.0.6 - resolution: "pirates@npm:4.0.6" - checksum: 10c0/00d5fa51f8dded94d7429700fb91a0c1ead00ae2c7fd27089f0c5b63e6eca36197fe46384631872690a66f390c5e27198e99006ab77ae472692ab9c2ca903f36 +"picomatch@npm:^4.0.2": + version: 4.0.2 + resolution: "picomatch@npm:4.0.2" + checksum: 10c0/7c51f3ad2bb42c776f49ebf964c644958158be30d0a510efd5a395e8d49cb5acfed5b82c0c5b365523ce18e6ab85013c9ebe574f60305892ec3fa8eee8304ccc languageName: node linkType: hard -"pkg-dir@npm:^4.2.0": - version: 4.2.0 - resolution: "pkg-dir@npm:4.2.0" +"postcss@npm:^8.5.3": + version: 8.5.6 + resolution: "postcss@npm:8.5.6" dependencies: - find-up: "npm:^4.0.0" - checksum: 10c0/c56bda7769e04907a88423feb320babaed0711af8c436ce3e56763ab1021ba107c7b0cafb11cde7529f669cfc22bffcaebffb573645cbd63842ea9fb17cd7728 + nanoid: "npm:^3.3.11" + picocolors: "npm:^1.1.1" + source-map-js: "npm:^1.2.1" + checksum: 10c0/5127cc7c91ed7a133a1b7318012d8bfa112da9ef092dddf369ae699a1f10ebbd89b1b9f25f3228795b84585c72aabd5ced5fc11f2ba467eedf7b081a66fad024 languageName: node linkType: hard @@ -10161,7 +8527,7 @@ __metadata: languageName: node linkType: hard -"prompts@npm:2.4.2, prompts@npm:^2.0.1": +"prompts@npm:2.4.2": version: 2.4.2 resolution: "prompts@npm:2.4.2" dependencies: @@ -10206,7 +8572,7 @@ __metadata: languageName: node linkType: hard -"pure-rand@npm:^6.0.0, pure-rand@npm:^6.1.0": +"pure-rand@npm:^6.1.0": version: 6.1.0 resolution: "pure-rand@npm:6.1.0" checksum: 10c0/1abe217897bf74dcb3a0c9aba3555fe975023147b48db540aa2faf507aee91c03bf54f6aef0eb2bf59cc259a16d06b28eca37f0dc426d94f4692aeff02fb0e65 @@ -10269,15 +8635,6 @@ __metadata: languageName: node linkType: hard -"rdf-canonize@npm:^4.0.1": - version: 4.0.1 - resolution: "rdf-canonize@npm:4.0.1" - dependencies: - setimmediate: "npm:^1.0.5" - checksum: 10c0/8f6040847c5731817cc5ad95ca16caa588fba76c94ee3b24f282c9a3054f36226560bcb33bed8a173903960af1b9937e21db6e0dc2e90caa749682fff8228250 - languageName: node - linkType: hard - "rdf-data-factory@npm:^1.0.1, rdf-data-factory@npm:^1.1.0, rdf-data-factory@npm:^1.1.1, rdf-data-factory@npm:^1.1.2": version: 1.1.2 resolution: "rdf-data-factory@npm:1.1.2" @@ -10738,13 +9095,6 @@ __metadata: languageName: node linkType: hard -"regenerator-runtime@npm:^0.14.0": - version: 0.14.1 - resolution: "regenerator-runtime@npm:0.14.1" - checksum: 10c0/1b16eb2c4bceb1665c89de70dcb64126a22bc8eb958feef3cd68fe11ac6d2a4899b5cd1b80b0774c7c03591dc57d16631a7f69d2daa2ec98100e2f29f7ec4cc4 - languageName: node - linkType: hard - "relative-to-absolute-iri@npm:^1.0.0, relative-to-absolute-iri@npm:^1.0.2, relative-to-absolute-iri@npm:^1.0.5, relative-to-absolute-iri@npm:^1.0.6, relative-to-absolute-iri@npm:^1.0.7": version: 1.0.7 resolution: "relative-to-absolute-iri@npm:1.0.7" @@ -10766,15 +9116,6 @@ __metadata: languageName: node linkType: hard -"resolve-cwd@npm:^3.0.0": - version: 3.0.0 - resolution: "resolve-cwd@npm:3.0.0" - dependencies: - resolve-from: "npm:^5.0.0" - checksum: 10c0/e608a3ebd15356264653c32d7ecbc8fd702f94c6703ea4ac2fb81d9c359180cba0ae2e6b71faa446631ed6145454d5a56b227efc33a2d40638ac13f8beb20ee4 - languageName: node - linkType: hard - "resolve-from@npm:5.0.0, resolve-from@npm:^5.0.0": version: 5.0.0 resolution: "resolve-from@npm:5.0.0" @@ -10805,14 +9146,7 @@ __metadata: languageName: node linkType: hard -"resolve.exports@npm:^2.0.0": - version: 2.0.2 - resolution: "resolve.exports@npm:2.0.2" - checksum: 10c0/cc4cffdc25447cf34730f388dca5021156ba9302a3bad3d7f168e790dc74b2827dff603f1bc6ad3d299bac269828dca96dd77e036dc9fba6a2a1807c47ab5c98 - languageName: node - linkType: hard - -"resolve@npm:^1.1.6, resolve@npm:^1.10.0, resolve@npm:^1.20.0": +"resolve@npm:^1.1.6, resolve@npm:^1.10.0": version: 1.22.8 resolution: "resolve@npm:1.22.8" dependencies: @@ -10825,7 +9159,7 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@npm%3A^1.1.6#optional!builtin, resolve@patch:resolve@npm%3A^1.10.0#optional!builtin, resolve@patch:resolve@npm%3A^1.20.0#optional!builtin": +"resolve@patch:resolve@npm%3A^1.1.6#optional!builtin, resolve@patch:resolve@npm%3A^1.10.0#optional!builtin": version: 1.22.8 resolution: "resolve@patch:resolve@npm%3A1.22.8#optional!builtin::version=1.22.8&hash=c3c19d" dependencies: @@ -10889,6 +9223,81 @@ __metadata: languageName: node linkType: hard +"rollup@npm:^4.34.9": + version: 4.44.0 + resolution: "rollup@npm:4.44.0" + dependencies: + "@rollup/rollup-android-arm-eabi": "npm:4.44.0" + "@rollup/rollup-android-arm64": "npm:4.44.0" + "@rollup/rollup-darwin-arm64": "npm:4.44.0" + "@rollup/rollup-darwin-x64": "npm:4.44.0" + "@rollup/rollup-freebsd-arm64": "npm:4.44.0" + "@rollup/rollup-freebsd-x64": "npm:4.44.0" + "@rollup/rollup-linux-arm-gnueabihf": "npm:4.44.0" + "@rollup/rollup-linux-arm-musleabihf": "npm:4.44.0" + "@rollup/rollup-linux-arm64-gnu": "npm:4.44.0" + "@rollup/rollup-linux-arm64-musl": "npm:4.44.0" + "@rollup/rollup-linux-loongarch64-gnu": "npm:4.44.0" + "@rollup/rollup-linux-powerpc64le-gnu": "npm:4.44.0" + "@rollup/rollup-linux-riscv64-gnu": "npm:4.44.0" + "@rollup/rollup-linux-riscv64-musl": "npm:4.44.0" + "@rollup/rollup-linux-s390x-gnu": "npm:4.44.0" + "@rollup/rollup-linux-x64-gnu": "npm:4.44.0" + "@rollup/rollup-linux-x64-musl": "npm:4.44.0" + "@rollup/rollup-win32-arm64-msvc": "npm:4.44.0" + "@rollup/rollup-win32-ia32-msvc": "npm:4.44.0" + "@rollup/rollup-win32-x64-msvc": "npm:4.44.0" + "@types/estree": "npm:1.0.8" + fsevents: "npm:~2.3.2" + dependenciesMeta: + "@rollup/rollup-android-arm-eabi": + optional: true + "@rollup/rollup-android-arm64": + optional: true + "@rollup/rollup-darwin-arm64": + optional: true + "@rollup/rollup-darwin-x64": + optional: true + "@rollup/rollup-freebsd-arm64": + optional: true + "@rollup/rollup-freebsd-x64": + optional: true + "@rollup/rollup-linux-arm-gnueabihf": + optional: true + "@rollup/rollup-linux-arm-musleabihf": + optional: true + "@rollup/rollup-linux-arm64-gnu": + optional: true + "@rollup/rollup-linux-arm64-musl": + optional: true + "@rollup/rollup-linux-loongarch64-gnu": + optional: true + "@rollup/rollup-linux-powerpc64le-gnu": + optional: true + "@rollup/rollup-linux-riscv64-gnu": + optional: true + "@rollup/rollup-linux-riscv64-musl": + optional: true + "@rollup/rollup-linux-s390x-gnu": + optional: true + "@rollup/rollup-linux-x64-gnu": + optional: true + "@rollup/rollup-linux-x64-musl": + optional: true + "@rollup/rollup-win32-arm64-msvc": + optional: true + "@rollup/rollup-win32-ia32-msvc": + optional: true + "@rollup/rollup-win32-x64-msvc": + optional: true + fsevents: + optional: true + bin: + rollup: dist/bin/rollup + checksum: 10c0/ff3e0741f2fc7b7b183079628cf50fcfc9163bef86ecfbc9f4e4023adfdee375b7075940963514e2bc4969764688d38d67095bce038b0ad5d572207f114afff5 + languageName: node + linkType: hard + "run-parallel@npm:^1.1.9": version: 1.2.0 resolution: "run-parallel@npm:1.2.0" @@ -10898,15 +9307,6 @@ __metadata: languageName: node linkType: hard -"rxjs@npm:^7.8.1": - version: 7.8.1 - resolution: "rxjs@npm:7.8.1" - dependencies: - tslib: "npm:^2.1.0" - checksum: 10c0/3c49c1ecd66170b175c9cacf5cef67f8914dcbc7cd0162855538d365c83fea631167cacb644b3ce533b2ea0e9a4d0b12175186985f89d75abe73dbd8f7f06f68 - languageName: node - linkType: hard - "safe-buffer@npm:5.2.1, safe-buffer@npm:^5.0.1, safe-buffer@npm:~5.2.0": version: 5.2.1 resolution: "safe-buffer@npm:5.2.1" @@ -10955,7 +9355,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:7.7.0, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.5.3, semver@npm:^7.5.4": +"semver@npm:7.7.0, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7": version: 7.7.0 resolution: "semver@npm:7.7.0" bin: @@ -10964,24 +9364,6 @@ __metadata: languageName: node linkType: hard -"semver@npm:^6.3.0, semver@npm:^6.3.1": - version: 6.3.1 - resolution: "semver@npm:6.3.1" - bin: - semver: bin/semver.js - checksum: 10c0/e3d79b609071caa78bcb6ce2ad81c7966a46a7431d9d58b8800cfa9cb6a63699b3899a0e4bcce36167a284578212d9ae6942b6929ba4aa5015c079a67751d42d - languageName: node - linkType: hard - -"serialize-error@npm:^8.0.1, serialize-error@npm:^8.1.0": - version: 8.1.0 - resolution: "serialize-error@npm:8.1.0" - dependencies: - type-fest: "npm:^0.20.2" - checksum: 10c0/8cfd89f43ca93e283c5f1d16178a536bdfac9bc6029f4a9df988610cc399bc4f2478d1f10ce40b9dff66b863a5158a19b438fbec929045c96d92174f6bca1e88 - languageName: node - linkType: hard - "setimmediate@npm:^1.0.5": version: 1.0.5 resolution: "setimmediate@npm:1.0.5" @@ -11033,13 +9415,6 @@ __metadata: languageName: node linkType: hard -"shell-quote@npm:^1.8.1": - version: 1.8.1 - resolution: "shell-quote@npm:1.8.1" - checksum: 10c0/8cec6fd827bad74d0a49347057d40dfea1e01f12a6123bf82c4649f3ef152fc2bc6d6176e6376bffcd205d9d0ccb4f1f9acae889384d20baff92186f01ea455a - languageName: node - linkType: hard - "shelljs@npm:^0.8.5": version: 0.8.5 resolution: "shelljs@npm:0.8.5" @@ -11065,7 +9440,14 @@ __metadata: languageName: node linkType: hard -"signal-exit@npm:^3.0.2, signal-exit@npm:^3.0.3, signal-exit@npm:^3.0.7": +"siginfo@npm:^2.0.0": + version: 2.0.0 + resolution: "siginfo@npm:2.0.0" + checksum: 10c0/3def8f8e516fbb34cb6ae415b07ccc5d9c018d85b4b8611e3dc6f8be6d1899f693a4382913c9ed51a06babb5201639d76453ab297d1c54a456544acf5c892e34 + languageName: node + linkType: hard + +"signal-exit@npm:^3.0.2, signal-exit@npm:^3.0.3": version: 3.0.7 resolution: "signal-exit@npm:3.0.7" checksum: 10c0/25d272fa73e146048565e08f3309d5b942c1979a6f4a58a8c59d5fa299728e9c2fcd1a759ec870863b1fd38653670240cd420dad2ad9330c71f36608a6a1c912 @@ -11137,17 +9519,14 @@ __metadata: languageName: node linkType: hard -"source-map-support@npm:0.5.13": - version: 0.5.13 - resolution: "source-map-support@npm:0.5.13" - dependencies: - buffer-from: "npm:^1.0.0" - source-map: "npm:^0.6.0" - checksum: 10c0/137539f8c453fa0f496ea42049ab5da4569f96781f6ac8e5bfda26937be9494f4e8891f523c5f98f0e85f71b35d74127a00c46f83f6a4f54672b58d53202565e +"source-map-js@npm:^1.2.1": + version: 1.2.1 + resolution: "source-map-js@npm:1.2.1" + checksum: 10c0/7bda1fc4c197e3c6ff17de1b8b2c20e60af81b63a52cb32ec5a5d67a20a7d42651e2cb34ebe93833c5a2a084377e17455854fee3e21e7925c64a51b6a52b0faf languageName: node linkType: hard -"source-map@npm:^0.6.0, source-map@npm:^0.6.1": +"source-map@npm:^0.6.1": version: 0.6.1 resolution: "source-map@npm:0.6.1" checksum: 10c0/ab55398007c5e5532957cb0beee2368529618ac0ab372d789806f5718123cc4367d57de3904b4e6a4170eb5a0b0f41373066d02ca0735a0c4d75c7d328d3e011 @@ -11228,13 +9607,6 @@ __metadata: languageName: node linkType: hard -"spawn-command@npm:0.0.2": - version: 0.0.2 - resolution: "spawn-command@npm:0.0.2" - checksum: 10c0/b22f2d71239e6e628a400831861ba747750bbb40c0a53323754cf7b84330b73d81e40ff1f9055e6d1971818679510208a9302e13d9ff3b32feb67e74d7a1b3ef - languageName: node - linkType: hard - "spdx-correct@npm:^3.0.0": version: 3.2.0 resolution: "spdx-correct@npm:3.2.0" @@ -11278,13 +9650,6 @@ __metadata: languageName: node linkType: hard -"sprintf-js@npm:~1.0.2": - version: 1.0.3 - resolution: "sprintf-js@npm:1.0.3" - checksum: 10c0/ecadcfe4c771890140da5023d43e190b7566d9cf8b2d238600f31bec0fc653f328da4450eb04bd59a431771a8e9cc0e118f0aa3974b683a4981b4e07abc2a5bb - languageName: node - linkType: hard - "ssri@npm:^10.0.0": version: 10.0.5 resolution: "ssri@npm:10.0.5" @@ -11310,6 +9675,13 @@ __metadata: languageName: node linkType: hard +"stackback@npm:0.0.2": + version: 0.0.2 + resolution: "stackback@npm:0.0.2" + checksum: 10c0/89a1416668f950236dd5ac9f9a6b2588e1b9b62b1b6ad8dff1bfc5d1a15dbf0aafc9b52d2226d00c28dffff212da464eaeebfc6b7578b9d180cef3e3782c5983 + languageName: node + linkType: hard + "standard-as-callback@npm:^2.1.0": version: 2.1.0 resolution: "standard-as-callback@npm:2.1.0" @@ -11331,6 +9703,13 @@ __metadata: languageName: node linkType: hard +"std-env@npm:^3.9.0": + version: 3.9.0 + resolution: "std-env@npm:3.9.0" + checksum: 10c0/4a6f9218aef3f41046c3c7ecf1f98df00b30a07f4f35c6d47b28329bc2531eef820828951c7d7b39a1c5eb19ad8a46e3ddfc7deb28f0a2f3ceebee11bab7ba50 + languageName: node + linkType: hard + "stdin-discarder@npm:^0.2.2": version: 0.2.2 resolution: "stdin-discarder@npm:0.2.2" @@ -11372,16 +9751,6 @@ __metadata: languageName: node linkType: hard -"string-length@npm:^4.0.1": - version: 4.0.2 - resolution: "string-length@npm:4.0.2" - dependencies: - char-regex: "npm:^1.0.2" - strip-ansi: "npm:^6.0.0" - checksum: 10c0/1cd77409c3d7db7bc59406f6bcc9ef0783671dcbabb23597a1177c166906ef2ee7c8290f78cae73a8aec858768f189d2cb417797df5e15ec4eb5e16b3346340c - languageName: node - linkType: hard - "string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3": version: 4.2.3 resolution: "string-width@npm:4.2.3" @@ -11472,6 +9841,15 @@ __metadata: languageName: node linkType: hard +"strip-literal@npm:^3.0.0": + version: 3.0.0 + resolution: "strip-literal@npm:3.0.0" + dependencies: + js-tokens: "npm:^9.0.1" + checksum: 10c0/d81657f84aba42d4bbaf2a677f7e7f34c1f3de5a6726db8bc1797f9c0b303ba54d4660383a74bde43df401cf37cce1dff2c842c55b077a4ceee11f9e31fba828 + languageName: node + linkType: hard + "structured-headers@npm:^1.0.1": version: 1.0.1 resolution: "structured-headers@npm:1.0.1" @@ -11497,15 +9875,6 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:^8.0.0, supports-color@npm:^8.1.1": - version: 8.1.1 - resolution: "supports-color@npm:8.1.1" - dependencies: - has-flag: "npm:^4.0.0" - checksum: 10c0/ea1d3c275dd604c974670f63943ed9bd83623edc102430c05adb8efc56ba492746b6e95386e7831b872ec3807fd89dd8eb43f735195f37b5ec343e4234cc7e89 - languageName: node - linkType: hard - "supports-preserve-symlinks-flag@npm:^1.0.0": version: 1.0.0 resolution: "supports-preserve-symlinks-flag@npm:1.0.0" @@ -11587,17 +9956,6 @@ __metadata: languageName: node linkType: hard -"test-exclude@npm:^6.0.0": - version: 6.0.0 - resolution: "test-exclude@npm:6.0.0" - dependencies: - "@istanbuljs/schema": "npm:^0.1.2" - glob: "npm:^7.1.4" - minimatch: "npm:^3.0.4" - checksum: 10c0/019d33d81adff3f9f1bfcff18125fb2d3c65564f437d9be539270ee74b994986abb8260c7c2ce90e8f30162178b09dbbce33c6389273afac4f36069c48521f57 - languageName: node - linkType: hard - "text-extensions@npm:^1.0.0": version: 1.9.0 resolution: "text-extensions@npm:1.9.0" @@ -11649,24 +10007,55 @@ __metadata: languageName: node linkType: hard -"tmp@npm:^0.2.1, tmp@npm:^0.2.3": - version: 0.2.3 - resolution: "tmp@npm:0.2.3" - checksum: 10c0/3e809d9c2f46817475b452725c2aaa5d11985cf18d32a7a970ff25b568438e2c076c2e8609224feef3b7923fa9749b74428e3e634f6b8e520c534eef2fd24125 +"tinybench@npm:^2.9.0": + version: 2.9.0 + resolution: "tinybench@npm:2.9.0" + checksum: 10c0/c3500b0f60d2eb8db65250afe750b66d51623057ee88720b7f064894a6cb7eb93360ca824a60a31ab16dab30c7b1f06efe0795b352e37914a9d4bad86386a20c languageName: node linkType: hard -"tmpl@npm:1.0.5": - version: 1.0.5 - resolution: "tmpl@npm:1.0.5" - checksum: 10c0/f935537799c2d1922cb5d6d3805f594388f75338fe7a4a9dac41504dd539704ca4db45b883b52e7b0aa5b2fd5ddadb1452bf95cd23a69da2f793a843f9451cc9 +"tinyexec@npm:^0.3.2": + version: 0.3.2 + resolution: "tinyexec@npm:0.3.2" + checksum: 10c0/3efbf791a911be0bf0821eab37a3445c2ba07acc1522b1fa84ae1e55f10425076f1290f680286345ed919549ad67527d07281f1c19d584df3b74326909eb1f90 + languageName: node + linkType: hard + +"tinyglobby@npm:^0.2.13, tinyglobby@npm:^0.2.14": + version: 0.2.14 + resolution: "tinyglobby@npm:0.2.14" + dependencies: + fdir: "npm:^6.4.4" + picomatch: "npm:^4.0.2" + checksum: 10c0/f789ed6c924287a9b7d3612056ed0cda67306cd2c80c249fd280cf1504742b12583a2089b61f4abbd24605f390809017240e250241f09938054c9b363e51c0a6 languageName: node linkType: hard -"to-fast-properties@npm:^2.0.0": +"tinypool@npm:^1.1.1": + version: 1.1.1 + resolution: "tinypool@npm:1.1.1" + checksum: 10c0/bf26727d01443061b04fa863f571016950888ea994ba0cd8cba3a1c51e2458d84574341ab8dbc3664f1c3ab20885c8cf9ff1cc4b18201f04c2cde7d317fff69b + languageName: node + linkType: hard + +"tinyrainbow@npm:^2.0.0": version: 2.0.0 - resolution: "to-fast-properties@npm:2.0.0" - checksum: 10c0/b214d21dbfb4bce3452b6244b336806ffea9c05297148d32ebb428d5c43ce7545bdfc65a1ceb58c9ef4376a65c0cb2854d645f33961658b3e3b4f84910ddcdd7 + resolution: "tinyrainbow@npm:2.0.0" + checksum: 10c0/c83c52bef4e0ae7fb8ec6a722f70b5b6fa8d8be1c85792e829f56c0e1be94ab70b293c032dc5048d4d37cfe678f1f5babb04bdc65fd123098800148ca989184f + languageName: node + linkType: hard + +"tinyspy@npm:^4.0.3": + version: 4.0.3 + resolution: "tinyspy@npm:4.0.3" + checksum: 10c0/0a92a18b5350945cc8a1da3a22c9ad9f4e2945df80aaa0c43e1b3a3cfb64d8501e607ebf0305e048e3c3d3e0e7f8eb10cea27dc17c21effb73e66c4a3be36373 + languageName: node + linkType: hard + +"tmp@npm:^0.2.1, tmp@npm:^0.2.3": + version: 0.2.3 + resolution: "tmp@npm:0.2.3" + checksum: 10c0/3e809d9c2f46817475b452725c2aaa5d11985cf18d32a7a970ff25b568438e2c076c2e8609224feef3b7923fa9749b74428e3e634f6b8e520c534eef2fd24125 languageName: node linkType: hard @@ -11700,15 +10089,6 @@ __metadata: languageName: node linkType: hard -"tree-kill@npm:^1.2.2": - version: 1.2.2 - resolution: "tree-kill@npm:1.2.2" - bin: - tree-kill: cli.js - checksum: 10c0/7b1b7c7f17608a8f8d20a162e7957ac1ef6cd1636db1aba92f4e072dc31818c2ff0efac1e3d91064ede67ed5dc57c565420531a8134090a12ac10cf792ab14d2 - languageName: node - linkType: hard - "trim-newlines@npm:^3.0.0": version: 3.0.1 resolution: "trim-newlines@npm:3.0.1" @@ -11730,40 +10110,7 @@ __metadata: languageName: node linkType: hard -"ts-jest@npm:^29.1.2": - version: 29.1.2 - resolution: "ts-jest@npm:29.1.2" - dependencies: - bs-logger: "npm:0.x" - fast-json-stable-stringify: "npm:2.x" - jest-util: "npm:^29.0.0" - json5: "npm:^2.2.3" - lodash.memoize: "npm:4.x" - make-error: "npm:1.x" - semver: "npm:^7.5.3" - yargs-parser: "npm:^21.0.1" - 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 - bin: - ts-jest: cli.js - checksum: 10c0/c2f51f0241f89d127d41392decbcb83b5dfd5e57ab9d50220aa7b7e2f9b3f3b07ccdbba33311284df1c41941879e4ddfad44b15a9d0da4b74bd1b98702b729df - languageName: node - linkType: hard - -"ts-node@npm:^10.8.1, ts-node@npm:^10.9.2": +"ts-node@npm:^10.8.1": version: 10.9.2 resolution: "ts-node@npm:10.9.2" dependencies: @@ -11815,13 +10162,6 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^2.1.0": - version: 2.6.2 - resolution: "tslib@npm:2.6.2" - checksum: 10c0/e03a8a4271152c8b26604ed45535954c0a45296e32445b4b87f8a5abdb2421f40b59b4ca437c4346af0f28179780d604094eb64546bee2019d903d01c6c19bdb - languageName: node - linkType: hard - "tsscmp@npm:1.0.6": version: 1.0.6 resolution: "tsscmp@npm:1.0.6" @@ -11841,10 +10181,10 @@ __metadata: linkType: hard "tsx@npm:^4.19.2": - version: 4.19.2 - resolution: "tsx@npm:4.19.2" + version: 4.20.3 + resolution: "tsx@npm:4.20.3" dependencies: - esbuild: "npm:~0.23.0" + esbuild: "npm:~0.25.0" fsevents: "npm:~2.3.3" get-tsconfig: "npm:^4.7.5" dependenciesMeta: @@ -11852,7 +10192,7 @@ __metadata: optional: true bin: tsx: dist/cli.mjs - checksum: 10c0/63164b889b1d170403e4d8753a6755dec371f220f5ce29a8e88f1f4d6085a784a12d8dc2ee669116611f2c72757ac9beaa3eea5c452796f541bdd2dc11753721 + checksum: 10c0/6ff0d91ed046ec743fac7ed60a07f3c025e5b71a5aaf58f3d2a6b45e4db114c83e59ebbb078c8e079e48d3730b944a02bc0de87695088aef4ec8bbc705dc791b languageName: node linkType: hard @@ -11865,13 +10205,6 @@ __metadata: languageName: node linkType: hard -"type-detect@npm:4.0.8": - version: 4.0.8 - resolution: "type-detect@npm:4.0.8" - checksum: 10c0/8fb9a51d3f365a7de84ab7f73b653534b61b622aa6800aecdb0f1095a4a646d3f5eb295322127b6573db7982afcd40ab492d038cf825a42093a58b1e1353e0bd - languageName: node - linkType: hard - "type-fest@npm:^0.18.0": version: 0.18.1 resolution: "type-fest@npm:0.18.1" @@ -11886,13 +10219,6 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:^0.21.3": - version: 0.21.3 - resolution: "type-fest@npm:0.21.3" - checksum: 10c0/902bd57bfa30d51d4779b641c2bc403cdf1371fb9c91d3c058b0133694fcfdb817aef07a47f40faf79039eecbaa39ee9d3c532deff244f3a19ce68cea71a61e8 - languageName: node - linkType: hard - "type-fest@npm:^0.6.0": version: 0.6.0 resolution: "type-fest@npm:0.6.0" @@ -11934,13 +10260,13 @@ __metadata: languageName: node linkType: hard -"typescript@npm:^5.3.3": - version: 5.3.3 - resolution: "typescript@npm:5.3.3" +"typescript@npm:^5.8.3": + version: 5.8.3 + resolution: "typescript@npm:5.8.3" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/e33cef99d82573624fc0f854a2980322714986bc35b9cb4d1ce736ed182aeab78e2cb32b385efa493b2a976ef52c53e20d6c6918312353a91850e2b76f1ea44f + checksum: 10c0/5f8bb01196e542e64d44db3d16ee0e4063ce4f3e3966df6005f2588e86d91c03e1fb131c2581baf0fb65ee79669eea6e161cd448178986587e9f6844446dbb48 languageName: node linkType: hard @@ -11954,13 +10280,13 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@npm%3A^5.3.3#optional!builtin": - version: 5.3.3 - resolution: "typescript@patch:typescript@npm%3A5.3.3#optional!builtin::version=5.3.3&hash=e012d7" +"typescript@patch:typescript@npm%3A^5.8.3#optional!builtin": + version: 5.8.3 + resolution: "typescript@patch:typescript@npm%3A5.8.3#optional!builtin::version=5.8.3&hash=5786d5" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/1d0a5f4ce496c42caa9a30e659c467c5686eae15d54b027ee7866744952547f1be1262f2d40de911618c242b510029d51d43ff605dba8fb740ec85ca2d3f9500 + checksum: 10c0/39117e346ff8ebd87ae1510b3a77d5d92dae5a89bde588c747d25da5c146603a99c8ee588c7ef80faaf123d89ed46f6dbd918d534d641083177d5fac38b8a1cb languageName: node linkType: hard @@ -11973,10 +10299,10 @@ __metadata: languageName: node linkType: hard -"undici-types@npm:~6.19.2": - version: 6.19.8 - resolution: "undici-types@npm:6.19.8" - checksum: 10c0/078afa5990fba110f6824823ace86073b4638f1d5112ee26e790155f481f2a868cc3e0615505b6f4282bdf74a3d8caad715fd809e870c2bb0704e3ea6082f344 +"undici-types@npm:~6.21.0": + version: 6.21.0 + resolution: "undici-types@npm:6.21.0" + checksum: 10c0/c01ed51829b10aa72fc3ce64b747f8e74ae9b60eafa19a7b46ef624403508a54c526ffab06a14a26b3120d055e1104d7abe7c9017e83ced038ea5cf52f8d5e04 languageName: node linkType: hard @@ -11989,13 +10315,6 @@ __metadata: languageName: node linkType: hard -"undici@npm:^6.6.2": - version: 6.21.1 - resolution: "undici@npm:6.21.1" - checksum: 10c0/d604080e4f8db89b35a63b483b5f96a5f8b19ec9f716e934639345449405809d2997e1dd7212d67048f210e54534143384d712bd9075e4394f0788895ef9ca8e - languageName: node - linkType: hard - "unicorn-magic@npm:^0.1.0": version: 0.1.0 resolution: "unicorn-magic@npm:0.1.0" @@ -12042,20 +10361,6 @@ __metadata: languageName: node linkType: hard -"update-browserslist-db@npm:^1.0.13": - version: 1.0.13 - resolution: "update-browserslist-db@npm:1.0.13" - dependencies: - escalade: "npm:^3.1.1" - picocolors: "npm:^1.0.0" - peerDependencies: - browserslist: ">= 4.21.0" - bin: - update-browserslist-db: cli.js - checksum: 10c0/e52b8b521c78ce1e0c775f356cd16a9c22c70d25f3e01180839c407a5dc787fb05a13f67560cbaf316770d26fa99f78f1acd711b1b54a4f35d4820d4ea7136e6 - languageName: node - linkType: hard - "uri-js@npm:^4.2.2": version: 4.4.1 resolution: "uri-js@npm:4.4.1" @@ -12128,17 +10433,6 @@ __metadata: languageName: node linkType: hard -"v8-to-istanbul@npm:^9.0.1": - version: 9.1.3 - resolution: "v8-to-istanbul@npm:9.1.3" - dependencies: - "@jridgewell/trace-mapping": "npm:^0.3.12" - "@types/istanbul-lib-coverage": "npm:^2.0.1" - convert-source-map: "npm:^2.0.0" - checksum: 10c0/7acfc460731b629a0d547b231e9d510aaa826df67f4deeaeeb991b492f78faf3bb1aa4b54fa0f9b06d815bc69eb0a04a6c2180c16ba43a83cc5e5490fa160a96 - languageName: node - linkType: hard - "validate-iri@npm:^1.0.0": version: 1.0.1 resolution: "validate-iri@npm:1.0.1" @@ -12170,12 +10464,129 @@ __metadata: languageName: node linkType: hard -"walker@npm:^1.0.8": - version: 1.0.8 - resolution: "walker@npm:1.0.8" +"vite-node@npm:3.2.4": + version: 3.2.4 + resolution: "vite-node@npm:3.2.4" + dependencies: + cac: "npm:^6.7.14" + debug: "npm:^4.4.1" + es-module-lexer: "npm:^1.7.0" + pathe: "npm:^2.0.3" + vite: "npm:^5.0.0 || ^6.0.0 || ^7.0.0-0" + bin: + vite-node: vite-node.mjs + checksum: 10c0/6ceca67c002f8ef6397d58b9539f80f2b5d79e103a18367288b3f00a8ab55affa3d711d86d9112fce5a7fa658a212a087a005a045eb8f4758947dd99af2a6c6b + languageName: node + linkType: hard + +"vite@npm:^5.0.0 || ^6.0.0 || ^7.0.0-0, vite@npm:^6.3.5": + version: 6.3.5 + resolution: "vite@npm:6.3.5" dependencies: - makeerror: "npm:1.0.12" - checksum: 10c0/a17e037bccd3ca8a25a80cb850903facdfed0de4864bd8728f1782370715d679fa72e0a0f5da7c1c1379365159901e5935f35be531229da53bbfc0efdabdb48e + esbuild: "npm:^0.25.0" + fdir: "npm:^6.4.4" + fsevents: "npm:~2.3.3" + picomatch: "npm:^4.0.2" + postcss: "npm:^8.5.3" + rollup: "npm:^4.34.9" + tinyglobby: "npm:^0.2.13" + peerDependencies: + "@types/node": ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: ">=1.21.0" + less: "*" + lightningcss: ^1.21.0 + sass: "*" + sass-embedded: "*" + stylus: "*" + sugarss: "*" + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + dependenciesMeta: + fsevents: + optional: true + peerDependenciesMeta: + "@types/node": + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + bin: + vite: bin/vite.js + checksum: 10c0/df70201659085133abffc6b88dcdb8a57ef35f742a01311fc56a4cfcda6a404202860729cc65a2c401a724f6e25f9ab40ce4339ed4946f550541531ced6fe41c + languageName: node + linkType: hard + +"vitest@npm:^3.2.3": + version: 3.2.4 + resolution: "vitest@npm:3.2.4" + dependencies: + "@types/chai": "npm:^5.2.2" + "@vitest/expect": "npm:3.2.4" + "@vitest/mocker": "npm:3.2.4" + "@vitest/pretty-format": "npm:^3.2.4" + "@vitest/runner": "npm:3.2.4" + "@vitest/snapshot": "npm:3.2.4" + "@vitest/spy": "npm:3.2.4" + "@vitest/utils": "npm:3.2.4" + chai: "npm:^5.2.0" + debug: "npm:^4.4.1" + expect-type: "npm:^1.2.1" + magic-string: "npm:^0.30.17" + pathe: "npm:^2.0.3" + picomatch: "npm:^4.0.2" + std-env: "npm:^3.9.0" + tinybench: "npm:^2.9.0" + tinyexec: "npm:^0.3.2" + tinyglobby: "npm:^0.2.14" + tinypool: "npm:^1.1.1" + tinyrainbow: "npm:^2.0.0" + vite: "npm:^5.0.0 || ^6.0.0 || ^7.0.0-0" + vite-node: "npm:3.2.4" + why-is-node-running: "npm:^2.3.0" + peerDependencies: + "@edge-runtime/vm": "*" + "@types/debug": ^4.1.12 + "@types/node": ^18.0.0 || ^20.0.0 || >=22.0.0 + "@vitest/browser": 3.2.4 + "@vitest/ui": 3.2.4 + happy-dom: "*" + jsdom: "*" + peerDependenciesMeta: + "@edge-runtime/vm": + optional: true + "@types/debug": + optional: true + "@types/node": + optional: true + "@vitest/browser": + optional: true + "@vitest/ui": + optional: true + happy-dom: + optional: true + jsdom: + optional: true + bin: + vitest: vitest.mjs + checksum: 10c0/5bf53ede3ae6a0e08956d72dab279ae90503f6b5a05298a6a5e6ef47d2fd1ab386aaf48fafa61ed07a0ebfe9e371772f1ccbe5c258dd765206a8218bf2eb79eb languageName: node linkType: hard @@ -12232,6 +10643,18 @@ __metadata: languageName: node linkType: hard +"why-is-node-running@npm:^2.3.0": + version: 2.3.0 + resolution: "why-is-node-running@npm:2.3.0" + dependencies: + siginfo: "npm:^2.0.0" + stackback: "npm:0.0.2" + bin: + why-is-node-running: cli.js + checksum: 10c0/1cde0b01b827d2cf4cb11db962f3958b9175d5d9e7ac7361d1a7b0e2dc6069a263e69118bd974c4f6d0a890ef4eedfe34cf3d5167ec14203dbc9a18620537054 + languageName: node + linkType: hard + "winston-transport@npm:^4.5.0": version: 4.6.0 resolution: "winston-transport@npm:4.6.0" @@ -12298,16 +10721,6 @@ __metadata: languageName: node linkType: hard -"write-file-atomic@npm:^4.0.2": - version: 4.0.2 - resolution: "write-file-atomic@npm:4.0.2" - dependencies: - imurmurhash: "npm:^0.1.4" - signal-exit: "npm:^3.0.7" - checksum: 10c0/a2c282c95ef5d8e1c27b335ae897b5eca00e85590d92a3fd69a437919b7b93ff36a69ea04145da55829d2164e724bc62202cdb5f4b208b425aba0807889375c7 - languageName: node - linkType: hard - "ws@npm:^8.14.2": version: 8.16.0 resolution: "ws@npm:8.16.0" @@ -12337,13 +10750,6 @@ __metadata: languageName: node linkType: hard -"yallist@npm:^3.0.2": - version: 3.1.1 - resolution: "yallist@npm:3.1.1" - checksum: 10c0/c66a5c46bc89af1625476f7f0f2ec3653c1a1791d2f9407cfb4c2ba812a1e1c9941416d71ba9719876530e3340a99925f697142989371b72d93b9ee628afd8c1 - languageName: node - linkType: hard - "yallist@npm:^4.0.0": version: 4.0.0 resolution: "yallist@npm:4.0.0" @@ -12365,14 +10771,14 @@ __metadata: languageName: node linkType: hard -"yargs-parser@npm:^21.0.1, yargs-parser@npm:^21.1.1": +"yargs-parser@npm:^21.1.1": version: 21.1.1 resolution: "yargs-parser@npm:21.1.1" checksum: 10c0/f84b5e48169479d2f402239c59f084cfd1c3acc197a05c59b98bab067452e6b3ea46d4dd8ba2985ba7b3d32a343d77df0debd6b343e5dae3da2aab2cdf5886b2 languageName: node linkType: hard -"yargs@npm:^17.0.0, yargs@npm:^17.3.1, yargs@npm:^17.7.2": +"yargs@npm:^17.0.0, yargs@npm:^17.7.2": version: 17.7.2 resolution: "yargs@npm:17.7.2" dependencies: