From e09b53b20de0e389715d299466a1e1101579dd07 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Mon, 15 Jan 2024 09:31:17 +0100 Subject: [PATCH 01/71] chore: Replace rdf-js import with @rdfjs/types --- src/authorization/AcpUtil.ts | 2 +- src/http/auxiliary/LinkMetadataGenerator.ts | 2 +- src/http/input/metadata/AuthorizationParser.ts | 2 +- src/http/input/metadata/CookieParser.ts | 2 +- src/http/ldp/PostOperationHandler.ts | 2 +- src/http/output/metadata/WacAllowMetadataWriter.ts | 2 +- src/http/representation/N3Patch.ts | 2 +- src/http/representation/RepresentationMetadata.ts | 2 +- src/server/notifications/BaseChannelType.ts | 2 +- src/storage/DataAccessorBasedStore.ts | 3 +-- src/storage/accessors/FileDataAccessor.ts | 2 +- src/storage/accessors/SparqlDataAccessor.ts | 2 +- src/storage/conversion/ContainerToTemplateConverter.ts | 2 +- src/storage/conversion/DynamicJsonToTemplateConverter.ts | 2 +- src/storage/conversion/QuadToRdfConverter.ts | 2 +- src/storage/patch/ImmutableMetadataPatcher.ts | 2 +- src/storage/patch/N3Patcher.ts | 2 +- src/util/QuadUtil.ts | 3 +-- src/util/TermUtil.ts | 2 +- src/util/Vocabularies.ts | 2 +- src/util/errors/HttpError.ts | 2 +- test/unit/authorization/AcpReader.test.ts | 2 +- .../authorization/permissions/N3PatchModesExtractor.test.ts | 2 +- test/unit/http/representation/RepresentationMetadata.test.ts | 2 +- test/unit/storage/accessors/SparqlDataAccessor.test.ts | 2 +- test/unit/storage/patch/RdfPatcher.test.ts | 2 +- test/unit/storage/patch/SparqlUpdatePatcher.test.ts | 2 +- 27 files changed, 27 insertions(+), 29 deletions(-) diff --git a/src/authorization/AcpUtil.ts b/src/authorization/AcpUtil.ts index 4313961b7..8883c0cbf 100644 --- a/src/authorization/AcpUtil.ts +++ b/src/authorization/AcpUtil.ts @@ -7,7 +7,7 @@ import type { IPolicy, } from '@solid/access-control-policy'; import type { Store } from 'n3'; -import type { NamedNode, Term } from 'rdf-js'; +import type { NamedNode, Term } from '@rdfjs/types'; import { ACP } from '../util/Vocabularies'; /** diff --git a/src/http/auxiliary/LinkMetadataGenerator.ts b/src/http/auxiliary/LinkMetadataGenerator.ts index d9f700c04..4af38fa5d 100644 --- a/src/http/auxiliary/LinkMetadataGenerator.ts +++ b/src/http/auxiliary/LinkMetadataGenerator.ts @@ -1,5 +1,5 @@ import { DataFactory } from 'n3'; -import type { NamedNode } from 'rdf-js'; +import type { NamedNode } from '@rdfjs/types'; import { SOLID_META } from '../../util/Vocabularies'; import type { RepresentationMetadata } from '../representation/RepresentationMetadata'; import type { AuxiliaryIdentifierStrategy } from './AuxiliaryIdentifierStrategy'; diff --git a/src/http/input/metadata/AuthorizationParser.ts b/src/http/input/metadata/AuthorizationParser.ts index 89ebd008b..fda49db7d 100644 --- a/src/http/input/metadata/AuthorizationParser.ts +++ b/src/http/input/metadata/AuthorizationParser.ts @@ -1,5 +1,5 @@ import { DataFactory } from 'n3'; -import type { NamedNode } from 'rdf-js'; +import type { NamedNode } from '@rdfjs/types'; import type { HttpRequest } from '../../../server/HttpRequest'; import { matchesAuthorizationScheme } from '../../../util/HeaderUtil'; import { SOLID_META } from '../../../util/Vocabularies'; diff --git a/src/http/input/metadata/CookieParser.ts b/src/http/input/metadata/CookieParser.ts index c3723cb66..d03993cc8 100644 --- a/src/http/input/metadata/CookieParser.ts +++ b/src/http/input/metadata/CookieParser.ts @@ -1,6 +1,6 @@ import { parse } from 'cookie'; import { DataFactory } from 'n3'; -import type { NamedNode } from 'rdf-js'; +import type { NamedNode } from '@rdfjs/types'; import type { HttpRequest } from '../../../server/HttpRequest'; import { SOLID_META } from '../../../util/Vocabularies'; import type { RepresentationMetadata } from '../../representation/RepresentationMetadata'; diff --git a/src/http/ldp/PostOperationHandler.ts b/src/http/ldp/PostOperationHandler.ts index e7bf0bf47..a88ccc923 100644 --- a/src/http/ldp/PostOperationHandler.ts +++ b/src/http/ldp/PostOperationHandler.ts @@ -1,4 +1,4 @@ -import type { Term } from 'rdf-js'; +import type { Term } from '@rdfjs/types'; import { getLoggerFor } from '../../logging/LogUtil'; import type { ResourceStore } from '../../storage/ResourceStore'; import { BadRequestHttpError } from '../../util/errors/BadRequestHttpError'; diff --git a/src/http/output/metadata/WacAllowMetadataWriter.ts b/src/http/output/metadata/WacAllowMetadataWriter.ts index 494d3220d..aec4823ae 100644 --- a/src/http/output/metadata/WacAllowMetadataWriter.ts +++ b/src/http/output/metadata/WacAllowMetadataWriter.ts @@ -1,4 +1,4 @@ -import type { Term } from 'rdf-js'; +import type { Term } from '@rdfjs/types'; import type { HttpResponse } from '../../../server/HttpResponse'; import { addHeader } from '../../../util/HeaderUtil'; import { ACL, AUTH } from '../../../util/Vocabularies'; diff --git a/src/http/representation/N3Patch.ts b/src/http/representation/N3Patch.ts index 80ab1c6e8..b83f804b7 100644 --- a/src/http/representation/N3Patch.ts +++ b/src/http/representation/N3Patch.ts @@ -1,4 +1,4 @@ -import type { Quad } from 'rdf-js'; +import type { Quad } from '@rdfjs/types'; import type { Patch } from './Patch'; /** diff --git a/src/http/representation/RepresentationMetadata.ts b/src/http/representation/RepresentationMetadata.ts index 82f01cbfa..d85a0f66a 100644 --- a/src/http/representation/RepresentationMetadata.ts +++ b/src/http/representation/RepresentationMetadata.ts @@ -1,5 +1,5 @@ import { DataFactory, Store } from 'n3'; -import type { BlankNode, DefaultGraph, Literal, NamedNode, Quad, Term } from 'rdf-js'; +import type { BlankNode, DefaultGraph, Literal, NamedNode, Quad, Term } from '@rdfjs/types'; import { getLoggerFor } from '../../logging/LogUtil'; import { ContentType, SIMPLE_MEDIA_RANGE } from '../../util/Header'; import { isTerm, toLiteral, toNamedTerm, toObjectTerm } from '../../util/TermUtil'; diff --git a/src/server/notifications/BaseChannelType.ts b/src/server/notifications/BaseChannelType.ts index bf07f119a..5248b04c9 100644 --- a/src/server/notifications/BaseChannelType.ts +++ b/src/server/notifications/BaseChannelType.ts @@ -3,7 +3,7 @@ import { KeysRdfParseJsonLd } from '@comunica/context-entries'; import { parse, toSeconds } from 'iso8601-duration'; import { DataFactory } from 'n3'; import type { Store } from 'n3'; -import type { NamedNode, Term } from 'rdf-js'; +import type { NamedNode, Term } from '@rdfjs/types'; import rdfParser from 'rdf-parse'; import SHACLValidator from 'rdf-validate-shacl'; import { v4 } from 'uuid'; diff --git a/src/storage/DataAccessorBasedStore.ts b/src/storage/DataAccessorBasedStore.ts index ea47f1e83..28b71d7e2 100644 --- a/src/storage/DataAccessorBasedStore.ts +++ b/src/storage/DataAccessorBasedStore.ts @@ -1,7 +1,6 @@ -import type { Quad } from '@rdfjs/types'; +import type { NamedNode, Quad, Term } from '@rdfjs/types'; import arrayifyStream from 'arrayify-stream'; import { DataFactory } from 'n3'; -import type { NamedNode, Term } from 'rdf-js'; import { v4 as uuid } from 'uuid'; import type { AuxiliaryStrategy } from '../http/auxiliary/AuxiliaryStrategy'; import { BasicRepresentation } from '../http/representation/BasicRepresentation'; diff --git a/src/storage/accessors/FileDataAccessor.ts b/src/storage/accessors/FileDataAccessor.ts index f5baeed63..8d20f70f2 100644 --- a/src/storage/accessors/FileDataAccessor.ts +++ b/src/storage/accessors/FileDataAccessor.ts @@ -1,7 +1,7 @@ import type { Readable } from 'node:stream'; import type { Stats } from 'fs-extra'; import { createReadStream, createWriteStream, ensureDir, lstat, opendir, remove, stat } from 'fs-extra'; -import type { Quad } from 'rdf-js'; +import type { Quad } from '@rdfjs/types'; import type { Representation } from '../../http/representation/Representation'; import { RepresentationMetadata } from '../../http/representation/RepresentationMetadata'; import type { ResourceIdentifier } from '../../http/representation/ResourceIdentifier'; diff --git a/src/storage/accessors/SparqlDataAccessor.ts b/src/storage/accessors/SparqlDataAccessor.ts index 117a9bc61..485725df7 100644 --- a/src/storage/accessors/SparqlDataAccessor.ts +++ b/src/storage/accessors/SparqlDataAccessor.ts @@ -2,7 +2,7 @@ import type { Readable } from 'node:stream'; import arrayifyStream from 'arrayify-stream'; import { SparqlEndpointFetcher } from 'fetch-sparql-endpoint'; import { DataFactory } from 'n3'; -import type { NamedNode, Quad } from 'rdf-js'; +import type { NamedNode, Quad } from '@rdfjs/types'; import type { ConstructQuery, GraphPattern, diff --git a/src/storage/conversion/ContainerToTemplateConverter.ts b/src/storage/conversion/ContainerToTemplateConverter.ts index db251038e..f232dcf31 100644 --- a/src/storage/conversion/ContainerToTemplateConverter.ts +++ b/src/storage/conversion/ContainerToTemplateConverter.ts @@ -1,6 +1,6 @@ import type { Readable } from 'node:stream'; import orderBy from 'lodash.orderby'; -import type { Quad } from 'rdf-js'; +import type { Quad } from '@rdfjs/types'; import { BasicRepresentation } from '../../http/representation/BasicRepresentation'; import type { Representation } from '../../http/representation/Representation'; import type { ResourceIdentifier } from '../../http/representation/ResourceIdentifier'; diff --git a/src/storage/conversion/DynamicJsonToTemplateConverter.ts b/src/storage/conversion/DynamicJsonToTemplateConverter.ts index 0ec8a7fe1..c715c8a2a 100644 --- a/src/storage/conversion/DynamicJsonToTemplateConverter.ts +++ b/src/storage/conversion/DynamicJsonToTemplateConverter.ts @@ -1,4 +1,4 @@ -import type { NamedNode, Term } from 'rdf-js'; +import type { NamedNode, Term } from '@rdfjs/types'; import { BasicRepresentation } from '../../http/representation/BasicRepresentation'; import type { Representation } from '../../http/representation/Representation'; import { RepresentationMetadata } from '../../http/representation/RepresentationMetadata'; diff --git a/src/storage/conversion/QuadToRdfConverter.ts b/src/storage/conversion/QuadToRdfConverter.ts index 1ed20f4dd..1194704e4 100644 --- a/src/storage/conversion/QuadToRdfConverter.ts +++ b/src/storage/conversion/QuadToRdfConverter.ts @@ -1,6 +1,6 @@ import type { Readable } from 'node:stream'; import { DataFactory, StreamWriter } from 'n3'; -import type { Quad } from 'rdf-js'; +import type { Quad } from '@rdfjs/types'; import rdfSerializer from 'rdf-serialize'; import { BasicRepresentation } from '../../http/representation/BasicRepresentation'; import type { Representation } from '../../http/representation/Representation'; diff --git a/src/storage/patch/ImmutableMetadataPatcher.ts b/src/storage/patch/ImmutableMetadataPatcher.ts index 9c18fedd2..8475be95f 100644 --- a/src/storage/patch/ImmutableMetadataPatcher.ts +++ b/src/storage/patch/ImmutableMetadataPatcher.ts @@ -1,5 +1,5 @@ import { DataFactory } from 'n3'; -import type { Quad } from 'rdf-js'; +import type { Quad } from '@rdfjs/types'; import type { AuxiliaryStrategy } from '../../http/auxiliary/AuxiliaryStrategy'; import type { RdfDatasetRepresentation } from '../../http/representation/RdfDatasetRepresentation'; import { getLoggerFor } from '../../logging/LogUtil'; diff --git a/src/storage/patch/N3Patcher.ts b/src/storage/patch/N3Patcher.ts index 3b7dfc234..47f47da29 100644 --- a/src/storage/patch/N3Patcher.ts +++ b/src/storage/patch/N3Patcher.ts @@ -1,7 +1,7 @@ import { QueryEngine } from '@comunica/query-sparql'; import arrayifyStream from 'arrayify-stream'; import type { Store } from 'n3'; -import type { Bindings, Quad, Term } from 'rdf-js'; +import type { Bindings, Quad, Term } from '@rdfjs/types'; import { mapTerms } from 'rdf-terms'; import { Generator, Wildcard } from 'sparqljs'; import type { SparqlGenerator } from 'sparqljs'; diff --git a/src/util/QuadUtil.ts b/src/util/QuadUtil.ts index 285b3b3bb..494bbfdbc 100644 --- a/src/util/QuadUtil.ts +++ b/src/util/QuadUtil.ts @@ -1,9 +1,8 @@ import type { Readable } from 'node:stream'; -import type { NamedNode } from '@rdfjs/types'; +import type { NamedNode, Quad, Term } from '@rdfjs/types'; import arrayifyStream from 'arrayify-stream'; import type { ParserOptions } from 'n3'; import { StreamParser, StreamWriter } from 'n3'; -import type { Quad, Term } from 'rdf-js'; import type { Guarded } from './GuardedStream'; import { guardedStreamFrom, pipeSafely } from './StreamUtil'; import { toNamedTerm } from './TermUtil'; diff --git a/src/util/TermUtil.ts b/src/util/TermUtil.ts index 08418c6a9..14474cf32 100644 --- a/src/util/TermUtil.ts +++ b/src/util/TermUtil.ts @@ -1,5 +1,5 @@ import { DataFactory } from 'n3'; -import type { Literal, NamedNode, Term } from 'rdf-js'; +import type { Literal, NamedNode, Term } from '@rdfjs/types'; const { namedNode, literal } = DataFactory; diff --git a/src/util/Vocabularies.ts b/src/util/Vocabularies.ts index 1cdf58d69..681908a55 100644 --- a/src/util/Vocabularies.ts +++ b/src/util/Vocabularies.ts @@ -1,5 +1,5 @@ import { DataFactory } from 'n3'; -import type { NamedNode } from 'rdf-js'; +import type { NamedNode } from '@rdfjs/types'; /** * A `Record` in which each value is a concatenation of the baseUrl and its key. diff --git a/src/util/errors/HttpError.ts b/src/util/errors/HttpError.ts index ebb430944..ac81e4f5a 100644 --- a/src/util/errors/HttpError.ts +++ b/src/util/errors/HttpError.ts @@ -1,4 +1,4 @@ -import type { NamedNode } from 'rdf-js'; +import type { NamedNode } from '@rdfjs/types'; import { RepresentationMetadata } from '../../http/representation/RepresentationMetadata'; import { toLiteral, toNamedTerm } from '../TermUtil'; import { HTTP, SOLID_ERROR, XSD } from '../Vocabularies'; diff --git a/test/unit/authorization/AcpReader.test.ts b/test/unit/authorization/AcpReader.test.ts index a9cf68be9..e8fa66d6a 100644 --- a/test/unit/authorization/AcpReader.test.ts +++ b/test/unit/authorization/AcpReader.test.ts @@ -1,5 +1,5 @@ import { Parser } from 'n3'; -import type { Quad } from 'rdf-js'; +import type { Quad } from '@rdfjs/types'; import type { Credentials } from '../../../src/authentication/Credentials'; import { AcpReader } from '../../../src/authorization/AcpReader'; import { AccessMode } from '../../../src/authorization/permissions/Permissions'; diff --git a/test/unit/authorization/permissions/N3PatchModesExtractor.test.ts b/test/unit/authorization/permissions/N3PatchModesExtractor.test.ts index 87d5e21c8..666130e0f 100644 --- a/test/unit/authorization/permissions/N3PatchModesExtractor.test.ts +++ b/test/unit/authorization/permissions/N3PatchModesExtractor.test.ts @@ -1,5 +1,5 @@ import { DataFactory } from 'n3'; -import type { Quad } from 'rdf-js'; +import type { Quad } from '@rdfjs/types'; import { N3PatchModesExtractor } from '../../../../src/authorization/permissions/N3PatchModesExtractor'; import type { AccessMap } from '../../../../src/authorization/permissions/Permissions'; import { AccessMode } from '../../../../src/authorization/permissions/Permissions'; diff --git a/test/unit/http/representation/RepresentationMetadata.test.ts b/test/unit/http/representation/RepresentationMetadata.test.ts index ab75aed02..71453c4c8 100644 --- a/test/unit/http/representation/RepresentationMetadata.test.ts +++ b/test/unit/http/representation/RepresentationMetadata.test.ts @@ -1,7 +1,7 @@ import 'jest-rdf'; import type { BlankNode } from 'n3'; import { DataFactory } from 'n3'; -import type { NamedNode, Quad } from 'rdf-js'; +import type { NamedNode, Quad } from '@rdfjs/types'; import { RepresentationMetadata } from '../../../../src/http/representation/RepresentationMetadata'; import { ContentType } from '../../../../src/util/Header'; import { CONTENT_TYPE_TERM, RDFS, SOLID_META } from '../../../../src/util/Vocabularies'; diff --git a/test/unit/storage/accessors/SparqlDataAccessor.test.ts b/test/unit/storage/accessors/SparqlDataAccessor.test.ts index a35a14967..93a71a1c0 100644 --- a/test/unit/storage/accessors/SparqlDataAccessor.test.ts +++ b/test/unit/storage/accessors/SparqlDataAccessor.test.ts @@ -3,7 +3,7 @@ import { Readable } from 'node:stream'; import arrayifyStream from 'arrayify-stream'; import { SparqlEndpointFetcher } from 'fetch-sparql-endpoint'; import { DataFactory } from 'n3'; -import type { Quad } from 'rdf-js'; +import type { Quad } from '@rdfjs/types'; import { BasicRepresentation } from '../../../../src/http/representation/BasicRepresentation'; import { RepresentationMetadata } from '../../../../src/http/representation/RepresentationMetadata'; import { SparqlDataAccessor } from '../../../../src/storage/accessors/SparqlDataAccessor'; diff --git a/test/unit/storage/patch/RdfPatcher.test.ts b/test/unit/storage/patch/RdfPatcher.test.ts index a67d72abd..f09c0d6d4 100644 --- a/test/unit/storage/patch/RdfPatcher.test.ts +++ b/test/unit/storage/patch/RdfPatcher.test.ts @@ -1,6 +1,6 @@ import 'jest-rdf'; import { DataFactory } from 'n3'; -import type { Quad } from 'rdf-js'; +import type { Quad } from '@rdfjs/types'; import { BasicRepresentation } from '../../../../src/http/representation/BasicRepresentation'; import type { Patch } from '../../../../src/http/representation/Patch'; import type { RdfDatasetRepresentation } from '../../../../src/http/representation/RdfDatasetRepresentation'; diff --git a/test/unit/storage/patch/SparqlUpdatePatcher.test.ts b/test/unit/storage/patch/SparqlUpdatePatcher.test.ts index 8fb1da42a..02717dcaa 100644 --- a/test/unit/storage/patch/SparqlUpdatePatcher.test.ts +++ b/test/unit/storage/patch/SparqlUpdatePatcher.test.ts @@ -1,6 +1,6 @@ import 'jest-rdf'; import { DataFactory, Store } from 'n3'; -import type { Quad } from 'rdf-js'; +import type { Quad } from '@rdfjs/types'; import type { Algebra } from 'sparqlalgebrajs'; import { translate } from 'sparqlalgebrajs'; import { BasicRepresentation } from '../../../../src/http/representation/BasicRepresentation'; From 7d573596139283637cf2d1e99d44cb2130268811 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Mon, 15 Jan 2024 13:41:54 +0100 Subject: [PATCH 02/71] test: Remove workaround for authn library This is no longer necessary since dependencies have been updated --- test/integration/IdentityTestState.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test/integration/IdentityTestState.ts b/test/integration/IdentityTestState.ts index 4a3cbfa5d..bd9439e1e 100644 --- a/test/integration/IdentityTestState.ts +++ b/test/integration/IdentityTestState.ts @@ -104,10 +104,7 @@ export class IdentityTestState { const url = await this.handleLocationRedirect(res); expect(url.startsWith(this.redirectUrl)).toBe(true); - // Workaround for https://github.com/inrupt/solid-client-authn-js/issues/2985 - const strippedUrl = new URL(url); - strippedUrl.searchParams.delete('iss'); - const info = await this.session.handleIncomingRedirect(strippedUrl.href); + const info = await this.session.handleIncomingRedirect(url); expect(info?.isLoggedIn).toBe(true); expect(info?.webId).toBe(webId); } From 1e0974f89b026e4792b9a4d6b0edf40e3a187403 Mon Sep 17 00:00:00 2001 From: Ted Thibodeau Jr Date: Thu, 18 Jan 2024 03:33:17 -0500 Subject: [PATCH 03/71] docs: add link to CSS-focused Matrix chatroom to README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 26b5708ef..1af55d574 100644 --- a/README.md +++ b/README.md @@ -82,4 +82,6 @@ and available under the [MIT License](https://github.com/CommunitySolidServer/C Don't hesitate to [start a discussion](https://github.com/CommunitySolidServer/CommunitySolidServer/discussions) or [report a bug](https://github.com/CommunitySolidServer/CommunitySolidServer/issues). +There's also [a Matrix-based, CSS-focused chat](https://matrix.to/#/#CommunitySolidServer_community:gitter.im) + Learn more about Solid at [solidproject.org](https://solidproject.org/). From a93133fe7c8369b6029d8960fe7500b63b1ec4a2 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Thu, 18 Jan 2024 09:45:47 +0100 Subject: [PATCH 04/71] docs: Add login example to credentials documentation * docs: Add login example to credentials documentation * docs: Fix language Co-authored-by: Ted Thibodeau Jr --------- Co-authored-by: Ted Thibodeau Jr --- .../markdown/usage/client-credentials.md | 40 ++++++++++++++----- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/documentation/markdown/usage/client-credentials.md b/documentation/markdown/usage/client-credentials.md index fc76c64ce..4e7561b05 100644 --- a/documentation/markdown/usage/client-credentials.md +++ b/documentation/markdown/usage/client-credentials.md @@ -29,19 +29,42 @@ This only needs to be done once, afterwards this token can be used for all futur Before doing the step below, you already need to have an [authorization value](account/json-api.md#authorization) that you get after logging in to your account. -In the example below the cookie value is used. -In the default server configurations, -you can log in through the [email/password API](account/json-api.md#controlspasswordlogin). + +Below is an example of how this would work with +the [email/password API](account/json-api.md#controlspasswordlogin) +from the default server configurations. ```ts -// This assumes your server is started under http://localhost:3000/. -// It also assumes you have already logged in and `cookie` contains a valid cookie header -// as described in the API documentation. -const indexResponse = await fetch('http://localhost:3000/.account/', { headers: { cookie }}); +// All these examples assume the server is running at `http://localhost:3000/`. + +// First we request the account API controls to find out where we can log in +const indexResponse = await fetch('http://localhost:3000/.account/'); const { controls } = await indexResponse.json(); + +// And then we log in to the account API +const response = await fetch(controls.password.login, { + method: 'POST', + headers: { 'content-type': 'application/json' }, + body: JSON.stringify({ email: 'my-email@example.com', password: 'my-password' }), +}); +// This authorization value will be used to authenticate in the next step +const { authorization } = await response.json(); +``` + +The next step generates the token and assumes you have an authorization value as generated in the example above. + +```ts +// Now that we are logged in, we need to request the updated controls from the server. +// These will now have more values than in the previous example. +const indexResponse = await fetch('http://localhost:3000/.account/', { + headers: { authorization: `CSS-Account-Token ${authorization}` } +}); +const { controls } = await indexResponse.json(); + +// Here we request the server to generate a token on our account const response = await fetch(controls.account.clientCredentials, { method: 'POST', - headers: { cookie, 'content-type': 'application/json' }, + headers: { authorization: `CSS-Account-Token ${authorization}`, 'content-type': 'application/json' }, // The name field will be used when generating the ID of your token. // The WebID field determines which WebID you will identify as when using the token. // Only WebIDs linked to your account can be used. @@ -64,7 +87,6 @@ This Access Token is only valid for a certain amount of time, after which a new ```ts import { createDpopHeader, generateDpopKeyPair } from '@inrupt/solid-client-authn-core'; -import fetch from 'node-fetch'; // A key pair is needed for encryption. // This function from `solid-client-authn` generates such a pair for you. From d9a3612f3c4850e25bd7bea44c84f6778000a78e Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Thu, 25 Jan 2024 08:50:55 +0100 Subject: [PATCH 05/71] docs: Fix issues in notification documentation --- .../markdown/architecture/features/notifications.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/documentation/markdown/architecture/features/notifications.md b/documentation/markdown/architecture/features/notifications.md index 1136d3f57..431cd5caa 100644 --- a/documentation/markdown/architecture/features/notifications.md +++ b/documentation/markdown/architecture/features/notifications.md @@ -36,10 +36,10 @@ whose results get merged together in an `ArrayUnionHandler`. A `NotificationChannelType` contains the specific details of a specification notification channel type, including a JSON-LD representation of the corresponding subscription resource. -One specific instance of a `StorageDescriber` is a `NotificationSubcriber`, +One specific instance of a `StorageDescriber` is a `NotificationDescriber`, which merges those JSON-LD descriptions into a single set of RDF quads. When adding a new subscription type, -a new instance of such a class should be added to the `urn:solid-server:default:StorageDescriber`. +a new instance of such a class should be added to the `urn:solid-server:default:NotificationDescriber`. ## NotificationChannel @@ -53,9 +53,9 @@ flowchart LR subgraph NotificationTypeHandlerArgs[" "] direction LR OperationRouterHandler("
OperationRouterHandler") --> NotificationSubscriber("
NotificationSubscriber") - NotificationChannelType --> NotificationChannelType("
NotificationChannelType") +NotificationSubscriber --> NotificationChannelType("
NotificationChannelType") OperationRouterHandler2("
OperationRouterHandler") --> NotificationSubscriber2("
NotificationSubscriber") - NotificationChannelType2 --> NotificationChannelType2("
NotificationChannelType") +NotificationSubscriber2 --> NotificationChannelType2("
NotificationChannelType") end ``` From f890c769f8b5edb5e61873a79f312ca48fd2b0ea Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Wed, 7 Feb 2024 07:53:19 +0100 Subject: [PATCH 06/71] chore(release): Release version 7.0.4 of the npm package --- CHANGELOG.md | 10 ++++++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97c57a0ce..529b4eb7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,16 @@ All notable changes to this project will be documented in this file. +## [7.0.4](https://github.com/CommunitySolidServer/CommunitySolidServer/compare/v7.0.3...v7.0.4) (2024-02-07) + +### Chores + +* Replace rdf-js import with @rdfjs/types ([e09b53b](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/e09b53b20de0e389715d299466a1e1101579dd07)) + +### Testing + +* Remove workaround for authn library ([7d57359](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/7d573596139283637cf2d1e99d44cb2130268811)) + ## [7.0.3](https://github.com/CommunitySolidServer/CommunitySolidServer/compare/v7.0.2...v7.0.3) (2024-01-05) ### Features diff --git a/package-lock.json b/package-lock.json index 987f9a9ec..9f9add528 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@solid/community-server", - "version": "7.0.3", + "version": "7.0.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@solid/community-server", - "version": "7.0.3", + "version": "7.0.4", "license": "MIT", "dependencies": { "@comunica/context-entries": "^2.8.2", diff --git a/package.json b/package.json index dbd0fe120..47afe2477 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@solid/community-server", - "version": "7.0.3", + "version": "7.0.4", "description": "Community Solid Server: an open and modular implementation of the Solid specifications", "license": "MIT", "homepage": "https://github.com/CommunitySolidServer/CommunitySolidServer#readme", From a9bcc962170b7af9a09ee0ae8fb177c282305a1b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 07:00:20 +0000 Subject: [PATCH 07/71] chore(deps): bump nodemailer from 6.9.6 to 6.9.9 Bumps [nodemailer](https://github.com/nodemailer/nodemailer) from 6.9.6 to 6.9.9. - [Release notes](https://github.com/nodemailer/nodemailer/releases) - [Changelog](https://github.com/nodemailer/nodemailer/blob/master/CHANGELOG.md) - [Commits](https://github.com/nodemailer/nodemailer/compare/v6.9.6...v6.9.9) --- updated-dependencies: - dependency-name: nodemailer dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9f9add528..bbc9d2f6e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12979,9 +12979,9 @@ "dev": true }, "node_modules/nodemailer": { - "version": "6.9.6", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.6.tgz", - "integrity": "sha512-s7pDtWwe5fLMkQUhw8TkWB/wnZ7SRdd9HRZslq/s24hlZvBP3j32N/ETLmnqTpmj4xoBZL9fOWyCIZ7r2HORHg==", + "version": "6.9.9", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.9.tgz", + "integrity": "sha512-dexTll8zqQoVJEZPwQAKzxxtFn0qTnjdQTchoU6Re9BUUGBJiOy3YMn/0ShTW6J5M0dfQ1NeDeRTTl4oIWgQMA==", "engines": { "node": ">=6.0.0" } @@ -26146,9 +26146,9 @@ "dev": true }, "nodemailer": { - "version": "6.9.6", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.6.tgz", - "integrity": "sha512-s7pDtWwe5fLMkQUhw8TkWB/wnZ7SRdd9HRZslq/s24hlZvBP3j32N/ETLmnqTpmj4xoBZL9fOWyCIZ7r2HORHg==" + "version": "6.9.9", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.9.tgz", + "integrity": "sha512-dexTll8zqQoVJEZPwQAKzxxtFn0qTnjdQTchoU6Re9BUUGBJiOy3YMn/0ShTW6J5M0dfQ1NeDeRTTl4oIWgQMA==" }, "nodemon": { "version": "3.0.1", From 137027e421da9ffa2d2bbc23c08b2a47d4abd328 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Wed, 14 Feb 2024 14:15:35 +0100 Subject: [PATCH 08/71] fix: Keep content-type when using metadata templates --- src/pods/generate/BaseResourcesGenerator.ts | 4 ++++ test/unit/pods/generate/BaseResourcesGenerator.test.ts | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/src/pods/generate/BaseResourcesGenerator.ts b/src/pods/generate/BaseResourcesGenerator.ts index 4d46b00c8..2b89cb616 100644 --- a/src/pods/generate/BaseResourcesGenerator.ts +++ b/src/pods/generate/BaseResourcesGenerator.ts @@ -197,6 +197,10 @@ export class BaseResourcesGenerator implements TemplatedResourcesGenerator { // Add metadata from .meta file if there is one if (metaLink) { const rawMetadata = await this.generateMetadata(metaLink, options); + if (!rawMetadata.contentType) { + // Make sure this does not remove the content-type if none is explicitly defined + rawMetadata.contentType = metadata.contentType; + } const metaIdentifier = this.metadataStrategy.getAuxiliaryIdentifier(link.identifier); const descriptionMeta = new RepresentationMetadata(metaIdentifier); addResourceMetadata(rawMetadata, isContainerIdentifier(link.identifier)); diff --git a/test/unit/pods/generate/BaseResourcesGenerator.test.ts b/test/unit/pods/generate/BaseResourcesGenerator.test.ts index 9f97f5a4f..371f8ad76 100644 --- a/test/unit/pods/generate/BaseResourcesGenerator.test.ts +++ b/test/unit/pods/generate/BaseResourcesGenerator.test.ts @@ -10,6 +10,7 @@ import { asyncToArray } from '../../../../src/util/IterableUtil'; import { ensureTrailingSlash, joinFilePath, trimTrailingSlashes } from '../../../../src/util/PathUtil'; import { readableToQuads, readableToString } from '../../../../src/util/StreamUtil'; import { HandlebarsTemplateEngine } from '../../../../src/util/templates/HandlebarsTemplateEngine'; +import { CONTENT_TYPE_TERM } from '../../../../src/util/Vocabularies'; import { SimpleSuffixStrategy } from '../../../util/SimpleSuffixStrategy'; import { mockFileSystem } from '../../../util/Util'; @@ -144,6 +145,10 @@ describe('A BaseResourcesGenerator', (): void => { const expDocMetadataQuads = docMetadataQuads.getQuads(docMetadata.identifier, 'pre:has', null, null); expect(expDocMetadataQuads).toHaveLength(1); expect(expDocMetadataQuads[0].object.value).toBe('metadata'); + // Metadata will replace existing metadata so need to make sure content-type is still there + const contentDocMetadataQuads = docMetadataQuads.getQuads(docMetadata.identifier, CONTENT_TYPE_TERM, null, null); + expect(contentDocMetadataQuads).toHaveLength(1); + expect(contentDocMetadataQuads[0].object.value).toBe('text/turtle'); }); it('does not create container when it already exists.', async(): Promise => { From 68975e6627416c248d82150692199db8a5fd0d31 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Wed, 14 Feb 2024 07:41:17 +0100 Subject: [PATCH 09/71] fix: Prevent error when switching accounts --- src/identity/interaction/InteractionUtil.ts | 8 ++++++++ .../interaction/InteractionUtil.test.ts | 17 +++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/identity/interaction/InteractionUtil.ts b/src/identity/interaction/InteractionUtil.ts index 6f6d09663..c1c15d4c4 100644 --- a/src/identity/interaction/InteractionUtil.ts +++ b/src/identity/interaction/InteractionUtil.ts @@ -86,4 +86,12 @@ export async function forgetWebId(provider: Provider, oidcInteraction: Interacti delete session.accountId; await session.persist(); } + + // If a client previously successfully completed an interaction a grant will have been created. + // If the same session gets reused to authenticate with a different WebID, + // we need to first delete the previous grant as the oidc-provider will try to reuse it. + if (oidcInteraction.grantId) { + const grant = await provider.Grant.find(oidcInteraction.grantId); + await grant?.destroy(); + } } diff --git a/test/unit/identity/interaction/InteractionUtil.test.ts b/test/unit/identity/interaction/InteractionUtil.test.ts index 7cceeb49e..7c60676b1 100644 --- a/test/unit/identity/interaction/InteractionUtil.test.ts +++ b/test/unit/identity/interaction/InteractionUtil.test.ts @@ -85,14 +85,31 @@ describe('InteractionUtil', (): void => { persist: jest.fn(), }), }, + Grant: { + find: jest.fn().mockResolvedValue({ + destroy: jest.fn(), + }), + }, } as any; }); it('removes the accountId from the session.', async(): Promise => { await expect(forgetWebId(provider, oidcInteraction)).resolves.toBeUndefined(); + expect(provider.Session.find).toHaveBeenCalledTimes(1); + expect(provider.Session.find).toHaveBeenLastCalledWith('cookie'); const session = await (provider.Session.find as jest.Mock).mock.results[0].value; expect(session.accountId).toBeUndefined(); expect(session.persist).toHaveBeenCalledTimes(1); }); + + it('deletes the grant if there is one associated to the session.', async(): Promise => { + delete oidcInteraction.session; + oidcInteraction.grantId = 'grantId'; + await expect(forgetWebId(provider, oidcInteraction)).resolves.toBeUndefined(); + expect(provider.Grant.find).toHaveBeenCalledTimes(1); + expect(provider.Grant.find).toHaveBeenLastCalledWith('grantId'); + const grant = await (provider.Grant.find as jest.Mock).mock.results[0].value; + expect(grant.destroy).toHaveBeenCalledTimes(1); + }); }); }); From 2d44d61942f587d2696f2b0c8510b59d378421f2 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Thu, 15 Feb 2024 06:48:11 +0100 Subject: [PATCH 10/71] docs: Fix language Co-authored-by: Ted Thibodeau Jr --- src/identity/interaction/InteractionUtil.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/identity/interaction/InteractionUtil.ts b/src/identity/interaction/InteractionUtil.ts index c1c15d4c4..3a1646077 100644 --- a/src/identity/interaction/InteractionUtil.ts +++ b/src/identity/interaction/InteractionUtil.ts @@ -87,9 +87,9 @@ export async function forgetWebId(provider: Provider, oidcInteraction: Interacti await session.persist(); } - // If a client previously successfully completed an interaction a grant will have been created. - // If the same session gets reused to authenticate with a different WebID, - // we need to first delete the previous grant as the oidc-provider will try to reuse it. + // If a client previously successfully completed an interaction, a grant will have been created. + // If such a session is reused to authenticate with a different WebID, we need to + // first delete the previously created grant, as the oidc-provider will try to reuse it as well. if (oidcInteraction.grantId) { const grant = await provider.Grant.find(oidcInteraction.grantId); await grant?.destroy(); From e0e20dc6f5cd150cdbb6f29e403d5786d60f3edb Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Thu, 15 Feb 2024 14:25:06 +0100 Subject: [PATCH 11/71] chore: Update year --- LICENSE.md | 2 +- templates/main.html.ejs | 2 +- templates/root/intro/base/index.html | 2 +- templates/root/prefilled/base/index.html | 2 +- templates/root/static/index.html | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/LICENSE.md b/LICENSE.md index 0c863f6c0..91953501a 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ MIT License -Copyright © 2019–2023 Inrupt Inc. and imec +Copyright © 2019–2024 Inrupt Inc. and imec Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/templates/main.html.ejs b/templates/main.html.ejs index be495c417..dc3bd1e21 100644 --- a/templates/main.html.ejs +++ b/templates/main.html.ejs @@ -17,7 +17,7 @@ diff --git a/templates/root/intro/base/index.html b/templates/root/intro/base/index.html index b74cf1c73..d19fa710f 100644 --- a/templates/root/intro/base/index.html +++ b/templates/root/intro/base/index.html @@ -74,7 +74,7 @@ diff --git a/templates/root/prefilled/base/index.html b/templates/root/prefilled/base/index.html index 1e420eaae..42516a14c 100644 --- a/templates/root/prefilled/base/index.html +++ b/templates/root/prefilled/base/index.html @@ -64,7 +64,7 @@ diff --git a/templates/root/static/index.html b/templates/root/static/index.html index d9ec66448..9aa11d0ec 100644 --- a/templates/root/static/index.html +++ b/templates/root/static/index.html @@ -78,7 +78,7 @@ From 5086f2280b318b39349e2370025bfb84671fe9b4 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Thu, 15 Feb 2024 14:31:10 +0100 Subject: [PATCH 12/71] chore: Update nodemailer dependency 6.9.6 had a vulnerability issue --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index bbc9d2f6e..170f82841 100644 --- a/package-lock.json +++ b/package-lock.json @@ -57,7 +57,7 @@ "marked": "^9.1.0", "mime-types": "^2.1.35", "n3": "^1.17.1", - "nodemailer": "^6.9.6", + "nodemailer": "^6.9.9", "oidc-provider": "^8.4.0", "proper-lockfile": "^4.1.2", "pump": "^3.0.0", diff --git a/package.json b/package.json index 47afe2477..c586e49da 100644 --- a/package.json +++ b/package.json @@ -121,7 +121,7 @@ "marked": "^9.1.0", "mime-types": "^2.1.35", "n3": "^1.17.1", - "nodemailer": "^6.9.6", + "nodemailer": "^6.9.9", "oidc-provider": "^8.4.0", "proper-lockfile": "^4.1.2", "pump": "^3.0.0", From 8fff08a9b60a11c7a7f313c540d9f28a2f96ebc0 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Tue, 27 Feb 2024 09:08:36 +0100 Subject: [PATCH 13/71] fix: Extract root as possible pod when using subdomains --- src/pods/generate/SubdomainIdentifierGenerator.ts | 6 ++++-- .../unit/pods/generate/SubdomainIdentifierGenerator.test.ts | 5 +++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/pods/generate/SubdomainIdentifierGenerator.ts b/src/pods/generate/SubdomainIdentifierGenerator.ts index 6cd3f7cd0..b48d3363a 100644 --- a/src/pods/generate/SubdomainIdentifierGenerator.ts +++ b/src/pods/generate/SubdomainIdentifierGenerator.ts @@ -7,6 +7,8 @@ import type { IdentifierGenerator } from './IdentifierGenerator'; /** * Generates identifiers by using the name as a subdomain on the base URL. * Non-alphanumeric characters will be replaced with `-`. + * + * When extracting the pod, the base URl is also seen as a pod as there is no issue of nested containers here. */ export class SubdomainIdentifierGenerator implements IdentifierGenerator { private readonly baseParts: { scheme: string; rest: string }; @@ -32,8 +34,8 @@ export class SubdomainIdentifierGenerator implements IdentifierGenerator { const idx = path.indexOf(this.baseParts.rest); - // If the idx is smaller than this, either there was no match, or there is no subdomain - if (idx <= this.baseParts.scheme.length) { + // If the idx is smaller than this, there was no match + if (idx < 0) { throw new BadRequestHttpError(`Invalid identifier ${path}`); } diff --git a/test/unit/pods/generate/SubdomainIdentifierGenerator.test.ts b/test/unit/pods/generate/SubdomainIdentifierGenerator.test.ts index 39184ec5a..307608560 100644 --- a/test/unit/pods/generate/SubdomainIdentifierGenerator.test.ts +++ b/test/unit/pods/generate/SubdomainIdentifierGenerator.test.ts @@ -30,6 +30,11 @@ describe('A SubdomainIdentifierGenerator', (): void => { it('errors when extracting if there is no pod.', async(): Promise => { const identifier = { path: 'http://example.com/bar/baz' }; + expect(generator.extractPod(identifier)).toEqual({ path: 'http://example.com/' }); + }); + + it('errors when extracting if the domain is wrong.', async(): Promise => { + const identifier = { path: 'http://foo.example.org/bar/baz' }; expect((): any => generator.extractPod(identifier)).toThrow(BadRequestHttpError); }); }); From df9062cfc507adaca5162c20852665c6e2b82e8b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Mar 2024 19:07:18 +0000 Subject: [PATCH 14/71] chore(deps): bump jose from 4.15.4 to 4.15.5 Bumps [jose](https://github.com/panva/jose) from 4.15.4 to 4.15.5. - [Release notes](https://github.com/panva/jose/releases) - [Changelog](https://github.com/panva/jose/blob/v4.15.5/CHANGELOG.md) - [Commits](https://github.com/panva/jose/compare/v4.15.4...v4.15.5) --- updated-dependencies: - dependency-name: jose dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 170f82841..9ea5f24e5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11739,9 +11739,9 @@ } }, "node_modules/jose": { - "version": "4.15.4", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.4.tgz", - "integrity": "sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ==", + "version": "4.15.5", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.5.tgz", + "integrity": "sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg==", "funding": { "url": "https://github.com/sponsors/panva" } @@ -25163,9 +25163,9 @@ } }, "jose": { - "version": "4.15.4", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.4.tgz", - "integrity": "sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ==" + "version": "4.15.5", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.5.tgz", + "integrity": "sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg==" }, "js-tokens": { "version": "4.0.0", From 33e9ae41916c9de0638709b02c42936e53d49414 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Wed, 13 Mar 2024 14:16:30 +0100 Subject: [PATCH 15/71] fix: Add priorities to RDF types when converting --- src/storage/conversion/RdfToQuadConverter.ts | 9 ++++++--- test/unit/storage/conversion/RdfToQuadConverter.test.ts | 9 +++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/storage/conversion/RdfToQuadConverter.ts b/src/storage/conversion/RdfToQuadConverter.ts index 3cecdc0ee..078cd1cab 100644 --- a/src/storage/conversion/RdfToQuadConverter.ts +++ b/src/storage/conversion/RdfToQuadConverter.ts @@ -5,7 +5,7 @@ import rdfParser from 'rdf-parse'; import { BasicRepresentation } from '../../http/representation/BasicRepresentation'; import type { Representation } from '../../http/representation/Representation'; import { RepresentationMetadata } from '../../http/representation/RepresentationMetadata'; -import { INTERNAL_QUADS } from '../../util/ContentTypes'; +import { APPLICATION_JSON, INTERNAL_QUADS } from '../../util/ContentTypes'; import { BadRequestHttpError } from '../../util/errors/BadRequestHttpError'; import { pipeSafely } from '../../util/StreamUtil'; import { PREFERRED_PREFIX_TERM, SOLID_META } from '../../util/Vocabularies'; @@ -25,9 +25,12 @@ export class RdfToQuadConverter extends BaseTypedRepresentationConverter { private readonly documentLoader: ContextDocumentLoader; public constructor(contexts: Record = {}) { - const inputTypes = rdfParser.getContentTypes() + const inputTypes = rdfParser.getContentTypesPrioritized() // ContentType application/json MAY NOT be converted to Quad. - .then((types): string[] => types.filter((type): boolean => type !== 'application/json')); + .then((types): Record => { + delete types[APPLICATION_JSON]; + return types; + }); super(inputTypes, INTERNAL_QUADS); this.documentLoader = new ContextDocumentLoader(contexts); } diff --git a/test/unit/storage/conversion/RdfToQuadConverter.test.ts b/test/unit/storage/conversion/RdfToQuadConverter.test.ts index b1ca6caad..73c0c6d92 100644 --- a/test/unit/storage/conversion/RdfToQuadConverter.test.ts +++ b/test/unit/storage/conversion/RdfToQuadConverter.test.ts @@ -35,10 +35,11 @@ describe('A RdfToQuadConverter', (): void => { const converter = new RdfToQuadConverter(); const identifier: ResourceIdentifier = { path: 'http://example.com/resource' }; it('supports serializing as quads.', async(): Promise => { - const types = rdfParser.getContentTypes() - .then((inputTypes): string[] => inputTypes.filter((type): boolean => type !== 'application/json')); - for (const type of await types) { - await expect(converter.getOutputTypes(type)).resolves.toEqual({ [INTERNAL_QUADS]: 1 }); + const types = await rdfParser.getContentTypesPrioritized(); + // JSON is not supported + delete types['application/json']; + for (const [ type, priority ] of Object.entries(types)) { + await expect(converter.getOutputTypes(type)).resolves.toEqual({ [INTERNAL_QUADS]: priority }); } }); From 6fe6b6ec89cfa3c1005ca4cf2219fc77de3fb975 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Mon, 25 Mar 2024 09:32:53 +0100 Subject: [PATCH 16/71] fix: Allow path segments to start with 2 or more dots --- src/storage/mapping/BaseFileIdentifierMapper.ts | 6 +++--- .../unit/storage/mapping/BaseFileIdentifierMapper.test.ts | 8 ++++++-- test/unit/storage/mapping/ExtensionBasedMapper.test.ts | 2 +- test/unit/storage/mapping/FixedContentTypeMapper.test.ts | 2 +- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/storage/mapping/BaseFileIdentifierMapper.ts b/src/storage/mapping/BaseFileIdentifierMapper.ts index c1311d710..5f533b8a5 100644 --- a/src/storage/mapping/BaseFileIdentifierMapper.ts +++ b/src/storage/mapping/BaseFileIdentifierMapper.ts @@ -205,9 +205,9 @@ export class BaseFileIdentifierMapper implements FileIdentifierMapper { throw new BadRequestHttpError('URL needs a / after the base'); } - if (path.includes('/..')) { - this.logger.warn(`Disallowed /.. segment in URL ${identifier.path}.`); - throw new BadRequestHttpError('Disallowed /.. segment in URL'); + if (path.includes('/../') || path.endsWith('/..')) { + this.logger.warn(`Disallowed /../ segment in URL ${identifier.path}.`); + throw new BadRequestHttpError('Disallowed /../ segment in URL'); } } diff --git a/test/unit/storage/mapping/BaseFileIdentifierMapper.test.ts b/test/unit/storage/mapping/BaseFileIdentifierMapper.test.ts index e8fb2ba98..13064d954 100644 --- a/test/unit/storage/mapping/BaseFileIdentifierMapper.test.ts +++ b/test/unit/storage/mapping/BaseFileIdentifierMapper.test.ts @@ -22,9 +22,13 @@ describe('An BaseFileIdentifierMapper', (): void => { }); it('throws 400 if the input path contains relative parts.', async(): Promise => { - const result = mapper.mapUrlToFilePath({ path: `${base}test/../test2` }, false); + let result = mapper.mapUrlToFilePath({ path: `${base}test/../test2` }, false); await expect(result).rejects.toThrow(BadRequestHttpError); - await expect(result).rejects.toThrow('Disallowed /.. segment in URL'); + await expect(result).rejects.toThrow('Disallowed /../ segment in URL'); + + result = mapper.mapUrlToFilePath({ path: `${base}test/..` }, false); + await expect(result).rejects.toThrow(BadRequestHttpError); + await expect(result).rejects.toThrow('Disallowed /../ segment in URL'); }); it('returns the corresponding file path for container identifiers.', async(): Promise => { diff --git a/test/unit/storage/mapping/ExtensionBasedMapper.test.ts b/test/unit/storage/mapping/ExtensionBasedMapper.test.ts index 541739855..758311094 100644 --- a/test/unit/storage/mapping/ExtensionBasedMapper.test.ts +++ b/test/unit/storage/mapping/ExtensionBasedMapper.test.ts @@ -38,7 +38,7 @@ describe('An ExtensionBasedMapper', (): void => { it('throws 400 if the input path contains relative parts.', async(): Promise => { const result = mapper.mapUrlToFilePath({ path: `${base}test/../test2` }, false); await expect(result).rejects.toThrow(BadRequestHttpError); - await expect(result).rejects.toThrow('Disallowed /.. segment in URL'); + await expect(result).rejects.toThrow('Disallowed /../ segment in URL'); }); it('returns the corresponding file path for container identifiers.', async(): Promise => { diff --git a/test/unit/storage/mapping/FixedContentTypeMapper.test.ts b/test/unit/storage/mapping/FixedContentTypeMapper.test.ts index c5ee7a364..6b6f5e6d7 100644 --- a/test/unit/storage/mapping/FixedContentTypeMapper.test.ts +++ b/test/unit/storage/mapping/FixedContentTypeMapper.test.ts @@ -25,7 +25,7 @@ describe('An FixedContentTypeMapper', (): void => { it('throws 400 if the input path contains relative parts.', async(): Promise => { const result = mapper.mapUrlToFilePath({ path: `${base}test/../test2` }, false); await expect(result).rejects.toThrow(BadRequestHttpError); - await expect(result).rejects.toThrow('Disallowed /.. segment in URL'); + await expect(result).rejects.toThrow('Disallowed /../ segment in URL'); }); it('returns the corresponding file path for container identifiers.', async(): Promise => { From c4df54dd886e8c8d88899462b7db10ec2eb48a6b Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Mon, 25 Mar 2024 14:10:35 +0100 Subject: [PATCH 17/71] chore(release): Release version 7.0.5 of the npm package --- CHANGELOG.md | 10 ++++++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 529b4eb7b..8d83164e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,16 @@ All notable changes to this project will be documented in this file. +## [7.0.5](https://github.com/CommunitySolidServer/CommunitySolidServer/compare/v7.0.4...v7.0.5) (2024-03-25) + +### Fixes + +* Allow path segments to start with 2 or more dots ([6fe6b6e](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/6fe6b6ec89cfa3c1005ca4cf2219fc77de3fb975)) +* Add priorities to RDF types when converting ([33e9ae4](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/33e9ae41916c9de0638709b02c42936e53d49414)) +* Extract root as possible pod when using subdomains ([8fff08a](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/8fff08a9b60a11c7a7f313c540d9f28a2f96ebc0)) +* Prevent error when switching accounts ([68975e6](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/68975e6627416c248d82150692199db8a5fd0d31)) +* Keep content-type when using metadata templates ([137027e](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/137027e421da9ffa2d2bbc23c08b2a47d4abd328)) + ## [7.0.4](https://github.com/CommunitySolidServer/CommunitySolidServer/compare/v7.0.3...v7.0.4) (2024-02-07) ### Chores diff --git a/package-lock.json b/package-lock.json index 9ea5f24e5..47ff48ea2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@solid/community-server", - "version": "7.0.4", + "version": "7.0.5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@solid/community-server", - "version": "7.0.4", + "version": "7.0.5", "license": "MIT", "dependencies": { "@comunica/context-entries": "^2.8.2", diff --git a/package.json b/package.json index c586e49da..4ff9a9e0a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@solid/community-server", - "version": "7.0.4", + "version": "7.0.5", "description": "Community Solid Server: an open and modular implementation of the Solid specifications", "license": "MIT", "homepage": "https://github.com/CommunitySolidServer/CommunitySolidServer#readme", From 28af181eee1d224720eb27666dce85c2f06eeedb Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Tue, 12 Mar 2024 14:44:09 +0100 Subject: [PATCH 18/71] refactor: Make no-extra-parens rule stricter --- eslint/general.js | 5 ++++- src/http/representation/ResourceIdentifier.ts | 2 +- src/server/middleware/StaticAssetHandler.ts | 2 +- src/util/IterableUtil.ts | 7 ++++++- .../identity/interaction/oidc/ClientInfoHandler.test.ts | 2 +- 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/eslint/general.js b/eslint/general.js index bb01b86b7..fe640d4a2 100644 --- a/eslint/general.js +++ b/eslint/general.js @@ -67,7 +67,10 @@ module.exports = { multiline: { delimiter: 'semi', requireLast: true }, singleline: { delimiter: 'semi', requireLast: false }, }], - 'style/no-extra-parens': [ 'error', 'functions' ], + 'style/no-extra-parens': [ 'error', 'all', { + // To prevent conflicts with style/no-mixed-operators + nestedBinaryExpressions: false, + }], 'style/object-curly-spacing': [ 'error', 'always', { objectsInObjects: false, arraysInObjects: false, diff --git a/src/http/representation/ResourceIdentifier.ts b/src/http/representation/ResourceIdentifier.ts index e01040916..41e773f70 100644 --- a/src/http/representation/ResourceIdentifier.ts +++ b/src/http/representation/ResourceIdentifier.ts @@ -12,5 +12,5 @@ export interface ResourceIdentifier { * Determines whether the object is a {@link ResourceIdentifier}. */ export function isResourceIdentifier(object: unknown): object is ResourceIdentifier { - return Boolean(object) && (typeof (object as ResourceIdentifier).path === 'string'); + return Boolean(object) && typeof (object as ResourceIdentifier).path === 'string'; } diff --git a/src/server/middleware/StaticAssetHandler.ts b/src/server/middleware/StaticAssetHandler.ts index 77632c3b1..5b6358e27 100644 --- a/src/server/middleware/StaticAssetHandler.ts +++ b/src/server/middleware/StaticAssetHandler.ts @@ -160,7 +160,7 @@ export class StaticAssetHandler extends HttpHandler { { // eslint-disable-next-line ts/naming-convention 'cache-control': `max-age=${this.expires}`, - expires: new Date(Date.now() + (this.expires * 1000)).toUTCString(), + expires: new Date(Date.now() + this.expires * 1000).toUTCString(), }; } } diff --git a/src/util/IterableUtil.ts b/src/util/IterableUtil.ts index 4b6ecb176..dda2cf40f 100644 --- a/src/util/IterableUtil.ts +++ b/src/util/IterableUtil.ts @@ -184,7 +184,12 @@ async function findNextSorted( export async function* sortedAsyncMerge(iterators: AsyncIterator[], comparator?: (left: T, right: T) => number): AsyncIterable { if (!comparator) { - comparator = (left, right): number => left < right ? -1 : (left > right ? 1 : 0); + comparator = (left, right): number => { + if (left < right) { + return -1; + } + return left > right ? 1 : 0; + }; } // Initialize the array to the first result of every iterator diff --git a/test/unit/identity/interaction/oidc/ClientInfoHandler.test.ts b/test/unit/identity/interaction/oidc/ClientInfoHandler.test.ts index 385792df4..ef4643ba9 100644 --- a/test/unit/identity/interaction/oidc/ClientInfoHandler.test.ts +++ b/test/unit/identity/interaction/oidc/ClientInfoHandler.test.ts @@ -23,7 +23,7 @@ describe('A ClientInfoHandler', (): void => { provider = { Client: { - find: (id: string): any => (id ? { metadata: jest.fn().mockReturnValue(clientMetadata) } : undefined), + find: (id: string): any => id ? { metadata: jest.fn().mockReturnValue(clientMetadata) } : undefined, }, } as any; From 5c1553bdda1ebd63e8cceb95f22a3734e5dd3bbd Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Tue, 12 Mar 2024 14:46:48 +0100 Subject: [PATCH 19/71] refactor: Enable no-unnecessary-type-arguments rule --- eslint/typed.js | 1 + src/storage/patch/N3Patcher.ts | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/eslint/typed.js b/eslint/typed.js index b2214102e..bf925de74 100644 --- a/eslint/typed.js +++ b/eslint/typed.js @@ -12,6 +12,7 @@ const typeAwareRules = { 'ts/no-implied-eval': 'error', 'ts/no-misused-promises': 'error', 'ts/no-throw-literal': 'error', + 'ts/no-unnecessary-type-arguments': 'error', 'ts/no-unnecessary-type-assertion': 'error', 'ts/no-unsafe-argument': 'error', 'ts/no-unsafe-assignment': 'error', diff --git a/src/storage/patch/N3Patcher.ts b/src/storage/patch/N3Patcher.ts index 47f47da29..f04bee784 100644 --- a/src/storage/patch/N3Patcher.ts +++ b/src/storage/patch/N3Patcher.ts @@ -140,9 +140,9 @@ export class N3Patcher extends RepresentationPatcher { } // Apply bindings to deletes/inserts - deletes = deletes.map((quad): Quad => mapTerms(quad, (term): Term => + deletes = deletes.map((quad): Quad => mapTerms(quad, (term): Term => term.termType === 'Variable' ? bindings[0].get(term)! : term)); - inserts = inserts.map((quad): Quad => mapTerms(quad, (term): Term => + inserts = inserts.map((quad): Quad => mapTerms(quad, (term): Term => term.termType === 'Variable' ? bindings[0].get(term)! : term)); } From c24e6d5a18ff664a08ecd1a6fae068f0e3127eeb Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Tue, 12 Mar 2024 14:51:55 +0100 Subject: [PATCH 20/71] refactor: Enable consistent-this rule --- eslint/general.js | 1 + src/storage/quota/QuotaStrategy.ts | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/eslint/general.js b/eslint/general.js index fe640d4a2..bf05ce45c 100644 --- a/eslint/general.js +++ b/eslint/general.js @@ -4,6 +4,7 @@ module.exports = { 'arrow-body-style': [ 'error', 'as-needed', { requireReturnForObjectLiteral: false }], 'capitalized-comments': [ 'error', 'always', { ignoreConsecutiveComments: true }], + 'consistent-this': 'error', curly: [ 'error', 'all' ], 'default-case': 'error', eqeqeq: [ 'error', 'always' ], diff --git a/src/storage/quota/QuotaStrategy.ts b/src/storage/quota/QuotaStrategy.ts index a09c95a6a..8c5d3568e 100644 --- a/src/storage/quota/QuotaStrategy.ts +++ b/src/storage/quota/QuotaStrategy.ts @@ -83,13 +83,13 @@ export abstract class QuotaStrategy { */ public async createQuotaGuard(identifier: ResourceIdentifier): Promise> { let total = 0; - const strategy = this; + const that = this; const { reporter } = this; return guardStream(new PassThrough({ async transform(this, chunk: any, enc: string, done: () => void): Promise { total += await reporter.calculateChunkSize(chunk); - const availableSpace = await strategy.getAvailableSpace(identifier); + const availableSpace = await that.getAvailableSpace(identifier); if (availableSpace.amount < total) { this.destroy(new PayloadHttpError( `Quota exceeded by ${total - availableSpace.amount} ${availableSpace.unit} during write`, From c65096020e4abc85bdc1b245cd904a4eb0cf794c Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Tue, 12 Mar 2024 15:04:49 +0100 Subject: [PATCH 21/71] refactor: Enable prefer-global rules --- eslint/general.js | 6 ++++-- src/init/ServerInitializer.ts | 1 - src/logging/Logger.ts | 1 - src/util/identifiers/BaseIdentifierStrategy.ts | 1 - test/unit/logging/Logger.test.ts | 1 - 5 files changed, 4 insertions(+), 6 deletions(-) diff --git a/eslint/general.js b/eslint/general.js index bf05ce45c..2930769b9 100644 --- a/eslint/general.js +++ b/eslint/general.js @@ -50,8 +50,10 @@ module.exports = { 'jsdoc/no-multi-asterisks': [ 'error', { allowWhitespace: true }], - 'node/prefer-global/buffer': 'off', - 'node/prefer-global/process': 'off', + 'node/prefer-global/buffer': [ 'error', 'always' ], + 'node/prefer-global/console': [ 'error', 'always' ], + 'node/prefer-global/process': [ 'error', 'always' ], + 'node/prefer-global/url': [ 'error', 'always' ], 'style/array-bracket-spacing': [ 'error', 'always', { singleValue: true, diff --git a/src/init/ServerInitializer.ts b/src/init/ServerInitializer.ts index b379f1d6d..27afa4002 100644 --- a/src/init/ServerInitializer.ts +++ b/src/init/ServerInitializer.ts @@ -1,5 +1,4 @@ import type { Server } from 'node:http'; -import { URL } from 'node:url'; import { promisify } from 'node:util'; import { getLoggerFor } from '../logging/LogUtil'; import { isHttpsServer } from '../server/HttpServerFactory'; diff --git a/src/logging/Logger.ts b/src/logging/Logger.ts index e97b1ba72..5bcbb81e8 100644 --- a/src/logging/Logger.ts +++ b/src/logging/Logger.ts @@ -1,5 +1,4 @@ import cluster from 'node:cluster'; -import process from 'node:process'; import type { LogLevel } from './LogLevel'; export interface LogMetadata { diff --git a/src/util/identifiers/BaseIdentifierStrategy.ts b/src/util/identifiers/BaseIdentifierStrategy.ts index 48260028f..b466198a8 100644 --- a/src/util/identifiers/BaseIdentifierStrategy.ts +++ b/src/util/identifiers/BaseIdentifierStrategy.ts @@ -1,4 +1,3 @@ -import { URL } from 'node:url'; import type { ResourceIdentifier } from '../../http/representation/ResourceIdentifier'; import { errorTermsToMetadata } from '../errors/HttpErrorUtil'; import { InternalServerError } from '../errors/InternalServerError'; diff --git a/test/unit/logging/Logger.test.ts b/test/unit/logging/Logger.test.ts index 88aeda11b..212f6717d 100644 --- a/test/unit/logging/Logger.test.ts +++ b/test/unit/logging/Logger.test.ts @@ -1,4 +1,3 @@ -import process from 'node:process'; import { BaseLogger, WrappingLogger } from '../../../src/logging/Logger'; import type { LogMetadata, SimpleLogger } from '../../../src/logging/Logger'; From c96b60d4d33adb2baba40fb1f266b35e2b37df84 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Tue, 12 Mar 2024 15:36:47 +0100 Subject: [PATCH 22/71] refactor: Enable callback-return rule --- eslint/general.js | 1 + src/util/SliceStream.ts | 2 +- templates/scripts/util.js | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/eslint/general.js b/eslint/general.js index 2930769b9..4bb61b991 100644 --- a/eslint/general.js +++ b/eslint/general.js @@ -4,6 +4,7 @@ module.exports = { 'arrow-body-style': [ 'error', 'as-needed', { requireReturnForObjectLiteral: false }], 'capitalized-comments': [ 'error', 'always', { ignoreConsecutiveComments: true }], + 'callback-return': 'error', 'consistent-this': 'error', curly: [ 'error', 'all' ], 'default-case': 'error', diff --git a/src/util/SliceStream.ts b/src/util/SliceStream.ts index 0586b7008..f26b1477a 100644 --- a/src/util/SliceStream.ts +++ b/src/util/SliceStream.ts @@ -65,8 +65,8 @@ export class SliceStream extends Transform { this.binarySlice(chunk as Buffer); } - callback(); this.source.resume(); + callback(); } protected binarySlice(chunk: Buffer): void { diff --git a/templates/scripts/util.js b/templates/scripts/util.js index bd0571ac6..f55e7716f 100644 --- a/templates/scripts/util.js +++ b/templates/scripts/util.js @@ -62,7 +62,7 @@ function addPostListener(callback, formId = 'mainForm', errorId = 'error') { event.preventDefault(); try { - await callback(); + return await callback(); } catch (error) { setError(error.message, errorId); } From 73fbe80cff436277dd6bc29e9cfdf4aac02dbf2a Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Tue, 12 Mar 2024 15:43:52 +0100 Subject: [PATCH 23/71] refactor: Enable global-require rule --- eslint/general.js | 1 + test/util/SetupTests.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/eslint/general.js b/eslint/general.js index 4bb61b991..2ecd1b0ec 100644 --- a/eslint/general.js +++ b/eslint/general.js @@ -14,6 +14,7 @@ module.exports = { 'function-call-argument-newline': [ 'error', 'consistent' ], 'function-paren-newline': [ 'error', 'consistent' ], 'getter-return': [ 'error', { allowImplicit: true }], + 'global-require': 'error', 'grouped-accessor-pairs': [ 'error', 'getBeforeSet' ], 'guard-for-in': 'error', 'line-comment-position': [ 'error', { position: 'above' }], diff --git a/test/util/SetupTests.ts b/test/util/SetupTests.ts index 520b3309a..ebebad1da 100644 --- a/test/util/SetupTests.ts +++ b/test/util/SetupTests.ts @@ -12,7 +12,7 @@ export default async function(): Promise { // Also set the logger factory of transpiled JS modules // (which are instantiated by Components.js) try { - // eslint-disable-next-line ts/no-var-requires,ts/no-require-imports + // eslint-disable-next-line global-require,ts/no-var-requires,ts/no-require-imports const dist = require('../../dist/logging/LogUtil'); dist.setGlobalLoggerFactory(loggerFactory); } catch { From 331f83d6591ca3b2313158b32dc9774b4cb9d8b6 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Tue, 12 Mar 2024 16:24:21 +0100 Subject: [PATCH 24/71] refactor: Enable style/indent-binary-ops rule --- eslint/general.js | 3 +-- src/authorization/ParentContainerReader.ts | 4 +++- src/http/input/metadata/LinkRelParser.ts | 6 ++++-- src/storage/conversion/ConversionUtil.ts | 8 ++++---- src/storage/mapping/ExtensionBasedMapper.ts | 2 +- src/util/HeaderUtil.ts | 11 +++++++---- src/util/errors/ErrorUtil.ts | 4 ++-- src/util/errors/HttpError.ts | 2 +- src/util/handlers/ProcessHandler.ts | 2 +- src/util/templates/StaticTemplateEngine.ts | 2 +- test/unit/storage/patch/SparqlUpdatePatcher.test.ts | 4 ++-- 11 files changed, 27 insertions(+), 21 deletions(-) diff --git a/eslint/general.js b/eslint/general.js index 2ecd1b0ec..ccacf5ae9 100644 --- a/eslint/general.js +++ b/eslint/general.js @@ -66,8 +66,7 @@ module.exports = { 'style/block-spacing': 'off', 'style/brace-style': [ 'error', '1tbs', { allowSingleLine: false }], 'style/generator-star-spacing': [ 'error', { before: false, after: true }], - // Seems to be inconsistent in when it adds indentation and when it does not - 'style/indent-binary-ops': 'off', + 'style/indent-binary-ops': 'error', 'style/member-delimiter-style': [ 'error', { multiline: { delimiter: 'semi', requireLast: true }, singleline: { delimiter: 'semi', requireLast: false }, diff --git a/src/authorization/ParentContainerReader.ts b/src/authorization/ParentContainerReader.ts index 7ba0ea596..dc6f90387 100644 --- a/src/authorization/ParentContainerReader.ts +++ b/src/authorization/ParentContainerReader.ts @@ -102,7 +102,9 @@ export class ParentContainerReader extends PermissionReader { // When an operation requests to delete a resource, // the server MUST match Authorizations allowing the acl:Write access privilege // on the resource and the containing container. - mergedPermission.delete = resourcePermission.write && containerPermission.write && + mergedPermission.delete = + resourcePermission.write && + containerPermission.write && resourcePermission.delete !== false; return mergedPermission; diff --git a/src/http/input/metadata/LinkRelParser.ts b/src/http/input/metadata/LinkRelParser.ts index 549a9957c..f9d518f3f 100644 --- a/src/http/input/metadata/LinkRelParser.ts +++ b/src/http/input/metadata/LinkRelParser.ts @@ -67,8 +67,10 @@ export class LinkRelObject { if (this.objectAllowed(object)) { if (this.ephemeral) { metadata.add(this.value, namedNode(object), SOLID_META.terms.ResponseMetadata); - logger.debug(`"<${metadata.identifier.value}> <${this.value.value}> <${object}>." ` + -`will not be stored permanently in the metadata.`); + logger.debug( + `"<${metadata.identifier.value}> <${this.value.value}> <${object}>." ` + + `will not be stored permanently in the metadata.`, + ); } else { metadata.add(this.value, namedNode(object)); } diff --git a/src/storage/conversion/ConversionUtil.ts b/src/storage/conversion/ConversionUtil.ts index ac282a8c0..3b7dc6fae 100644 --- a/src/storage/conversion/ConversionUtil.ts +++ b/src/storage/conversion/ConversionUtil.ts @@ -79,10 +79,10 @@ export function getTypeWeight(type: string, preferred: ValuePreferences): number // specific media types. If more than one media range applies to a // given type, the most specific reference has precedence. return preferred[type] ?? - preferred[`${main}/${sub}`] ?? - preferred[`${main}/*`] ?? - preferred['*/*'] ?? - 0; + preferred[`${main}/${sub}`] ?? + preferred[`${main}/*`] ?? + preferred['*/*'] ?? + 0; } /** diff --git a/src/storage/mapping/ExtensionBasedMapper.ts b/src/storage/mapping/ExtensionBasedMapper.ts index 4b59e77c2..98f1a16d3 100644 --- a/src/storage/mapping/ExtensionBasedMapper.ts +++ b/src/storage/mapping/ExtensionBasedMapper.ts @@ -84,7 +84,7 @@ export class ExtensionBasedMapper extends BaseFileIdentifierMapper { const extension = getExtension(filePath).toLowerCase(); return mime.lookup(extension) || this.customTypes[extension] || - await super.getContentTypeFromPath(filePath); + await super.getContentTypeFromPath(filePath); } /** diff --git a/src/util/HeaderUtil.ts b/src/util/HeaderUtil.ts index 9e5a3a140..18a26dbaa 100644 --- a/src/util/HeaderUtil.ts +++ b/src/util/HeaderUtil.ts @@ -119,8 +119,8 @@ export function parseParameters(parameters: string[], replacements: Record, str weight = parseQValue(value); } else { if (!value && map !== extensionParams) { - handleInvalidValue(`Invalid Accept parameter ${name}: ` + - `Accept parameter values are not optional when preceding the q value`, strict); + handleInvalidValue( + `Invalid Accept parameter ${name}: ` + + `Accept parameter values are not optional when preceding the q value`, + strict, + ); continue; } map[name] = value || ''; diff --git a/src/util/errors/ErrorUtil.ts b/src/util/errors/ErrorUtil.ts index adcca72b4..6ab51b10f 100644 --- a/src/util/errors/ErrorUtil.ts +++ b/src/util/errors/ErrorUtil.ts @@ -7,8 +7,8 @@ export function isError(error: unknown): error is Error { return types.isNativeError(error) || (Boolean(error) && typeof (error as Error).name === 'string' && - typeof (error as Error).message === 'string' && - (typeof (error as Error).stack === 'undefined' || typeof (error as Error).stack === 'string')); + typeof (error as Error).message === 'string' && + (typeof (error as Error).stack === 'undefined' || typeof (error as Error).stack === 'string')); } /** diff --git a/src/util/errors/HttpError.ts b/src/util/errors/HttpError.ts index ac81e4f5a..aeb9b440f 100644 --- a/src/util/errors/HttpError.ts +++ b/src/util/errors/HttpError.ts @@ -47,7 +47,7 @@ export class HttpError extends Error implements HttpE public static isInstance(error: any): error is HttpError { return isError(error) && typeof (error as HttpError).statusCode === 'number' && - Boolean((error as HttpError).metadata); + Boolean((error as HttpError).metadata); } /** diff --git a/src/util/handlers/ProcessHandler.ts b/src/util/handlers/ProcessHandler.ts index 70144de93..2711ee4e3 100644 --- a/src/util/handlers/ProcessHandler.ts +++ b/src/util/handlers/ProcessHandler.ts @@ -41,6 +41,6 @@ export class ProcessHandler extends AsyncHandler { */ private canExecute(): boolean { return this.clusterManager.isSingleThreaded() || - (this.executeOnPrimary ? this.clusterManager.isPrimary() : this.clusterManager.isWorker()); + (this.executeOnPrimary ? this.clusterManager.isPrimary() : this.clusterManager.isWorker()); } } diff --git a/src/util/templates/StaticTemplateEngine.ts b/src/util/templates/StaticTemplateEngine.ts index 9e62de795..b1191c620 100644 --- a/src/util/templates/StaticTemplateEngine.ts +++ b/src/util/templates/StaticTemplateEngine.ts @@ -25,7 +25,7 @@ export class StaticTemplateEngine = Dict> extends Templ public async canHandle({ contents, template }: TemplateEngineInput): Promise { if (typeof template !== 'undefined') { throw new TypeError('StaticTemplateEngine does not support template as handle input, ' + - 'provide a template via the constructor instead!'); + 'provide a template via the constructor instead!'); } return this.templateEngine.canHandle({ contents, template: this.template }); } diff --git a/test/unit/storage/patch/SparqlUpdatePatcher.test.ts b/test/unit/storage/patch/SparqlUpdatePatcher.test.ts index 02717dcaa..72b5a262c 100644 --- a/test/unit/storage/patch/SparqlUpdatePatcher.test.ts +++ b/test/unit/storage/patch/SparqlUpdatePatcher.test.ts @@ -134,7 +134,7 @@ describe('A SparqlUpdatePatcher', (): void => { it('handles composite INSERT/DELETE updates.', async(): Promise => { const query = 'INSERT DATA { :s1 :p1 :o1 . :s2 :p2 :o2 };' + - 'DELETE WHERE { :s1 :p1 :o1 . :startS1 :startP1 :startO1 }'; + 'DELETE WHERE { :s1 :p1 :o1 . :startS1 :startP1 :startO1 }'; input.patch = getPatch(query); const result = await patcher.handle(input); expect(result.dataset).toBeRdfIsomorphic([ @@ -153,7 +153,7 @@ describe('A SparqlUpdatePatcher', (): void => { it('handles composite DELETE/INSERT updates.', async(): Promise => { const query = 'DELETE DATA { :s1 :p1 :o1 . :startS1 :startP1 :startO1 } ;' + - 'INSERT DATA { :s1 :p1 :o1 . :s2 :p2 :o2 }'; + 'INSERT DATA { :s1 :p1 :o1 . :s2 :p2 :o2 }'; input.patch = getPatch(query); const result = await patcher.handle(input); expect(result.dataset).toBeRdfIsomorphic([ From b381a9c926960513dc07557ecd44701c0838faf5 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Wed, 13 Mar 2024 10:44:51 +0100 Subject: [PATCH 25/71] refactor: Enable ts/no-explicit-any rule --- eslint/general.js | 1 + eslint/test.js | 1 + .../output/error/ConvertingErrorHandler.ts | 4 ++-- .../representation/BasicRepresentation.ts | 15 +++++++------ .../representation/RepresentationMetadata.ts | 14 ++++++++----- .../configuration/IdentityProviderFactory.ts | 16 +++++++++----- src/identity/interaction/ControlHandler.ts | 3 ++- src/identity/interaction/InteractionUtil.ts | 6 +----- .../interaction/JsonConversionHandler.ts | 2 +- .../interaction/JsonInteractionHandler.ts | 3 ++- .../interaction/OidcControlHandler.ts | 2 +- .../interaction/StaticInteractionHandler.ts | 3 ++- src/identity/interaction/YupUtil.ts | 21 ++++++++++--------- .../account/util/BaseAccountStore.ts | 5 +++-- .../util/BaseClientCredentialsStore.ts | 5 +++-- .../interaction/login/ResolveLoginHandler.ts | 3 ++- .../password/util/BasePasswordStore.ts | 5 +++-- .../interaction/pod/util/BasePodStore.ts | 5 +++-- .../routing/InteractionRouteHandler.ts | 2 +- .../interaction/webid/util/BaseWebIdStore.ts | 5 +++-- src/index.ts | 1 + src/init/AppRunner.ts | 6 +++--- src/init/cli/YargsCliExtractor.ts | 2 +- src/init/migration/V6MigrationInitializer.ts | 9 ++++---- .../variables/CombinedShorthandResolver.ts | 2 +- src/logging/WinstonLogger.ts | 2 +- src/logging/WinstonLoggerFactory.ts | 3 ++- src/pods/generate/BaseComponentsJsFactory.ts | 6 +++--- src/pods/generate/ComponentsJsFactory.ts | 2 +- src/server/middleware/CorsHandler.ts | 6 +++--- src/server/util/BaseRouterHandler.ts | 4 ++-- src/storage/LockingResourceStore.ts | 2 +- src/storage/accessors/FileDataAccessor.ts | 2 +- src/storage/accessors/InMemoryDataAccessor.ts | 2 +- .../DynamicJsonToTemplateConverter.ts | 2 +- src/storage/quota/GlobalQuotaStrategy.ts | 2 +- src/storage/quota/PodQuotaStrategy.ts | 2 +- src/storage/quota/QuotaStrategy.ts | 6 +++--- src/util/GenericEventEmitter.ts | 1 + src/util/IterableUtil.ts | 11 ++++++---- src/util/Json.ts | 4 ++++ src/util/LockUtils.ts | 2 +- src/util/PathUtil.ts | 5 +++-- src/util/RecordObject.ts | 7 ++++--- src/util/SliceStream.ts | 6 +++--- src/util/StreamUtil.ts | 15 ++++++------- src/util/Vocabularies.ts | 8 +++---- src/util/errors/HttpError.ts | 6 +++--- src/util/errors/RedirectHttpError.ts | 4 ++-- src/util/errors/SystemError.ts | 2 +- src/util/handlers/ArrayUnionHandler.ts | 2 +- src/util/handlers/AsyncHandler.ts | 4 ++-- src/util/handlers/CachedHandler.ts | 2 +- src/util/handlers/StaticHandler.ts | 2 +- src/util/handlers/StaticThrowHandler.ts | 2 +- src/util/handlers/UnionHandler.ts | 2 +- src/util/handlers/UnsupportedAsyncHandler.ts | 2 +- src/util/map/HashMap.ts | 4 ++-- src/util/map/MapUtil.ts | 13 ++++++------ src/util/map/SetMultiMap.ts | 2 +- src/util/map/WrappedSetMultiMap.ts | 2 +- src/util/templates/ChainedTemplateEngine.ts | 2 +- src/util/templates/EjsTemplateEngine.ts | 2 +- .../templates/ExtensionBasedTemplateEngine.ts | 2 +- .../templates/HandlebarsTemplateEngine.ts | 2 +- src/util/templates/StaticTemplateEngine.ts | 2 +- src/util/templates/TemplateEngine.ts | 2 +- 67 files changed, 167 insertions(+), 135 deletions(-) create mode 100644 src/util/Json.ts diff --git a/eslint/general.js b/eslint/general.js index ccacf5ae9..b274a15a4 100644 --- a/eslint/general.js +++ b/eslint/general.js @@ -101,6 +101,7 @@ module.exports = { 'ts/explicit-member-accessibility': 'error', 'ts/method-signature-style': 'error', 'ts/no-confusing-non-null-assertion': 'error', + 'ts/no-explicit-any': 'error', 'ts/no-extraneous-class': [ 'error', { allowConstructorOnly: false, allowEmpty: false, diff --git a/eslint/test.js b/eslint/test.js index ad5bb33d4..c62c4efe5 100644 --- a/eslint/test.js +++ b/eslint/test.js @@ -32,6 +32,7 @@ module.exports = { 'test/prefer-lowercase-title': 'off', 'ts/naming-convention': 'off', + 'ts/no-explicit-any': 'off', 'ts/no-unsafe-argument': 'off', 'ts/no-unsafe-assignment': 'off', 'ts/no-unsafe-call': 'off', diff --git a/src/http/output/error/ConvertingErrorHandler.ts b/src/http/output/error/ConvertingErrorHandler.ts index 1a0687529..d58150dec 100644 --- a/src/http/output/error/ConvertingErrorHandler.ts +++ b/src/http/output/error/ConvertingErrorHandler.ts @@ -62,8 +62,8 @@ export class ConvertingErrorHandler extends ErrorHandler { private async extractErrorDetails({ error, request }: ErrorHandlerArgs): Promise { if (!this.showStackTrace) { delete error.stack; - // eslint-disable-next-line ts/no-unsafe-member-access - delete (error as any).cause; + // Cheating here to delete a readonly field + delete (error as { cause: unknown }).cause; } const representation = new BasicRepresentation([ error ], error.metadata, INTERNAL_ERROR, false); const identifier = { path: representation.metadata.identifier.value }; diff --git a/src/http/representation/BasicRepresentation.ts b/src/http/representation/BasicRepresentation.ts index 9c961805b..4cb1a7756 100644 --- a/src/http/representation/BasicRepresentation.ts +++ b/src/http/representation/BasicRepresentation.ts @@ -35,7 +35,7 @@ export class BasicRepresentation implements Representation { * @param binary - Whether the representation is a binary or object stream */ public constructor( - data: Guarded | Readable | any[] | string, + data: Guarded | Readable | unknown[] | string, metadata: RepresentationMetadata | MetadataRecord, binary?: boolean, ); @@ -47,7 +47,7 @@ export class BasicRepresentation implements Representation { * @param binary - Whether the representation is a binary or object stream */ public constructor( - data: Guarded | Readable | any[] | string, + data: Guarded | Readable | unknown[] | string, metadata: RepresentationMetadata | MetadataRecord, contentType?: string, binary?: boolean, @@ -59,7 +59,7 @@ export class BasicRepresentation implements Representation { * @param binary - Whether the representation is a binary or object stream */ public constructor( - data: Guarded | Readable | any[] | string, + data: Guarded | Readable | unknown[] | string, contentType: string, binary?: boolean, ); @@ -71,7 +71,7 @@ export class BasicRepresentation implements Representation { * @param binary - Whether the representation is a binary or object stream */ public constructor( - data: Guarded | Readable | any[] | string, + data: Guarded | Readable | unknown[] | string, identifier: MetadataIdentifier, metadata?: MetadataRecord, binary?: boolean, @@ -84,14 +84,14 @@ export class BasicRepresentation implements Representation { * @param binary - Whether the representation is a binary or object stream */ public constructor( - data: Guarded | Readable | any[] | string, + data: Guarded | Readable | unknown[] | string, identifier: MetadataIdentifier, contentType?: string, binary?: boolean, ); public constructor( - data?: Readable | any[] | string, + data?: Readable | unknown[] | string, metadata?: RepresentationMetadata | MetadataRecord | MetadataIdentifier | string, metadataRest?: MetadataRecord | string | boolean, binary?: boolean, @@ -109,8 +109,7 @@ export class BasicRepresentation implements Representation { } if (!isRepresentationMetadata(metadata) || typeof metadataRest === 'string') { // This combination will always match with a valid overload - // eslint-disable-next-line ts/no-unsafe-argument - metadata = new RepresentationMetadata(metadata as any, metadataRest as any); + metadata = new RepresentationMetadata(metadata as RepresentationMetadata, metadataRest as string); } this.metadata = metadata; diff --git a/src/http/representation/RepresentationMetadata.ts b/src/http/representation/RepresentationMetadata.ts index d85a0f66a..e96465752 100644 --- a/src/http/representation/RepresentationMetadata.ts +++ b/src/http/representation/RepresentationMetadata.ts @@ -15,7 +15,7 @@ export type MetadataGraph = NamedNode | BlankNode | DefaultGraph | string; /** * Determines whether the object is a `RepresentationMetadata`. */ -export function isRepresentationMetadata(object: any): object is RepresentationMetadata { +export function isRepresentationMetadata(object: unknown): object is RepresentationMetadata { return typeof (object as RepresentationMetadata)?.setMetadata === 'function'; } @@ -240,7 +240,7 @@ export class RepresentationMetadata { * @param graph - Optional graph of where to add the values to. */ public add(predicate: NamedNode, object: MetadataValue, graph?: MetadataGraph): this { - return this.forQuads(predicate, object, (pred, obj): any => this.addQuad(this.id, pred, obj, graph)); + return this.forQuads(predicate, object, (pred, obj): unknown => this.addQuad(this.id, pred, obj, graph)); } /** @@ -250,7 +250,7 @@ export class RepresentationMetadata { * @param graph - Optional graph of where to remove the values from. */ public remove(predicate: NamedNode, object: MetadataValue, graph?: MetadataGraph): this { - return this.forQuads(predicate, object, (pred, obj): any => this.removeQuad(this.id, pred, obj, graph)); + return this.forQuads(predicate, object, (pred, obj): unknown => this.removeQuad(this.id, pred, obj, graph)); } /** @@ -290,8 +290,12 @@ export class RepresentationMetadata { ): boolean { // This works with N3.js but at the time of writing the typings have not been updated yet. // If you see this line of code check if the typings are already correct and update this if so. - // eslint-disable-next-line ts/no-unsafe-call - return (this.store.has as any)(this.id, predicate, object, graph) as boolean; + return (this.store as unknown as { + has: (subject: Term, + predicate: Term | string | null, + object: Term | string | null, + graph: Term | string | null) => boolean; + }).has(this.id, predicate, object, graph) as boolean; } /** diff --git a/src/identity/configuration/IdentityProviderFactory.ts b/src/identity/configuration/IdentityProviderFactory.ts index 026ce76aa..094750a4a 100644 --- a/src/identity/configuration/IdentityProviderFactory.ts +++ b/src/identity/configuration/IdentityProviderFactory.ts @@ -187,14 +187,20 @@ export class IdentityProviderFactory implements ProviderFactory { provider.use(async(ctx, next): Promise => { const accepts = ctx.accepts.bind(ctx); - // Using `any` typings to make sure we support all different versions of `ctx.accepts` - ctx.accepts = (...types): any => { + // This is how you get the correct typing for an overloaded function + type AcceptFn = { + (): string[]; + (...types: string[]): string | false; + (types: string[]): string | false; + }; + + ctx.accepts = ((...types): string[] | string | false => { // Make sure we only override our specific case if (types.length === 2 && types[0] === 'json' && types[1] === 'html') { return 'html'; } return accepts(...types as string[]); - }; + }) as AcceptFn; return next(); }); @@ -257,7 +263,7 @@ export class IdentityProviderFactory implements ProviderFactory { * Checks if the given token is an access token. * The AccessToken interface is not exported, so we have to access it like this. */ - private isAccessToken(token: any): token is KoaContextWithOIDC['oidc']['accessToken'] { + private isAccessToken(token: unknown): token is KoaContextWithOIDC['oidc']['accessToken'] { return (token as KoaContextWithOIDC['oidc']['accessToken'])?.kind === 'AccessToken'; } @@ -270,7 +276,7 @@ export class IdentityProviderFactory implements ProviderFactory { // Some fields are still missing, see https://github.com/CommunitySolidServer/CommunitySolidServer/issues/1154#issuecomment-1040233385 config.findAccount = async(ctx: KoaContextWithOIDC, sub: string): Promise => ({ accountId: sub, - async claims(): Promise<{ sub: string; [key: string]: any }> { + async claims(): Promise<{ sub: string; [key: string]: unknown }> { return { sub, webid: sub, azp: ctx.oidc.client?.clientId }; }, }); diff --git a/src/identity/interaction/ControlHandler.ts b/src/identity/interaction/ControlHandler.ts index 0c0506862..a50d5c5c4 100644 --- a/src/identity/interaction/ControlHandler.ts +++ b/src/identity/interaction/ControlHandler.ts @@ -1,5 +1,6 @@ +import type { Json } from '../../util/Json'; import { ACCOUNT_ID_KEY } from './account/AccountIdRoute'; -import type { Json, JsonRepresentation } from './InteractionUtil'; +import type { JsonRepresentation } from './InteractionUtil'; import type { JsonInteractionHandlerInput } from './JsonInteractionHandler'; import { JsonInteractionHandler } from './JsonInteractionHandler'; import type { InteractionRoute } from './routing/InteractionRoute'; diff --git a/src/identity/interaction/InteractionUtil.ts b/src/identity/interaction/InteractionUtil.ts index 3a1646077..6c3541884 100644 --- a/src/identity/interaction/InteractionUtil.ts +++ b/src/identity/interaction/InteractionUtil.ts @@ -3,16 +3,12 @@ import type Provider from '../../../templates/types/oidc-provider'; import type { RepresentationMetadata } from '../../http/representation/RepresentationMetadata'; import { getLoggerFor } from '../../logging/LogUtil'; import { BadRequestHttpError } from '../../util/errors/BadRequestHttpError'; +import type { Json } from '../../util/Json'; import type { Interaction } from './InteractionHandler'; import Dict = NodeJS.Dict; const logger = getLoggerFor('AccountUtil'); -/** - * A JSON object. - */ -export type Json = string | number | boolean | Dict | Json[]; - /** * Contains a JSON object and any associated metadata. * Similar to a {@link Representation} but with all the data in memory instead of as a stream diff --git a/src/identity/interaction/JsonConversionHandler.ts b/src/identity/interaction/JsonConversionHandler.ts index 80af8ada1..d165ca0d7 100644 --- a/src/identity/interaction/JsonConversionHandler.ts +++ b/src/identity/interaction/JsonConversionHandler.ts @@ -3,10 +3,10 @@ import type { Representation } from '../../http/representation/Representation'; import { RepresentationMetadata } from '../../http/representation/RepresentationMetadata'; import type { RepresentationConverter } from '../../storage/conversion/RepresentationConverter'; import { APPLICATION_JSON } from '../../util/ContentTypes'; +import type { Json } from '../../util/Json'; import { readJsonStream } from '../../util/StreamUtil'; import type { InteractionHandlerInput } from './InteractionHandler'; import { InteractionHandler } from './InteractionHandler'; -import type { Json } from './InteractionUtil'; import type { JsonInteractionHandler, JsonInteractionHandlerInput } from './JsonInteractionHandler'; /** diff --git a/src/identity/interaction/JsonInteractionHandler.ts b/src/identity/interaction/JsonInteractionHandler.ts index 9846c95eb..7ccc95b9d 100644 --- a/src/identity/interaction/JsonInteractionHandler.ts +++ b/src/identity/interaction/JsonInteractionHandler.ts @@ -1,8 +1,9 @@ import type { RepresentationMetadata } from '../../http/representation/RepresentationMetadata'; import type { ResourceIdentifier } from '../../http/representation/ResourceIdentifier'; import { AsyncHandler } from '../../util/handlers/AsyncHandler'; +import type { Json } from '../../util/Json'; import type { Interaction } from './InteractionHandler'; -import type { Json, JsonRepresentation } from './InteractionUtil'; +import type { JsonRepresentation } from './InteractionUtil'; import Dict = NodeJS.Dict; export interface JsonInteractionHandlerInput { diff --git a/src/identity/interaction/OidcControlHandler.ts b/src/identity/interaction/OidcControlHandler.ts index 7da91bc8c..0282254b0 100644 --- a/src/identity/interaction/OidcControlHandler.ts +++ b/src/identity/interaction/OidcControlHandler.ts @@ -1,5 +1,5 @@ +import type { Json } from '../../util/Json'; import { ControlHandler } from './ControlHandler'; -import type { Json } from './InteractionUtil'; import type { JsonInteractionHandlerInput } from './JsonInteractionHandler'; /** diff --git a/src/identity/interaction/StaticInteractionHandler.ts b/src/identity/interaction/StaticInteractionHandler.ts index 6833a2d2f..661445099 100644 --- a/src/identity/interaction/StaticInteractionHandler.ts +++ b/src/identity/interaction/StaticInteractionHandler.ts @@ -1,4 +1,5 @@ -import type { Json, JsonRepresentation } from './InteractionUtil'; +import type { Json } from '../../util/Json'; +import type { JsonRepresentation } from './InteractionUtil'; import { JsonInteractionHandler } from './JsonInteractionHandler'; /** diff --git a/src/identity/interaction/YupUtil.ts b/src/identity/interaction/YupUtil.ts index fb48caff6..242818658 100644 --- a/src/identity/interaction/YupUtil.ts +++ b/src/identity/interaction/YupUtil.ts @@ -1,11 +1,13 @@ import { string } from 'yup'; -import type { ObjectSchema, Schema, ValidateOptions } from 'yup'; +import type { AnyObject, Maybe, ObjectSchema, Schema, ValidateOptions } from 'yup'; import { BadRequestHttpError } from '../../util/errors/BadRequestHttpError'; import { createErrorMessage } from '../../util/errors/ErrorUtil'; +import type { Json } from '../../util/Json'; import { isUrl } from '../../util/StringUtil'; -import type { Json } from './InteractionUtil'; import Dict = NodeJS.Dict; +type BaseObjectSchema = ObjectSchema>; + // The builtin `url` validator of `yup` does not support localhost URLs, so we create a custom one here. // The reason for having a URL validator on the WebID is to prevent us from generating invalid ACL, // which would break the pod creation causing us to have an incomplete pod. @@ -20,16 +22,16 @@ export const URL_SCHEMA = string().trim().optional().test({ }, }); -function isObjectSchema(schema: Schema): schema is ObjectSchema { +function isObjectSchema(schema: Schema): schema is BaseObjectSchema { return schema.type === 'object'; } // `T` can't extend Schema since it could also be a Reference, which is a type `yup` doesn't export -type SchemaType = T extends ObjectSchema ? ObjectType : { required: boolean; type: string }; +type SchemaType = T extends BaseObjectSchema ? ObjectType : { required: boolean; type: string }; // The type of the fields in an object schema -type FieldType> = T extends { fields: Record } ? R : never; +type FieldType = T extends { fields: Record } ? R : never; // Simplified type we use to represent yup objects -type ObjectType> = +type ObjectType = { required: boolean; type: 'object'; fields: {[ K in FieldType ]: SchemaType }}; /** @@ -50,7 +52,7 @@ function parseSchemaDescription(schema: T): SchemaType { /** * Generates a simplified representation of a yup schema. */ -export function parseSchema>(schema: T): Pick, 'fields'> { +export function parseSchema(schema: T): Pick, 'fields'> { const result = parseSchemaDescription(schema); return { fields: result.fields }; } @@ -58,13 +60,12 @@ export function parseSchema>(schema: T): Pick>( +export async function validateWithError( schema: T, data: unknown, - options?: ValidateOptions, + options?: ValidateOptions, ): Promise { try { - // eslint-disable-next-line ts/no-unsafe-return return await schema.validate(data, options); } catch (error: unknown) { throw new BadRequestHttpError(createErrorMessage(error)); diff --git a/src/identity/interaction/account/util/BaseAccountStore.ts b/src/identity/interaction/account/util/BaseAccountStore.ts index f1e8aa0a2..200d398cb 100644 --- a/src/identity/interaction/account/util/BaseAccountStore.ts +++ b/src/identity/interaction/account/util/BaseAccountStore.ts @@ -22,9 +22,10 @@ export class BaseAccountStore extends Initializer implements AccountStore { private readonly storage: AccountLoginStorage<{ [ACCOUNT_TYPE]: typeof ACCOUNT_STORAGE_DESCRIPTION }>; private initialized = false; - public constructor(storage: AccountLoginStorage) { + // Wrong typings to prevent Components.js typing issues + public constructor(storage: AccountLoginStorage>) { super(); - this.storage = storage as typeof this.storage; + this.storage = storage as unknown as typeof this.storage; } // Initialize the type definitions diff --git a/src/identity/interaction/client-credentials/util/BaseClientCredentialsStore.ts b/src/identity/interaction/client-credentials/util/BaseClientCredentialsStore.ts index 51e043d28..eb075722f 100644 --- a/src/identity/interaction/client-credentials/util/BaseClientCredentialsStore.ts +++ b/src/identity/interaction/client-credentials/util/BaseClientCredentialsStore.ts @@ -27,9 +27,10 @@ export class BaseClientCredentialsStore extends Initializer implements ClientCre private initialized = false; - public constructor(storage: AccountLoginStorage) { + // Wrong typings to prevent Components.js typing issues + public constructor(storage: AccountLoginStorage>) { super(); - this.storage = storage as typeof this.storage; + this.storage = storage as unknown as typeof this.storage; } // Initialize the type definitions diff --git a/src/identity/interaction/login/ResolveLoginHandler.ts b/src/identity/interaction/login/ResolveLoginHandler.ts index 142376f97..ddba472a2 100644 --- a/src/identity/interaction/login/ResolveLoginHandler.ts +++ b/src/identity/interaction/login/ResolveLoginHandler.ts @@ -1,10 +1,11 @@ import { RepresentationMetadata } from '../../../http/representation/RepresentationMetadata'; import { getLoggerFor } from '../../../logging/LogUtil'; +import type { Json } from '../../../util/Json'; import { SOLID_HTTP } from '../../../util/Vocabularies'; import { ACCOUNT_SETTINGS_REMEMBER_LOGIN } from '../account/util/AccountStore'; import type { AccountStore } from '../account/util/AccountStore'; import type { CookieStore } from '../account/util/CookieStore'; -import type { Json, JsonRepresentation } from '../InteractionUtil'; +import type { JsonRepresentation } from '../InteractionUtil'; import { finishInteraction } from '../InteractionUtil'; import type { JsonInteractionHandlerInput } from '../JsonInteractionHandler'; import { JsonInteractionHandler } from '../JsonInteractionHandler'; diff --git a/src/identity/interaction/password/util/BasePasswordStore.ts b/src/identity/interaction/password/util/BasePasswordStore.ts index 495418fee..997f3f998 100644 --- a/src/identity/interaction/password/util/BasePasswordStore.ts +++ b/src/identity/interaction/password/util/BasePasswordStore.ts @@ -29,9 +29,10 @@ export class BasePasswordStore extends Initializer implements PasswordStore { private readonly saltRounds: number; private initialized = false; - public constructor(storage: AccountLoginStorage, saltRounds = 10) { + // Wrong typings to prevent Components.js typing issues + public constructor(storage: AccountLoginStorage>, saltRounds = 10) { super(); - this.storage = storage as typeof this.storage; + this.storage = storage as unknown as typeof this.storage; this.saltRounds = saltRounds; } diff --git a/src/identity/interaction/pod/util/BasePodStore.ts b/src/identity/interaction/pod/util/BasePodStore.ts index 5bd249781..f6f9d2ac3 100644 --- a/src/identity/interaction/pod/util/BasePodStore.ts +++ b/src/identity/interaction/pod/util/BasePodStore.ts @@ -44,9 +44,10 @@ export class BasePodStore extends Initializer implements PodStore { private initialized = false; - public constructor(storage: AccountLoginStorage, manager: PodManager, visible = false) { + // Wrong typings to prevent Components.js typing issues + public constructor(storage: AccountLoginStorage>, manager: PodManager, visible = false) { super(); - this.storage = storage as typeof this.storage; + this.storage = storage as unknown as typeof this.storage; this.visible = visible; this.manager = manager; } diff --git a/src/identity/interaction/routing/InteractionRouteHandler.ts b/src/identity/interaction/routing/InteractionRouteHandler.ts index 45e204484..3482aa4c2 100644 --- a/src/identity/interaction/routing/InteractionRouteHandler.ts +++ b/src/identity/interaction/routing/InteractionRouteHandler.ts @@ -10,7 +10,7 @@ import type { InteractionRoute } from './InteractionRoute'; * Rejects operations that target a different route, * otherwise the input parameters are passed to the source handler. */ -export class InteractionRouteHandler> extends JsonInteractionHandler { +export class InteractionRouteHandler> extends JsonInteractionHandler { protected readonly route: T; protected readonly source: JsonInteractionHandler; diff --git a/src/identity/interaction/webid/util/BaseWebIdStore.ts b/src/identity/interaction/webid/util/BaseWebIdStore.ts index 8c1248c3a..2abd2d24f 100644 --- a/src/identity/interaction/webid/util/BaseWebIdStore.ts +++ b/src/identity/interaction/webid/util/BaseWebIdStore.ts @@ -23,9 +23,10 @@ export class BaseWebIdStore extends Initializer implements WebIdStore { private readonly storage: AccountLoginStorage<{ [WEBID_STORAGE_TYPE]: typeof WEBID_STORAGE_DESCRIPTION }>; private initialized = false; - public constructor(storage: AccountLoginStorage) { + // Wrong typings to prevent Components.js typing issues + public constructor(storage: AccountLoginStorage>) { super(); - this.storage = storage as typeof this.storage; + this.storage = storage as unknown as typeof this.storage; } // Initialize the type definitions diff --git a/src/index.ts b/src/index.ts index a57c18c4c..3e4c844d4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -615,6 +615,7 @@ export * from './util/GenericEventEmitter'; export * from './util/GuardedStream'; export * from './util/HeaderUtil'; export * from './util/IterableUtil'; +export * from './util/Json'; export * from './util/PathUtil'; export * from './util/PromiseUtil'; export * from './util/QuadUtil'; diff --git a/src/init/AppRunner.ts b/src/init/AppRunner.ts index 0f2f701c1..0baca15c3 100644 --- a/src/init/AppRunner.ts +++ b/src/init/AppRunner.ts @@ -105,9 +105,9 @@ export class AppRunner { let configs = input.config ?? [ '@css:config/default.json' ]; configs = (Array.isArray(configs) ? configs : [ configs ]).map(resolveAssetPath); - let componentsManager: ComponentsManager; + let componentsManager: ComponentsManager; try { - componentsManager = await this.createComponentsManager(loaderProperties, configs); + componentsManager = await this.createComponentsManager(loaderProperties, configs); } catch (error: unknown) { this.resolveError(`Could not build the config files from ${configs.join(',')}`, error); } @@ -227,7 +227,7 @@ export class AppRunner { // Finally try and read from the config.community-solid-server // field in the root package.json - const pkg = await readJSON(packageJsonPath) as { config?: Record }; + const pkg = await readJSON(packageJsonPath) as { config?: Record }; if (typeof pkg.config?.['community-solid-server'] === 'object') { return pkg.config['community-solid-server'] as Record; } diff --git a/src/init/cli/YargsCliExtractor.ts b/src/init/cli/YargsCliExtractor.ts index 7b711f91b..5b8922701 100644 --- a/src/init/cli/YargsCliExtractor.ts +++ b/src/init/cli/YargsCliExtractor.ts @@ -19,7 +19,7 @@ export class YargsParameter { * @param name - Name of the parameter. Corresponds to the first parameter passed to the `yargs.options` function. * @param options - Options for a single parameter that should be parsed. @range {json} */ - public constructor(name: string, options: Record) { + public constructor(name: string, options: Record) { this.name = name; this.options = options; } diff --git a/src/init/migration/V6MigrationInitializer.ts b/src/init/migration/V6MigrationInitializer.ts index 2a9afe274..a6da3e52f 100644 --- a/src/init/migration/V6MigrationInitializer.ts +++ b/src/init/migration/V6MigrationInitializer.ts @@ -68,11 +68,12 @@ export interface V6MigrationInitializerArgs { /** * Storages for which all entries need to be removed. */ - cleanupStorages: KeyValueStorage[]; + cleanupStorages: KeyValueStorage[]; /** * The storage that will contain the account data in the new format. + * Wrong typings to prevent Components.js typing issues. */ - newAccountStorage: AccountLoginStorage; + newAccountStorage: AccountLoginStorage>; /** * The storage that will contain the setup entries in the new format. */ @@ -100,7 +101,7 @@ export class V6MigrationInitializer extends Initializer { private readonly accountStorage: KeyValueStorage; private readonly clientCredentialsStorage: KeyValueStorage; - private readonly cleanupStorages: KeyValueStorage[]; + private readonly cleanupStorages: KeyValueStorage[]; private readonly newAccountStorage: AccountLoginStorage; private readonly newSetupStorage: KeyValueStorage; @@ -113,7 +114,7 @@ export class V6MigrationInitializer extends Initializer { this.accountStorage = args.accountStorage; this.clientCredentialsStorage = args.clientCredentialsStorage; this.cleanupStorages = args.cleanupStorages; - this.newAccountStorage = args.newAccountStorage as AccountLoginStorage; + this.newAccountStorage = args.newAccountStorage as unknown as AccountLoginStorage; this.newSetupStorage = args.newSetupStorage; } diff --git a/src/init/variables/CombinedShorthandResolver.ts b/src/init/variables/CombinedShorthandResolver.ts index 199706cf2..afa204b28 100644 --- a/src/init/variables/CombinedShorthandResolver.ts +++ b/src/init/variables/CombinedShorthandResolver.ts @@ -14,7 +14,7 @@ export class CombinedShorthandResolver extends ShorthandResolver { } public async handle(input: Record): Promise> { - const vars: Record = {}; + const vars: Record = {}; for (const [ name, computer ] of Object.entries(this.resolvers)) { try { vars[name] = await computer.handleSafe(input); diff --git a/src/logging/WinstonLogger.ts b/src/logging/WinstonLogger.ts index b2f6e9542..86381e357 100644 --- a/src/logging/WinstonLogger.ts +++ b/src/logging/WinstonLogger.ts @@ -13,7 +13,7 @@ export class WinstonLogger extends BaseLogger { this.logger = logger; } - public log(level: LogLevel, message: string, meta?: any): this { + public log(level: LogLevel, message: string, meta?: unknown): this { this.logger.log(level, message, meta); return this; } diff --git a/src/logging/WinstonLoggerFactory.ts b/src/logging/WinstonLoggerFactory.ts index a34c79334..66e0c5873 100644 --- a/src/logging/WinstonLoggerFactory.ts +++ b/src/logging/WinstonLoggerFactory.ts @@ -1,3 +1,4 @@ +import type { TransformableInfo } from 'logform'; import { createLogger, format, transports } from 'winston'; import type * as Transport from 'winston-transport'; import type { Logger, LogMetadata } from './Logger'; @@ -33,7 +34,7 @@ export class WinstonLoggerFactory implements LoggerFactory { format.timestamp(), format.metadata({ fillExcept: [ 'level', 'timestamp', 'label', 'message' ]}), format.printf( - ({ level: levelInner, message, label: labelInner, timestamp, metadata: meta }: Record): string => + ({ level: levelInner, message, label: labelInner, timestamp, metadata: meta }: TransformableInfo): string => `${timestamp} [${labelInner}] {${this.clusterInfo(meta as LogMetadata)}} ${levelInner}: ${message}`, ), ), diff --git a/src/pods/generate/BaseComponentsJsFactory.ts b/src/pods/generate/BaseComponentsJsFactory.ts index e24dd3d6c..d49ac8e88 100644 --- a/src/pods/generate/BaseComponentsJsFactory.ts +++ b/src/pods/generate/BaseComponentsJsFactory.ts @@ -10,7 +10,7 @@ import type { ComponentsJsFactory } from './ComponentsJsFactory'; * but moduleState will be stored in between calls. */ export class BaseComponentsJsFactory implements ComponentsJsFactory { - private readonly options: IComponentsManagerBuilderOptions; + private readonly options: IComponentsManagerBuilderOptions; public constructor(relativeModulePath = '../../../', logLevel = 'error') { this.options = { @@ -21,7 +21,7 @@ export class BaseComponentsJsFactory implements ComponentsJsFactory { }; } - private async buildManager(): Promise> { + private async buildManager(): Promise> { const manager = await ComponentsManager.build(this.options); this.options.moduleState = manager.moduleState; return manager; @@ -35,7 +35,7 @@ export class BaseComponentsJsFactory implements ComponentsJsFactory { * * @returns The resulting object, corresponding to the given component IRI. */ - public async generate(configPath: string, componentIri: string, variables: Record): + public async generate(configPath: string, componentIri: string, variables: Record): Promise { const manager = await this.buildManager(); await manager.configRegistry.register(configPath); diff --git a/src/pods/generate/ComponentsJsFactory.ts b/src/pods/generate/ComponentsJsFactory.ts index 318d6a258..6ce82bcc4 100644 --- a/src/pods/generate/ComponentsJsFactory.ts +++ b/src/pods/generate/ComponentsJsFactory.ts @@ -10,5 +10,5 @@ export interface ComponentsJsFactory { * * @returns The resulting object, corresponding to the given component IRI. */ - generate: (configPath: string, componentIri: string, variables: Record) => Promise; + generate: (configPath: string, componentIri: string, variables: Record) => Promise; } diff --git a/src/server/middleware/CorsHandler.ts b/src/server/middleware/CorsHandler.ts index 4f7dc1890..fb603f835 100644 --- a/src/server/middleware/CorsHandler.ts +++ b/src/server/middleware/CorsHandler.ts @@ -35,10 +35,10 @@ export class CorsHandler extends HttpHandler { req: CorsRequest, res: { statusCode?: number; - setHeader: (key: string, value: string) => any; - end: () => any; + setHeader: (key: string, value: string) => unknown; + end: () => unknown; }, - next: (err?: any) => any, + next: (err?: unknown) => unknown, ) => void; public constructor(options: SimpleCorsOptions = {}) { diff --git a/src/server/util/BaseRouterHandler.ts b/src/server/util/BaseRouterHandler.ts index 7377707a2..8bcf9a927 100644 --- a/src/server/util/BaseRouterHandler.ts +++ b/src/server/util/BaseRouterHandler.ts @@ -5,7 +5,7 @@ import type { AsyncHandlerInput, AsyncHandlerOutput } from '../../util/handlers/ import { AsyncHandler } from '../../util/handlers/AsyncHandler'; import { trimTrailingSlashes } from '../../util/PathUtil'; -export interface BaseRouterHandlerArgs> { +export interface BaseRouterHandlerArgs> { /** * The base URL of the server. * Not required if no value is provided for `allowedPathNames`. @@ -36,7 +36,7 @@ export interface BaseRouterHandlerArgs> { * * `canHandleInput` expects a ResourceIdentifier to indicate it expects the target to have been validated already. */ -export abstract class BaseRouterHandler> +export abstract class BaseRouterHandler> extends AsyncHandler, AsyncHandlerOutput> { protected readonly baseUrlLength: number; protected readonly handler: T; diff --git a/src/storage/LockingResourceStore.ts b/src/storage/LockingResourceStore.ts index e7ceb8079..562c605c5 100644 --- a/src/storage/LockingResourceStore.ts +++ b/src/storage/LockingResourceStore.ts @@ -154,7 +154,7 @@ export class LockingResourceStore implements AtomicResourceStore { // Spy on the source to maintain the lock upon reading. const data = Object.create(source, { read: { - value(size: number): any { + value(size: number): unknown { maintainLock(); return source.read(size); }, diff --git a/src/storage/accessors/FileDataAccessor.ts b/src/storage/accessors/FileDataAccessor.ts index 8d20f70f2..4545689df 100644 --- a/src/storage/accessors/FileDataAccessor.ts +++ b/src/storage/accessors/FileDataAccessor.ts @@ -355,7 +355,7 @@ export class FileDataAccessor implements DataAccessor { * @param data - The data to be put in the file. */ protected async writeDataFile(path: string, data: Readable): Promise { - return new Promise((resolve, reject): any => { + return new Promise((resolve, reject): void => { const writeStream = createWriteStream(path); data.pipe(writeStream); data.on('error', (error): void => { diff --git a/src/storage/accessors/InMemoryDataAccessor.ts b/src/storage/accessors/InMemoryDataAccessor.ts index 6b0434203..38c47e79a 100644 --- a/src/storage/accessors/InMemoryDataAccessor.ts +++ b/src/storage/accessors/InMemoryDataAccessor.ts @@ -13,7 +13,7 @@ import { isInternalContentType } from '../conversion/ConversionUtil'; import type { DataAccessor } from './DataAccessor'; interface DataEntry { - data: any[]; + data: unknown[]; metadata: RepresentationMetadata; } interface ContainerEntry { diff --git a/src/storage/conversion/DynamicJsonToTemplateConverter.ts b/src/storage/conversion/DynamicJsonToTemplateConverter.ts index c715c8a2a..bef7224cb 100644 --- a/src/storage/conversion/DynamicJsonToTemplateConverter.ts +++ b/src/storage/conversion/DynamicJsonToTemplateConverter.ts @@ -58,7 +58,7 @@ export class DynamicJsonToTemplateConverter extends RepresentationConverter { return representation; } - const contents = JSON.parse(await readableToString(representation.data)) as NodeJS.Dict; + const contents = JSON.parse(await readableToString(representation.data)) as NodeJS.Dict; const rendered = await this.templateEngine.handleSafe({ contents, template: { templateFile: typeMap[type] }}); const metadata = new RepresentationMetadata(representation.metadata, { [CONTENT_TYPE]: type }); diff --git a/src/storage/quota/GlobalQuotaStrategy.ts b/src/storage/quota/GlobalQuotaStrategy.ts index 0800cbb3d..7227edfc2 100644 --- a/src/storage/quota/GlobalQuotaStrategy.ts +++ b/src/storage/quota/GlobalQuotaStrategy.ts @@ -8,7 +8,7 @@ import { QuotaStrategy } from './QuotaStrategy'; export class GlobalQuotaStrategy extends QuotaStrategy { private readonly base: string; - public constructor(limit: Size, reporter: SizeReporter, base: string) { + public constructor(limit: Size, reporter: SizeReporter, base: string) { super(reporter, limit); this.base = base; } diff --git a/src/storage/quota/PodQuotaStrategy.ts b/src/storage/quota/PodQuotaStrategy.ts index df765103d..2300a34d1 100644 --- a/src/storage/quota/PodQuotaStrategy.ts +++ b/src/storage/quota/PodQuotaStrategy.ts @@ -17,7 +17,7 @@ export class PodQuotaStrategy extends QuotaStrategy { public constructor( limit: Size, - reporter: SizeReporter, + reporter: SizeReporter, identifierStrategy: IdentifierStrategy, accessor: DataAccessor, ) { diff --git a/src/storage/quota/QuotaStrategy.ts b/src/storage/quota/QuotaStrategy.ts index 8c5d3568e..07efd6095 100644 --- a/src/storage/quota/QuotaStrategy.ts +++ b/src/storage/quota/QuotaStrategy.ts @@ -18,10 +18,10 @@ import type { SizeReporter } from '../size-reporter/SizeReporter'; * This can be bytes, quads, file count, ... */ export abstract class QuotaStrategy { - public readonly reporter: SizeReporter; + public readonly reporter: SizeReporter; public readonly limit: Size; - public constructor(reporter: SizeReporter, limit: Size) { + protected constructor(reporter: SizeReporter, limit: Size) { this.reporter = reporter; this.limit = limit; } @@ -87,7 +87,7 @@ export abstract class QuotaStrategy { const { reporter } = this; return guardStream(new PassThrough({ - async transform(this, chunk: any, enc: string, done: () => void): Promise { + async transform(this, chunk: unknown, enc: string, done: () => void): Promise { total += await reporter.calculateChunkSize(chunk); const availableSpace = await that.getAvailableSpace(identifier); if (availableSpace.amount < total) { diff --git a/src/util/GenericEventEmitter.ts b/src/util/GenericEventEmitter.ts index d10155f3e..b9a1ab823 100644 --- a/src/util/GenericEventEmitter.ts +++ b/src/util/GenericEventEmitter.ts @@ -9,6 +9,7 @@ import { EventEmitter } from 'node:events'; * Use the {@link createGenericEventEmitterClass} function to generate an event emitter class with the correct typings * in case {@link EventEmitter} needs to be extended. */ +// eslint-disable-next-line ts/no-explicit-any export interface GenericEventEmitter void> extends EventEmitter { addListener: (event: TEvent, listener: TFunc) => this; diff --git a/src/util/IterableUtil.ts b/src/util/IterableUtil.ts index dda2cf40f..79a57ebeb 100644 --- a/src/util/IterableUtil.ts +++ b/src/util/IterableUtil.ts @@ -12,7 +12,7 @@ export function* map( iterable: Iterable, callbackFn: (element: TIn, index: number) => TOut, - thisArg?: any, + thisArg?: unknown, ): Iterable { const boundMapFn = callbackFn.bind(thisArg); let count = 0; @@ -31,8 +31,11 @@ export function* map( * @param callbackFn - Function that is called to test every element. * @param thisArg - Value to use as `this` when executing `callbackFn`. */ -export function* filter(iterable: Iterable, callbackFn: (element: T, index: number) => boolean, thisArg?: any): -Iterable { +export function* filter( + iterable: Iterable, + callbackFn: (element: T, index: number) => boolean, + thisArg?: unknown, +): Iterable { const boundFilterFn = callbackFn.bind(thisArg); let count = 0; for (const value of iterable) { @@ -63,7 +66,7 @@ export function* concat(iterables: Iterable>): Iterable { * @param callbackFn - Function that is called to test every element. * @param thisArg - Value to use as `this` when executing `callbackFn`. */ -export function find(iterable: Iterable, callbackFn: (element: T, index: number) => boolean, thisArg?: any): +export function find(iterable: Iterable, callbackFn: (element: T, index: number) => boolean, thisArg?: unknown): T | undefined { const boundMapFn = callbackFn.bind(thisArg); const count = 0; diff --git a/src/util/Json.ts b/src/util/Json.ts new file mode 100644 index 000000000..fa00da4a4 --- /dev/null +++ b/src/util/Json.ts @@ -0,0 +1,4 @@ +/** + * A JSON object. + */ +export type Json = string | number | boolean | NodeJS.Dict | Json[]; diff --git a/src/util/LockUtils.ts b/src/util/LockUtils.ts index 970f265d9..5df47f554 100644 --- a/src/util/LockUtils.ts +++ b/src/util/LockUtils.ts @@ -12,7 +12,7 @@ const logger = getLoggerFor('LockUtil'); export async function setJitterTimeout(delay: number, jitter = 0): Promise { jitter = Math.max(0, Math.floor(Math.random() * jitter)); delay = Math.max(0, delay + jitter); - return new Promise((resolve): any => setTimeout(resolve, delay)); + return new Promise((resolve): unknown => setTimeout(resolve, delay)); } export interface AttemptSettings { diff --git a/src/util/PathUtil.ts b/src/util/PathUtil.ts index cfc2ee9d1..c9c9e6de1 100644 --- a/src/util/PathUtil.ts +++ b/src/util/PathUtil.ts @@ -6,6 +6,7 @@ import type { ResourceIdentifier } from '../http/representation/ResourceIdentifi import type { HttpRequest } from '../server/HttpRequest'; import { BadRequestHttpError } from './errors/BadRequestHttpError'; import { errorTermsToMetadata } from './errors/HttpErrorUtil'; +import type { Json } from './Json'; /** * Changes a potential Windows path into a POSIX path. @@ -305,8 +306,8 @@ export function resolveAssetPath(path = modulePathPlaceholder): string { /** * Reads the project package.json and returns it. */ -export async function readPackageJson(): Promise> { - return readJson(resolveModulePath('package.json')) as Promise>; +export async function readPackageJson(): Promise> { + return readJson(resolveModulePath('package.json')) as Promise>; } /** diff --git a/src/util/RecordObject.ts b/src/util/RecordObject.ts index 30994ab91..5528ade2e 100644 --- a/src/util/RecordObject.ts +++ b/src/util/RecordObject.ts @@ -2,10 +2,11 @@ * Helper class for instantiating multiple objects with Components.js. * See https://github.com/LinkedSoftwareDependencies/Components.js/issues/26 */ -// eslint-disable-next-line ts/no-extraneous-class -export class RecordObject implements Record { - public constructor(record: Record = {}) { +export class RecordObject implements Record { + public constructor(record: Record = {}) { // eslint-disable-next-line no-constructor-return return record; } + + [key: string]: unknown; } diff --git a/src/util/SliceStream.ts b/src/util/SliceStream.ts index f26b1477a..6f8d17d80 100644 --- a/src/util/SliceStream.ts +++ b/src/util/SliceStream.ts @@ -57,7 +57,7 @@ export class SliceStream extends Transform { } // eslint-disable-next-line ts/naming-convention - public _transform(chunk: any, encoding: BufferEncoding, callback: TransformCallback): void { + public _transform(chunk: unknown, encoding: BufferEncoding, callback: TransformCallback): void { this.source.pause(); if (this.writableObjectMode) { this.objectSlice(chunk); @@ -72,12 +72,12 @@ export class SliceStream extends Transform { protected binarySlice(chunk: Buffer): void { let length = chunk.length; if (this.remainingSkip > 0) { - chunk = chunk.slice(this.remainingSkip); + chunk = chunk.subarray(this.remainingSkip); this.remainingSkip -= length - chunk.length; length = chunk.length; } if (length > 0 && this.remainingSkip <= 0) { - chunk = chunk.slice(0, this.remainingRead); + chunk = chunk.subarray(0, this.remainingRead); this.push(chunk); this.remainingRead -= length; this.checkEnd(); diff --git a/src/util/StreamUtil.ts b/src/util/StreamUtil.ts index c6222f0c2..03524ff0c 100644 --- a/src/util/StreamUtil.ts +++ b/src/util/StreamUtil.ts @@ -10,6 +10,7 @@ import { isHttpRequest } from '../server/HttpRequest'; import { InternalServerError } from './errors/InternalServerError'; import type { Guarded } from './GuardedStream'; import { guardStream } from './GuardedStream'; +import type { Json } from './Json'; import type { PromiseOrValue } from './PromiseUtil'; export const endOfStream = promisify(eos); @@ -45,9 +46,9 @@ export async function readableToQuads(stream: Readable): Promise { * * @returns The parsed object. */ -export async function readJsonStream(stream: Readable): Promise> { +export async function readJsonStream(stream: Readable): Promise { const body = await readableToString(stream); - return JSON.parse(body) as NodeJS.Dict; + return JSON.parse(body) as Json; } /** @@ -119,16 +120,16 @@ export function pipeSafely( return guardStream(destination); } -export interface AsyncTransformOptions extends DuplexOptions { +export interface AsyncTransformOptions extends DuplexOptions { /** * Transforms data from the source by calling the `push` method */ - transform?: (this: Transform, data: T, encoding: string) => PromiseOrValue; + transform?: (this: Transform, data: T, encoding: string) => PromiseOrValue; /** * Performs any final actions after the source has ended */ - flush?: (this: Transform) => PromiseOrValue; + flush?: (this: Transform) => PromiseOrValue; } /** @@ -140,7 +141,7 @@ export interface AsyncTransformOptions extends DuplexOptions { * * @returns The transformed stream */ -export function transformSafely( +export function transformSafely( source: NodeJS.ReadableStream, { transform = function(data): void { @@ -179,6 +180,6 @@ export function transformSafely( * @param contents - Data to stream. * @param options - Options to pass to the Readable constructor. See {@link Readable.from}. */ -export function guardedStreamFrom(contents: string | Iterable, options?: ReadableOptions): Guarded { +export function guardedStreamFrom(contents: string | Iterable, options?: ReadableOptions): Guarded { return guardStream(Readable.from(typeof contents === 'string' ? [ contents ] : contents, options)); } diff --git a/src/util/Vocabularies.ts b/src/util/Vocabularies.ts index 681908a55..594f5b558 100644 --- a/src/util/Vocabularies.ts +++ b/src/util/Vocabularies.ts @@ -14,7 +14,7 @@ type ValueVocabulary = /** * A {@link ValueVocabulary} where the URI values are {@link NamedNode}s. */ -type TermVocabulary = T extends ValueVocabulary ? {[K in keyof T]: NamedNode } : never; +type TermVocabulary = T extends ValueVocabulary ? {[K in keyof T]: NamedNode } : never; /** * Contains a namespace and keys linking to the entries in this namespace. @@ -35,15 +35,15 @@ export type PartialVocabulary = /** * A local name of a {@link Vocabulary}. */ -export type VocabularyLocal = T extends Vocabulary ? TKey : never; +export type VocabularyLocal = T extends Vocabulary ? TKey : never; /** * A URI string entry of a {@link Vocabulary}. */ -export type VocabularyValue = T extends Vocabulary ? T[TKey] : never; +export type VocabularyValue = T extends Vocabulary ? T[TKey] : never; /** * A {@link NamedNode} entry of a {@link Vocabulary}. */ -export type VocabularyTerm = T extends Vocabulary ? T['terms'][TKey] : never; +export type VocabularyTerm = T extends Vocabulary ? T['terms'][TKey] : never; /** * Creates a {@link ValueVocabulary} with the given `baseUri` as namespace and all `localNames` as entries. diff --git a/src/util/errors/HttpError.ts b/src/util/errors/HttpError.ts index aeb9b440f..ed039c105 100644 --- a/src/util/errors/HttpError.ts +++ b/src/util/errors/HttpError.ts @@ -44,7 +44,7 @@ export class HttpError extends Error implements HttpE this.generateMetadata(); } - public static isInstance(error: any): error is HttpError { + public static isInstance(error: unknown): error is HttpError { return isError(error) && typeof (error as HttpError).statusCode === 'number' && Boolean((error as HttpError).metadata); @@ -77,7 +77,7 @@ export interface HttpErrorClass { /** * Checks if the given error is an instance of this class. */ - readonly isInstance: (error: any) => error is HttpError; + readonly isInstance: (error: unknown) => error is HttpError; } /** @@ -99,7 +99,7 @@ export function generateHttpErrorClass(statusCode: TCode, super(statusCode, name, message, options); } - public static isInstance(error: any): error is SpecificHttpError { + public static isInstance(error: unknown): error is SpecificHttpError { return HttpError.isInstance(error) && error.statusCode === statusCode; } }; diff --git a/src/util/errors/RedirectHttpError.ts b/src/util/errors/RedirectHttpError.ts index 622e12ca0..64847d400 100644 --- a/src/util/errors/RedirectHttpError.ts +++ b/src/util/errors/RedirectHttpError.ts @@ -16,7 +16,7 @@ export class RedirectHttpError extends HttpError< this.metadata.add(SOLID_HTTP.terms.location, DataFactory.namedNode(location)); } - public static isInstance(error: any): error is RedirectHttpError { + public static isInstance(error: unknown): error is RedirectHttpError { return HttpError.isInstance(error) && typeof (error as RedirectHttpError).location === 'string'; } } @@ -46,7 +46,7 @@ export function generateRedirectHttpErrorClass( super(code, name, location, message, options); } - public static isInstance(error: any): error is SpecificRedirectHttpError { + public static isInstance(error: unknown): error is SpecificRedirectHttpError { return RedirectHttpError.isInstance(error) && error.statusCode === code; } }; diff --git a/src/util/errors/SystemError.ts b/src/util/errors/SystemError.ts index 45604b201..44a9da1c2 100644 --- a/src/util/errors/SystemError.ts +++ b/src/util/errors/SystemError.ts @@ -26,7 +26,7 @@ export interface SystemError extends Error { /** * If present, extra details about the error condition. */ - info?: any; + info?: unknown; /** * If present, the file path when reporting a file system error. */ diff --git a/src/util/handlers/ArrayUnionHandler.ts b/src/util/handlers/ArrayUnionHandler.ts index 243b9b377..b3e4e1170 100644 --- a/src/util/handlers/ArrayUnionHandler.ts +++ b/src/util/handlers/ArrayUnionHandler.ts @@ -4,7 +4,7 @@ import { UnionHandler } from './UnionHandler'; /** * A utility handler that concatenates the results of all its handlers into a single result. */ -export class ArrayUnionHandler> extends UnionHandler { +export class ArrayUnionHandler> extends UnionHandler { public constructor(handlers: T[], requireAll?: boolean, ignoreErrors?: boolean) { super(handlers, requireAll, ignoreErrors); } diff --git a/src/util/handlers/AsyncHandler.ts b/src/util/handlers/AsyncHandler.ts index e0edf3a89..a454d2ab9 100644 --- a/src/util/handlers/AsyncHandler.ts +++ b/src/util/handlers/AsyncHandler.ts @@ -1,6 +1,6 @@ type Awaited = T extends PromiseLike ? U : T; -export type AsyncHandlerInput> = Parameters[0]; -export type AsyncHandlerOutput> = Awaited>; +export type AsyncHandlerInput> = Parameters[0]; +export type AsyncHandlerOutput> = Awaited>; /** * Simple interface for classes that can potentially handle a specific kind of data asynchronously. diff --git a/src/util/handlers/CachedHandler.ts b/src/util/handlers/CachedHandler.ts index 1b4a59b73..0f916a7be 100644 --- a/src/util/handlers/CachedHandler.ts +++ b/src/util/handlers/CachedHandler.ts @@ -12,7 +12,7 @@ type NestedMap = TOut | WeakMap>; * This also means that the cache key needs to be an object. * Errors will be thrown in case a primitive is used. */ -export class CachedHandler, TOut = void> extends AsyncHandler { +export class CachedHandler, TOut = void> extends AsyncHandler { private readonly source: AsyncHandler; private readonly fields?: [keyof TIn, ...(keyof TIn)[]]; diff --git a/src/util/handlers/StaticHandler.ts b/src/util/handlers/StaticHandler.ts index 6c2cd98ab..5c49ca1aa 100644 --- a/src/util/handlers/StaticHandler.ts +++ b/src/util/handlers/StaticHandler.ts @@ -7,7 +7,7 @@ import { AsyncHandler } from './AsyncHandler'; * The generic type extends `any` due to Components.js requirements. */ // eslint-disable-next-line ts/no-unnecessary-type-constraint -export class StaticHandler extends AsyncHandler { +export class StaticHandler extends AsyncHandler { private readonly value?: T; public constructor(value?: T) { diff --git a/src/util/handlers/StaticThrowHandler.ts b/src/util/handlers/StaticThrowHandler.ts index 4df8a3f1d..1928f61d8 100644 --- a/src/util/handlers/StaticThrowHandler.ts +++ b/src/util/handlers/StaticThrowHandler.ts @@ -4,7 +4,7 @@ import { AsyncHandler } from './AsyncHandler'; /** * Utility handler that can handle all input and always throws the given error. */ -export class StaticThrowHandler extends AsyncHandler { +export class StaticThrowHandler extends AsyncHandler { private readonly error: HttpError; public constructor(error: HttpError) { diff --git a/src/util/handlers/UnionHandler.ts b/src/util/handlers/UnionHandler.ts index 239ddd839..c508a393f 100644 --- a/src/util/handlers/UnionHandler.ts +++ b/src/util/handlers/UnionHandler.ts @@ -8,7 +8,7 @@ import { filterHandlers, findHandler } from './HandlerUtil'; * Will run the handlers and then call the abstract `combine` function with the results, * which then generates the handler's output. */ -export abstract class UnionHandler> extends +export abstract class UnionHandler> extends AsyncHandler, AsyncHandlerOutput> { protected readonly handlers: T[]; private readonly requireAll: boolean; diff --git a/src/util/handlers/UnsupportedAsyncHandler.ts b/src/util/handlers/UnsupportedAsyncHandler.ts index 7099ea5d8..230f898eb 100644 --- a/src/util/handlers/UnsupportedAsyncHandler.ts +++ b/src/util/handlers/UnsupportedAsyncHandler.ts @@ -4,7 +4,7 @@ import { AsyncHandler } from './AsyncHandler'; /** * Handler that does not support any input and will always throw an error. */ -export class UnsupportedAsyncHandler extends AsyncHandler { +export class UnsupportedAsyncHandler extends AsyncHandler { private readonly errorMessage?: string; public constructor(errorMessage?: string) { diff --git a/src/util/map/HashMap.ts b/src/util/map/HashMap.ts index 3bddcd44c..1d4194eec 100644 --- a/src/util/map/HashMap.ts +++ b/src/util/map/HashMap.ts @@ -6,7 +6,7 @@ type Entry = { key: TKey; value: TVal }; * A {@link Map} implementation that maps the Key object to a string using the provided hash function. * This ensures that equal objects that are not the same instance are mapped to the same value. */ -export class HashMap implements Map { +export class HashMap implements Map { private readonly hashMap: Map>; private readonly hashFn: (key: TKey) => string; @@ -64,7 +64,7 @@ export class HashMap implements Map { } } - public forEach(callbackfn: (value: TVal, key: TKey, map: Map) => void, thisArg?: any): void { + public forEach(callbackfn: (value: TVal, key: TKey, map: Map) => void, thisArg?: unknown): void { for (const [ key, value ] of this) { callbackfn.bind(thisArg)(value, key, this); } diff --git a/src/util/map/MapUtil.ts b/src/util/map/MapUtil.ts index c24726ee0..c18400c37 100644 --- a/src/util/map/MapUtil.ts +++ b/src/util/map/MapUtil.ts @@ -2,22 +2,22 @@ import { resolvePromiseOrValue } from '../PromiseUtil'; import type { PromiseOrValue } from '../PromiseUtil'; import type { SetMultiMap } from './SetMultiMap'; -export type ArrayElement = TArray[number]; +export type ArrayElement = TArray[number]; export type EmptyObject = Record; -export type MapKey = T extends Map ? TKey : never; -export type MapValue = T extends Map ? TValue : never; -export type MapEntry = T extends Map ? [MapKey, MapValue] : never; +export type MapKey = T extends Map ? TKey : never; +export type MapValue = T extends Map ? TValue : never; +export type MapEntry = T extends Map ? [MapKey, MapValue] : never; /** * A simplified version of {@link MapConstructor} that only allows creating an empty {@link Map}. */ -export type EmptyMapConstructor = new() => Map; +export type EmptyMapConstructor = new() => Map; /** * Options describing the necessary changes when calling {@link modify}. */ -export type ModifyOptions> = { +export type ModifyOptions> = { /** * Entries that need to be added to the Map. */ @@ -35,6 +35,7 @@ export type ModifyOptions> = { * @param map - Map to start from. * @param options - {@link ModifyOptions} describing the necessary changes. */ +// eslint-disable-next-line ts/no-explicit-any export function modify>(map: T, options: ModifyOptions): T { for (const key of options.remove ?? []) { map.delete(key); diff --git a/src/util/map/SetMultiMap.ts b/src/util/map/SetMultiMap.ts index a0a15f30e..8b9a2b668 100644 --- a/src/util/map/SetMultiMap.ts +++ b/src/util/map/SetMultiMap.ts @@ -55,5 +55,5 @@ export interface SetMultiMap extends Map) => void, thisArg?: any) => void; + forEach: (callbackfn: (value: TVal, key: TKey, map: SetMultiMap) => void, thisArg?: unknown) => void; } diff --git a/src/util/map/WrappedSetMultiMap.ts b/src/util/map/WrappedSetMultiMap.ts index 55d6d6ace..8636b8478 100644 --- a/src/util/map/WrappedSetMultiMap.ts +++ b/src/util/map/WrappedSetMultiMap.ts @@ -138,7 +138,7 @@ export class WrappedSetMultiMap implements SetMultiMap { return this.map.values(); } - public forEach(callbackfn: (value: TVal, key: TKey, map: SetMultiMap) => void, thisArg?: any): void { + public forEach(callbackfn: (value: TVal, key: TKey, map: SetMultiMap) => void, thisArg?: unknown): void { for (const [ key, value ] of this) { callbackfn.bind(thisArg)(value, key, this); } diff --git a/src/util/templates/ChainedTemplateEngine.ts b/src/util/templates/ChainedTemplateEngine.ts index 3e20faec1..71dc43c57 100644 --- a/src/util/templates/ChainedTemplateEngine.ts +++ b/src/util/templates/ChainedTemplateEngine.ts @@ -10,7 +10,7 @@ import Dict = NodeJS.Dict; * All subsequent engines will be called with no template parameter. * Contents will still be passed along and another entry will be added for the body of the previous output. */ -export class ChainedTemplateEngine = Dict> extends TemplateEngine { +export class ChainedTemplateEngine = Dict> extends TemplateEngine { private readonly firstEngine: TemplateEngine; private readonly chainedEngines: TemplateEngine[]; private readonly renderedName: string; diff --git a/src/util/templates/EjsTemplateEngine.ts b/src/util/templates/EjsTemplateEngine.ts index 3c86e8566..73866cc6f 100644 --- a/src/util/templates/EjsTemplateEngine.ts +++ b/src/util/templates/EjsTemplateEngine.ts @@ -7,7 +7,7 @@ import Dict = NodeJS.Dict; /** * Fills in EJS templates. */ -export class EjsTemplateEngine = Dict> extends ExtensionBasedTemplateEngine { +export class EjsTemplateEngine = Dict> extends ExtensionBasedTemplateEngine { private readonly baseUrl: string; /** diff --git a/src/util/templates/ExtensionBasedTemplateEngine.ts b/src/util/templates/ExtensionBasedTemplateEngine.ts index 94ed5d1fb..8aab8e121 100644 --- a/src/util/templates/ExtensionBasedTemplateEngine.ts +++ b/src/util/templates/ExtensionBasedTemplateEngine.ts @@ -8,7 +8,7 @@ import Dict = NodeJS.Dict; /** * Parent class for template engines that accept handling based on whether the template extension is supported. */ -export abstract class ExtensionBasedTemplateEngine = Dict> extends TemplateEngine { +export abstract class ExtensionBasedTemplateEngine = Dict> extends TemplateEngine { protected readonly supportedExtensions: string[]; /** diff --git a/src/util/templates/HandlebarsTemplateEngine.ts b/src/util/templates/HandlebarsTemplateEngine.ts index c4f4992ab..f62e0dd79 100644 --- a/src/util/templates/HandlebarsTemplateEngine.ts +++ b/src/util/templates/HandlebarsTemplateEngine.ts @@ -7,7 +7,7 @@ import Dict = NodeJS.Dict; /** * Fills in Handlebars templates. */ -export class HandlebarsTemplateEngine = Dict> extends ExtensionBasedTemplateEngine { +export class HandlebarsTemplateEngine = Dict> extends ExtensionBasedTemplateEngine { private readonly baseUrl: string; /** diff --git a/src/util/templates/StaticTemplateEngine.ts b/src/util/templates/StaticTemplateEngine.ts index b1191c620..3a3bc4913 100644 --- a/src/util/templates/StaticTemplateEngine.ts +++ b/src/util/templates/StaticTemplateEngine.ts @@ -6,7 +6,7 @@ import Dict = NodeJS.Dict; /** * Template engine that renders output based on a static template file. */ -export class StaticTemplateEngine = Dict> extends TemplateEngine { +export class StaticTemplateEngine = Dict> extends TemplateEngine { private readonly template: Template; private readonly templateEngine: AsyncHandler, string>; diff --git a/src/util/templates/TemplateEngine.ts b/src/util/templates/TemplateEngine.ts index 3b51af096..4e5100912 100644 --- a/src/util/templates/TemplateEngine.ts +++ b/src/util/templates/TemplateEngine.ts @@ -31,5 +31,5 @@ export interface TemplateEngineInput { * Generic interface for classes that implement a template engine. * A template engine renders content into a template. */ -export abstract class TemplateEngine = Dict> +export abstract class TemplateEngine = Dict> extends AsyncHandler, string> {} From 45640a36d64a5f103cb985091cfd03956a4451a1 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Wed, 13 Mar 2024 16:01:21 +0100 Subject: [PATCH 26/71] refactor: Enable import/no-extraneous-dependencies rule --- eslint/general.js | 1 + 1 file changed, 1 insertion(+) diff --git a/eslint/general.js b/eslint/general.js index b274a15a4..40e715e91 100644 --- a/eslint/general.js +++ b/eslint/general.js @@ -49,6 +49,7 @@ module.exports = { ], 'import/extensions': 'error', + 'import/no-extraneous-dependencies': 'error', 'jsdoc/no-multi-asterisks': [ 'error', { allowWhitespace: true }], From 5fc4ce8f7308fa65ddda2b8af46ccfc038142c9a Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Wed, 13 Mar 2024 16:14:59 +0100 Subject: [PATCH 27/71] refactor: Enable jsdoc/no-types rule --- eslint/general.js | 1 + src/util/HeaderUtil.ts | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/eslint/general.js b/eslint/general.js index 40e715e91..099e57121 100644 --- a/eslint/general.js +++ b/eslint/general.js @@ -52,6 +52,7 @@ module.exports = { 'import/no-extraneous-dependencies': 'error', 'jsdoc/no-multi-asterisks': [ 'error', { allowWhitespace: true }], + 'jsdoc/no-types': 'error', 'node/prefer-global/buffer': [ 'error', 'always' ], 'node/prefer-global/console': [ 'error', 'always' ], diff --git a/src/util/HeaderUtil.ts b/src/util/HeaderUtil.ts index 18a26dbaa..91df306f6 100644 --- a/src/util/HeaderUtil.ts +++ b/src/util/HeaderUtil.ts @@ -134,7 +134,6 @@ export function parseParameters(parameters: string[], replacements: Record, strict: boolean): Accept | undefined { From 3e59aa4b55905831e397de09e95a6610a98bdb5d Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Wed, 13 Mar 2024 16:50:02 +0100 Subject: [PATCH 28/71] refactor: Enable jsdoc/valid-types rule --- eslint/general.js | 1 + src/storage/mapping/BaseFileIdentifierMapper.ts | 4 ++-- src/util/HeaderUtil.ts | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/eslint/general.js b/eslint/general.js index 099e57121..5e39dab2e 100644 --- a/eslint/general.js +++ b/eslint/general.js @@ -53,6 +53,7 @@ module.exports = { 'jsdoc/no-multi-asterisks': [ 'error', { allowWhitespace: true }], 'jsdoc/no-types': 'error', + 'jsdoc/valid-types': 'error', 'node/prefer-global/buffer': [ 'error', 'always' ], 'node/prefer-global/console': [ 'error', 'always' ], diff --git a/src/storage/mapping/BaseFileIdentifierMapper.ts b/src/storage/mapping/BaseFileIdentifierMapper.ts index 5f533b8a5..a5440afec 100644 --- a/src/storage/mapping/BaseFileIdentifierMapper.ts +++ b/src/storage/mapping/BaseFileIdentifierMapper.ts @@ -177,7 +177,7 @@ export class BaseFileIdentifierMapper implements FileIdentifierMapper { * Strips the baseRequestURI from the identifier. * @param identifier - Incoming identifier. * - * @throws {@link NotFoundHttpError} + * @throws NotFoundHttpError * If the identifier does not match the baseRequestURI. * * @returns A string representing the relative path. @@ -193,7 +193,7 @@ export class BaseFileIdentifierMapper implements FileIdentifierMapper { /** * Check if the given relative path is valid. * - * @throws {@link BadRequestHttpError} + * @throws BadRequestHttpError * If the relative path is invalid. * * @param path - A relative path, as generated by {@link getRelativePath}. diff --git a/src/util/HeaderUtil.ts b/src/util/HeaderUtil.ts index 91df306f6..5c9ea8ffd 100644 --- a/src/util/HeaderUtil.ts +++ b/src/util/HeaderUtil.ts @@ -31,7 +31,7 @@ const logger = getLoggerFor('HeaderUtil'); * Replaces all double quoted strings in the input string with `"0"`, `"1"`, etc. * @param input - The Accept header string. * - * @throws {@link BadRequestHttpError} + * @throws BadRequestHttpError * Thrown if invalid characters are detected in a quoted string. * * @returns The transformed string and a map with keys `"0"`, etc. and values the original string that was there. @@ -371,7 +371,7 @@ export function addHeader(response: HttpResponse, name: string, value: string | * * @param input - The Content-Type header string. * - * @throws {@link BadRequestHttpError} + * @throws BadRequestHttpError * Thrown on invalid header syntax. * * @returns A {@link ContentType} object containing the value and optional parameters. From 65bf2bd34e9c26edabe4803caac7ff1466e4ea95 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Thu, 14 Mar 2024 09:29:56 +0100 Subject: [PATCH 29/71] refactor: Enable jsdoc/tag-lines and jsdoc/sort-tags rules --- eslint/general.js | 8 ++++++++ scripts/finalizeRelease.ts | 2 ++ scripts/formatChangelog.ts | 4 ++++ scripts/upgradeConfig.ts | 3 +++ src/authorization/AcpReader.ts | 1 + src/authorization/AcpUtil.ts | 5 +++++ .../PermissionBasedAuthorizer.ts | 3 +++ src/authorization/WebAclReader.ts | 2 ++ .../access/AgentGroupAccessChecker.ts | 1 + .../IntermediateCreateExtractor.ts | 1 + .../permissions/MethodModesExtractor.ts | 1 + .../permissions/N3PatchModesExtractor.ts | 1 + .../permissions/SparqlUpdateModesExtractor.ts | 1 + .../auxiliary/AuxiliaryIdentifierStrategy.ts | 2 ++ src/http/auxiliary/AuxiliaryStrategy.ts | 3 +++ src/http/input/metadata/LinkRelParser.ts | 3 +++ .../representation/RepresentationMetadata.ts | 12 +++++++++-- src/identity/interaction/InteractionUtil.ts | 2 ++ .../interaction/account/util/AccountStore.ts | 2 ++ .../interaction/account/util/CookieStore.ts | 4 ++++ .../interaction/login/ResolveLoginHandler.ts | 2 ++ .../password/util/ForgotPasswordStore.ts | 5 +++++ .../storage/ClientIdAdapterFactory.ts | 1 + src/init/AppRunner.ts | 1 + src/init/ConfigPodInitializer.ts | 1 + src/init/cluster/ClusterManager.ts | 5 +++++ src/init/cluster/SingleThreaded.ts | 3 +++ src/logging/LogUtil.ts | 1 + src/logging/Logger.ts | 8 ++++++++ src/logging/LoggerFactory.ts | 1 + src/pods/PodManager.ts | 1 + src/pods/generate/BaseComponentsJsFactory.ts | 1 + src/pods/generate/ComponentsJsFactory.ts | 1 + src/pods/generate/GenerateUtil.ts | 1 + src/pods/generate/ResourcesGenerator.ts | 1 + .../generate/TemplatedResourcesGenerator.ts | 1 + src/server/middleware/StaticAssetHandler.ts | 1 + .../NotificationChannelStorage.ts | 5 +++++ .../notifications/NotificationChannelType.ts | 4 ++++ .../WebSocketChannel2023/WebSocket2023Util.ts | 1 + src/server/util/RedirectingHttpHandler.ts | 1 + src/storage/DataAccessorBasedStore.ts | 9 +++++++++ src/storage/ResourceSet.ts | 1 + src/storage/ResourceStore.ts | 5 +++++ src/storage/accessors/DataAccessor.ts | 5 +++++ src/storage/accessors/FileDataAccessor.ts | 5 +++++ src/storage/accessors/SparqlDataAccessor.ts | 9 +++++++++ src/storage/conditions/Conditions.ts | 1 + src/storage/conditions/ETagHandler.ts | 1 + src/storage/conversion/ConversionUtil.ts | 2 ++ src/storage/keyvalue/JsonFileStorage.ts | 1 + src/storage/keyvalue/KeyValueStorage.ts | 4 ++++ .../mapping/BaseFileIdentifierMapper.ts | 20 ++++++++++++++----- src/storage/mapping/FileIdentifierMapper.ts | 2 ++ src/storage/quota/QuotaStrategy.ts | 4 ++++ src/storage/routing/BaseUrlRouterRule.ts | 1 + src/storage/size-reporter/FileSizeReporter.ts | 1 + src/storage/size-reporter/SizeReporter.ts | 3 +++ src/util/Header.ts | 1 + src/util/HeaderUtil.ts | 13 ++++++++---- src/util/IterableUtil.ts | 1 + src/util/LockUtils.ts | 6 ++++-- src/util/PathUtil.ts | 19 +++++++++++++----- src/util/PromiseUtil.ts | 1 + src/util/QuadUtil.ts | 3 +++ src/util/ResourceUtil.ts | 4 ++++ src/util/StreamUtil.ts | 7 +++++++ src/util/StringUtil.ts | 4 ++++ src/util/TermUtil.ts | 3 +++ src/util/Vocabularies.ts | 1 + src/util/errors/BadRequestHttpError.ts | 1 + src/util/errors/HttpError.ts | 1 + src/util/errors/PayloadHttpError.ts | 1 + src/util/errors/RangeNotSatisfiedHttpError.ts | 1 + src/util/handlers/AsyncHandler.ts | 3 +++ src/util/handlers/BooleanHandler.ts | 1 + src/util/handlers/ProcessHandler.ts | 1 + src/util/handlers/WaterfallHandler.ts | 4 ++++ src/util/locking/BaseReadWriteLocker.ts | 1 + src/util/locking/EqualReadWriteLocker.ts | 1 + src/util/locking/FileSystemResourceLocker.ts | 7 +++++++ src/util/locking/RedisLocker.ts | 7 +++++++ src/util/locking/ResourceLocker.ts | 2 ++ src/util/locking/scripts/RedisLuaScripts.ts | 6 ++++++ templates/scripts/util.js | 5 +++++ test/deploy/createAccountCredentials.ts | 4 ++++ test/integration/IdentityTestState.ts | 1 + test/util/AccountUtil.ts | 1 + test/util/NotificationUtil.ts | 2 ++ 89 files changed, 276 insertions(+), 18 deletions(-) diff --git a/eslint/general.js b/eslint/general.js index 5e39dab2e..182f806ec 100644 --- a/eslint/general.js +++ b/eslint/general.js @@ -51,8 +51,16 @@ module.exports = { 'import/extensions': 'error', 'import/no-extraneous-dependencies': 'error', + 'jsdoc/tag-lines': [ 'error', 'any', { startLines: 1 }], 'jsdoc/no-multi-asterisks': [ 'error', { allowWhitespace: true }], 'jsdoc/no-types': 'error', + 'jsdoc/sort-tags': [ 'error', { + tagSequence: [ + { tags: [ 'param' ]}, + { tags: [ 'returns' ]}, + { tags: [ 'throws' ]}, + ], + }], 'jsdoc/valid-types': 'error', 'node/prefer-global/buffer': [ 'error', 'always' ], diff --git a/scripts/finalizeRelease.ts b/scripts/finalizeRelease.ts index d3584b3ab..5826f093b 100644 --- a/scripts/finalizeRelease.ts +++ b/scripts/finalizeRelease.ts @@ -27,7 +27,9 @@ async function commitAndTag(): Promise { /** * Prompts the user for input + * * @param query - A string to prompt the user + * * @returns Promise with the input of the user */ async function waitForUserInput(query: string): Promise { diff --git a/scripts/formatChangelog.ts b/scripts/formatChangelog.ts index d95b45d55..266d6b664 100644 --- a/scripts/formatChangelog.ts +++ b/scripts/formatChangelog.ts @@ -14,7 +14,9 @@ import { readFile, writeFile } from 'fs-extra'; /** * Capitalize all list entries + * * @param input - String to search/replace + * * @returns Promise with output string */ async function capitalizeListEntries(input: string): Promise { @@ -31,7 +33,9 @@ function endProcess(error: Error): never { /** * Main function for changelog formatting + * * @param filePath - Path to the changelog file + * * @returns Promise */ async function formatChangelog(filePath: string): Promise { diff --git a/scripts/upgradeConfig.ts b/scripts/upgradeConfig.ts index 6ed86b6f5..94c2ab68a 100644 --- a/scripts/upgradeConfig.ts +++ b/scripts/upgradeConfig.ts @@ -18,6 +18,7 @@ import { joinFilePath, readPackageJson } from '../src/util/PathUtil'; /** * Search and replace the version of a component with given name + * * @param filePath - File to search/replace * @param regex - RegExp matching the component reference * @param version - Semantic version to change to @@ -31,8 +32,10 @@ async function replaceComponentVersion(filePath: string, regex: RegExp, version: /** * Recursive search for files that match a given Regex + * * @param path - Path of folder to start search in * @param regex - A regular expression to which file names will be matched + * * @returns Promise with all file pathss */ async function getFilePaths(path: string, regex: RegExp): Promise { diff --git a/src/authorization/AcpReader.ts b/src/authorization/AcpReader.ts index bc7ca9dcf..80b4d3f6e 100644 --- a/src/authorization/AcpReader.ts +++ b/src/authorization/AcpReader.ts @@ -65,6 +65,7 @@ export class AcpReader extends PermissionReader { /** * Generates the allowed permissions. + * * @param target - Target to generate permissions for. * @param credentials - Credentials that are trying to access the resource. * @param resourceCache - Cache used to store ACR data. diff --git a/src/authorization/AcpUtil.ts b/src/authorization/AcpUtil.ts index 8883c0cbf..41c8f8fc2 100644 --- a/src/authorization/AcpUtil.ts +++ b/src/authorization/AcpUtil.ts @@ -27,6 +27,7 @@ function getObjectValues(data: Store, subject: Term, predicate: NamedNode): stri /** * Finds the {@link IMatcher} with the given identifier in the given dataset. + * * @param data - Dataset to look in. * @param matcher - Identifier of the matcher. */ @@ -42,6 +43,7 @@ export function getMatcher(data: Store, matcher: Term): IMatcher { /** * Finds the {@link IPolicy} with the given identifier in the given dataset. + * * @param data - Dataset to look in. * @param policy - Identifier of the policy. */ @@ -58,6 +60,7 @@ export function getPolicy(data: Store, policy: Term): IPolicy { /** * Finds the {@link IAccessControl} with the given identifier in the given dataset. + * * @param data - Dataset to look in. * @param accessControl - Identifier of the access control. */ @@ -71,6 +74,7 @@ export function getAccessControl(data: Store, accessControl: Term): IAccessContr /** * Finds the {@link IAccessControlResource} with the given identifier in the given dataset. + * * @param data - Dataset to look in. * @param acr - Identifier of the access control resource. */ @@ -88,6 +92,7 @@ export function getAccessControlResource(data: Store, acr: Term): IAccessControl /** * Finds all {@link IAccessControlledResource} in the given dataset. + * * @param data - Dataset to look in. */ export function* getAccessControlledResources(data: Store): Iterable { diff --git a/src/authorization/PermissionBasedAuthorizer.ts b/src/authorization/PermissionBasedAuthorizer.ts index a48c9d305..ffcdc5b92 100644 --- a/src/authorization/PermissionBasedAuthorizer.ts +++ b/src/authorization/PermissionBasedAuthorizer.ts @@ -24,6 +24,7 @@ export class PermissionBasedAuthorizer extends Authorizer { /** * The existence of the target resource determines the output status code for certain situations. * The provided {@link ResourceSet} will be used for that. + * * @param resourceSet - {@link ResourceSet} that can verify the target resource existence. */ public constructor(resourceSet: ResourceSet) { @@ -77,6 +78,7 @@ export class PermissionBasedAuthorizer extends Authorizer { * Ensures that at least one of the credentials provides permissions for the given mode. * Throws a {@link ForbiddenHttpError} or {@link UnauthorizedHttpError} depending on the credentials * if access is not allowed. + * * @param credentials - Credentials that require access. * @param permissionSet - PermissionSet describing the available permissions of the credentials. * @param mode - Which mode is requested. @@ -98,6 +100,7 @@ export class PermissionBasedAuthorizer extends Authorizer { /** * Checks whether the agent is authenticated (logged in) or not (public/anonymous). + * * @param credentials - Credentials to check. */ private isAuthenticated(credentials: Credentials): boolean { diff --git a/src/authorization/WebAclReader.ts b/src/authorization/WebAclReader.ts index 1d83110ed..8087da2cc 100644 --- a/src/authorization/WebAclReader.ts +++ b/src/authorization/WebAclReader.ts @@ -96,6 +96,7 @@ export class WebAclReader extends PermissionReader { /** * Determines the available permissions for the given credentials. + * * @param acl - Store containing all relevant authorization triples. * @param credentials - Credentials to find the permissions for. */ @@ -223,6 +224,7 @@ export class WebAclReader extends PermissionReader { /** * Extracts all rules from the store that are relevant for the given target, * based on either the `acl:accessTo` or `acl:default` predicates. + * * @param store - Store to filter. * @param target - The identifier of which the acl rules need to be known. * @param directAcl - If the store contains triples from the direct acl resource of the target or not. diff --git a/src/authorization/access/AgentGroupAccessChecker.ts b/src/authorization/access/AgentGroupAccessChecker.ts index 957956bde..a65020292 100644 --- a/src/authorization/access/AgentGroupAccessChecker.ts +++ b/src/authorization/access/AgentGroupAccessChecker.ts @@ -29,6 +29,7 @@ export class AgentGroupAccessChecker extends AccessChecker { /** * Checks if the given agent is member of a given vCard group. + * * @param webId - WebID of the agent that needs access. * @param group - URL of the vCard group that needs to be checked. * diff --git a/src/authorization/permissions/IntermediateCreateExtractor.ts b/src/authorization/permissions/IntermediateCreateExtractor.ts index 646fa229a..36292033a 100644 --- a/src/authorization/permissions/IntermediateCreateExtractor.ts +++ b/src/authorization/permissions/IntermediateCreateExtractor.ts @@ -19,6 +19,7 @@ export class IntermediateCreateExtractor extends ModesExtractor { /** * Certain permissions depend on the existence of the target resource. * The provided {@link ResourceSet} will be used for that. + * * @param resourceSet - {@link ResourceSet} that can verify the target resource existence. * @param strategy - {@link IdentifierStrategy} that will be used to determine parent containers. * @param source - The source {@link ModesExtractor}. diff --git a/src/authorization/permissions/MethodModesExtractor.ts b/src/authorization/permissions/MethodModesExtractor.ts index 5a581ca14..6744e90d8 100644 --- a/src/authorization/permissions/MethodModesExtractor.ts +++ b/src/authorization/permissions/MethodModesExtractor.ts @@ -20,6 +20,7 @@ export class MethodModesExtractor extends ModesExtractor { /** * Certain permissions depend on the existence of the target resource. * The provided {@link ResourceSet} will be used for that. + * * @param resourceSet - {@link ResourceSet} that can verify the target resource existence. */ public constructor(resourceSet: ResourceSet) { diff --git a/src/authorization/permissions/N3PatchModesExtractor.ts b/src/authorization/permissions/N3PatchModesExtractor.ts index 8f7bb2ca9..dc217d3db 100644 --- a/src/authorization/permissions/N3PatchModesExtractor.ts +++ b/src/authorization/permissions/N3PatchModesExtractor.ts @@ -22,6 +22,7 @@ export class N3PatchModesExtractor extends ModesExtractor { /** * Certain permissions depend on the existence of the target resource. * The provided {@link ResourceSet} will be used for that. + * * @param resourceSet - {@link ResourceSet} that can verify the target resource existence. */ public constructor(resourceSet: ResourceSet) { diff --git a/src/authorization/permissions/SparqlUpdateModesExtractor.ts b/src/authorization/permissions/SparqlUpdateModesExtractor.ts index 56d789dc7..a26259557 100644 --- a/src/authorization/permissions/SparqlUpdateModesExtractor.ts +++ b/src/authorization/permissions/SparqlUpdateModesExtractor.ts @@ -20,6 +20,7 @@ export class SparqlUpdateModesExtractor extends ModesExtractor { /** * Certain permissions depend on the existence of the target resource. * The provided {@link ResourceSet} will be used for that. + * * @param resourceSet - {@link ResourceSet} that can verify the target resource existence. */ public constructor(resourceSet: ResourceSet) { diff --git a/src/http/auxiliary/AuxiliaryIdentifierStrategy.ts b/src/http/auxiliary/AuxiliaryIdentifierStrategy.ts index 0c2c2b99f..362ea5af3 100644 --- a/src/http/auxiliary/AuxiliaryIdentifierStrategy.ts +++ b/src/http/auxiliary/AuxiliaryIdentifierStrategy.ts @@ -31,6 +31,7 @@ export interface AuxiliaryIdentifierStrategy { * Checks if the input identifier corresponds to an auxiliary resource. * This does not check if that auxiliary resource exists, * only if the identifier indicates that there could be an auxiliary resource there. + * * @param identifier - Identifier to check. * * @returns true if the input identifier points to an auxiliary resource. @@ -40,6 +41,7 @@ export interface AuxiliaryIdentifierStrategy { /** * Returns the identifier of the resource which this auxiliary resource is referring to. * This does not guarantee that this resource exists. + * * @param identifier - Identifier of the auxiliary resource. * * @returns The ResourceIdentifier of the subject resource. diff --git a/src/http/auxiliary/AuxiliaryStrategy.ts b/src/http/auxiliary/AuxiliaryStrategy.ts index d660ca50e..d4f972a48 100644 --- a/src/http/auxiliary/AuxiliaryStrategy.ts +++ b/src/http/auxiliary/AuxiliaryStrategy.ts @@ -11,6 +11,7 @@ import type { AuxiliaryIdentifierStrategy } from './AuxiliaryIdentifierStrategy' export interface AuxiliaryStrategy extends AuxiliaryIdentifierStrategy { /** * Whether this auxiliary resources uses its own authorization instead of the subject resource authorization. + * * @param identifier - Identifier of the auxiliary resource. */ usesOwnAuthorization: (identifier: ResourceIdentifier) => boolean; @@ -18,6 +19,7 @@ export interface AuxiliaryStrategy extends AuxiliaryIdentifierStrategy { /** * Whether the root storage container requires this auxiliary resource to be present. * If yes, this means they can't be deleted individually from such a container. + * * @param identifier - Identifier of the auxiliary resource. */ isRequiredInRoot: (identifier: ResourceIdentifier) => boolean; @@ -42,6 +44,7 @@ export interface AuxiliaryStrategy extends AuxiliaryIdentifierStrategy { /** * Validates if the representation contains valid data for an auxiliary resource. * Should throw an error in case the data is invalid. + * * @param identifier - Identifier of the auxiliary resource. * @param representation - Representation of the auxiliary resource. */ diff --git a/src/http/input/metadata/LinkRelParser.ts b/src/http/input/metadata/LinkRelParser.ts index f9d518f3f..6e2c67c86 100644 --- a/src/http/input/metadata/LinkRelParser.ts +++ b/src/http/input/metadata/LinkRelParser.ts @@ -50,7 +50,9 @@ export class LinkRelObject { /** * Checks whether the object can be added to the metadata + * * @param object - The link target. + * * @returns a boolean to indicate whether it can be added to the metadata or not */ private objectAllowed(object: string): boolean { @@ -59,6 +61,7 @@ export class LinkRelObject { /** * Adds the object to the metadata when it is allowed + * * @param object - The link target. * @param metadata - Metadata of the resource. * @param logger - Logger diff --git a/src/http/representation/RepresentationMetadata.ts b/src/http/representation/RepresentationMetadata.ts index e96465752..55271ce82 100644 --- a/src/http/representation/RepresentationMetadata.ts +++ b/src/http/representation/RepresentationMetadata.ts @@ -26,6 +26,7 @@ const cachedNamedNodes: Record = {}; * Converts the incoming name (URI or shorthand) to a named node. * The generated terms get cached to reduce the number of created nodes, * so only use this for internal constants! + * * @param name - Predicate to potentially transform. */ function toCachedNamedNode(name: string): NamedNode { @@ -167,6 +168,7 @@ export class RepresentationMetadata { /** * Helper function to import all entries from the given metadata. * If the new metadata has a different identifier the internal one will be updated. + * * @param metadata - Metadata to import. */ public setMetadata(metadata: RepresentationMetadata): this { @@ -235,6 +237,7 @@ export class RepresentationMetadata { /** * Adds a value linked to the identifier. Strings get converted to literals. + * * @param predicate - Predicate linking identifier to value. * @param object - Value(s) to add. * @param graph - Optional graph of where to add the values to. @@ -245,6 +248,7 @@ export class RepresentationMetadata { /** * Removes the given value from the metadata. Strings get converted to literals. + * * @param predicate - Predicate linking identifier to value. * @param object - Value(s) to remove. * @param graph - Optional graph of where to remove the values from. @@ -271,6 +275,7 @@ export class RepresentationMetadata { /** * Removes all values linked through the given predicate. + * * @param predicate - Predicate to remove. * @param graph - Optional graph where to remove from. */ @@ -300,6 +305,7 @@ export class RepresentationMetadata { /** * Finds all object values matching the given predicate and/or graph. + * * @param predicate - Optional predicate to get the values for. * @param graph - Optional graph where to get from. * @@ -314,10 +320,10 @@ export class RepresentationMetadata { * @param predicate - Predicate to get the value for. * @param graph - Optional graph where the triple should be found. * + * @returns The corresponding value. Undefined if there is no match + * * @throws Error * If there are multiple matching values. - * - * @returns The corresponding value. Undefined if there is no match */ public get(predicate: NamedNode, graph?: MetadataGraph): Term | undefined { const terms = this.getAll(predicate, graph); @@ -337,6 +343,7 @@ export class RepresentationMetadata { /** * Sets the value for the given predicate, removing all other instances. * In case the object is undefined this is identical to `removeAll(predicate)`. + * * @param predicate - Predicate linking to the value. * @param object - Value(s) to set. * @param graph - Optional graph where the triple should be stored. @@ -383,6 +390,7 @@ export class RepresentationMetadata { /** * Parse the internal RDF structure to retrieve the Record with ContentType Parameters. + * * @returns A {@link ContentType} object containing the value and optional parameters if there is one. */ private getContentType(): ContentType | undefined { diff --git a/src/identity/interaction/InteractionUtil.ts b/src/identity/interaction/InteractionUtil.ts index 6c3541884..b1a9621d4 100644 --- a/src/identity/interaction/InteractionUtil.ts +++ b/src/identity/interaction/InteractionUtil.ts @@ -49,6 +49,7 @@ export type AccountInteractionResults = { [ACCOUNT_PROMPT]?: string } & Interact /** * Updates the `oidcInteraction` object with the necessary data in case a prompt gets updated. + * * @param oidcInteraction - Interaction to update. * @param result - New data to add to the interaction. * @param mergeWithLastSubmission - If this new data needs to be merged with already existing data in the interaction. @@ -72,6 +73,7 @@ export async function finishInteraction( * Removes the WebID, the `accountId`, from the OIDC session object, * allowing us to replace it with a new value. * If there is no session in the Interaction, nothing will happen. + * * @param provider - The OIDC provider. * @param oidcInteraction - The current interaction. */ diff --git a/src/identity/interaction/account/util/AccountStore.ts b/src/identity/interaction/account/util/AccountStore.ts index 53f7a6958..d5cc94bd1 100644 --- a/src/identity/interaction/account/util/AccountStore.ts +++ b/src/identity/interaction/account/util/AccountStore.ts @@ -20,6 +20,7 @@ export interface AccountStore { /** * Finds the setting of the account with the given identifier. + * * @param id - The account identifier. * @param setting - The setting to find the value of. */ @@ -27,6 +28,7 @@ export interface AccountStore { /** * Updates the settings for the account with the given identifier to the new values. + * * @param id - The account identifier. * @param setting - The setting to update. * @param value - The new value for the setting. diff --git a/src/identity/interaction/account/util/CookieStore.ts b/src/identity/interaction/account/util/CookieStore.ts index d6ea3c9e8..ed1e178d5 100644 --- a/src/identity/interaction/account/util/CookieStore.ts +++ b/src/identity/interaction/account/util/CookieStore.ts @@ -5,6 +5,7 @@ export interface CookieStore { /** * Generates and stores a new cookie for the given accountId. * This does not replace previously generated cookies. + * * @param accountId - Account to create a cookie for. * * @returns The generated cookie. @@ -13,18 +14,21 @@ export interface CookieStore { /** * Return the accountID associated with the given cookie. + * * @param cookie - Cookie to find the account for. */ get: (cookie: string) => Promise; /** * Refreshes the cookie expiration and returns when it will expire if the cookie exists. + * * @param cookie - Cookie to refresh. */ refresh: (cookie: string) => Promise; /** * Deletes the given cookie. + * * @param cookie - Cookie to delete. */ delete: (cookie: string) => Promise; diff --git a/src/identity/interaction/login/ResolveLoginHandler.ts b/src/identity/interaction/login/ResolveLoginHandler.ts index ddba472a2..6968379c1 100644 --- a/src/identity/interaction/login/ResolveLoginHandler.ts +++ b/src/identity/interaction/login/ResolveLoginHandler.ts @@ -82,6 +82,7 @@ export abstract class ResolveLoginHandler extends JsonInteractionHandler { /** * Updates the account setting that determines if the login status needs to be remembered. + * * @param accountId - ID of the account. * @param remember - If the account should be remembered or not. The setting will not be updated if this is undefined. */ @@ -95,6 +96,7 @@ export abstract class ResolveLoginHandler extends JsonInteractionHandler { /** * Takes the necessary steps to log a user in. + * * @param input - Same input that was passed to the handle function. */ public abstract login(input: JsonInteractionHandlerInput): Promise>; diff --git a/src/identity/interaction/password/util/ForgotPasswordStore.ts b/src/identity/interaction/password/util/ForgotPasswordStore.ts index 2fbd407c1..cd7a47363 100644 --- a/src/identity/interaction/password/util/ForgotPasswordStore.ts +++ b/src/identity/interaction/password/util/ForgotPasswordStore.ts @@ -6,7 +6,9 @@ export interface ForgotPasswordStore { * Creates a Forgot Password Confirmation Record. This will be to remember that * a user has made a request to reset a password. Throws an error if the email doesn't * exist. + * * @param id - ID of the email/password login object. + * * @returns The record id. This should be included in the reset password link. */ generate: (id: string) => Promise; @@ -14,13 +16,16 @@ export interface ForgotPasswordStore { /** * Gets the email associated with the forgot password confirmation record * or undefined if it's not present. + * * @param recordId - The record id retrieved from the link. + * * @returns The user's email. */ get: (recordId: string) => Promise; /** * Deletes the Forgot Password Confirmation Record. + * * @param recordId - The record id of the forgot password confirmation record. */ delete: (recordId: string) => Promise; diff --git a/src/identity/storage/ClientIdAdapterFactory.ts b/src/identity/storage/ClientIdAdapterFactory.ts index 6ec8654c4..879949bb8 100644 --- a/src/identity/storage/ClientIdAdapterFactory.ts +++ b/src/identity/storage/ClientIdAdapterFactory.ts @@ -81,6 +81,7 @@ export class ClientIdAdapter extends PassthroughAdapter { /** * Parses RDF data found at a Client ID. + * * @param data - Raw data from the Client ID. * @param id - The actual Client ID. * @param response - Response object from the request. diff --git a/src/init/AppRunner.ts b/src/init/AppRunner.ts index 0baca15c3..d3b1ebd77 100644 --- a/src/init/AppRunner.ts +++ b/src/init/AppRunner.ts @@ -203,6 +203,7 @@ export class AppRunner { /** * Retrieves settings from package.json or configuration file when * part of an npm project. + * * @returns The settings defined in the configuration file */ public async getPackageSettings(): Promise> { diff --git a/src/init/ConfigPodInitializer.ts b/src/init/ConfigPodInitializer.ts index 228cefb70..da5573e26 100644 --- a/src/init/ConfigPodInitializer.ts +++ b/src/init/ConfigPodInitializer.ts @@ -14,6 +14,7 @@ import { Initializer } from './Initializer'; * Part of the dynamic pod creation. * Reads the contents from the configuration storage, uses those values to instantiate ResourceStores, * and then adds them to the routing storage. + * * @see {@link ConfigPodManager}, {@link TemplatedPodGenerator}, {@link BaseUrlRouterRule} */ export class ConfigPodInitializer extends Initializer { diff --git a/src/init/cluster/ClusterManager.ts b/src/init/cluster/ClusterManager.ts index caf38828b..1bbfcdeaa 100644 --- a/src/init/cluster/ClusterManager.ts +++ b/src/init/cluster/ClusterManager.ts @@ -18,7 +18,9 @@ enum ClusterMode { /** * Convert workers amount to {@link ClusterMode} + * * @param workers - Amount of workers + * * @returns ClusterMode enum value */ function toClusterMode(workers: number): ClusterMode { @@ -92,6 +94,7 @@ export class ClusterManager { /** * Check whether the CSS server was booted in single threaded mode. + * * @returns True is single threaded. */ public isSingleThreaded(): boolean { @@ -100,6 +103,7 @@ export class ClusterManager { /** * Whether the calling process is the primary process. + * * @returns True if primary */ public isPrimary(): boolean { @@ -108,6 +112,7 @@ export class ClusterManager { /** * Whether the calling process is a worker process. + * * @returns True if worker */ public isWorker(): boolean { diff --git a/src/init/cluster/SingleThreaded.ts b/src/init/cluster/SingleThreaded.ts index 685267c80..591632271 100644 --- a/src/init/cluster/SingleThreaded.ts +++ b/src/init/cluster/SingleThreaded.ts @@ -11,8 +11,10 @@ export interface SingleThreaded {} /** * Convert an exported interface name to the properly expected Components.js type URI. + * * @param componentsManager - The currently used ComponentsManager * @param interfaceName - An interface name + * * @returns A Components.js type URI */ export async function toComponentsJsType(componentsManager: ComponentsManager, interfaceName: string): @@ -38,6 +40,7 @@ Promise { /** * Will list class names of components instantiated implementing the {@link SingleThreaded} * interface while the application is being run in multithreaded mode. + * * @param componentsManager - The componentsManager being used to set up the application */ export async function listSingleThreadedComponents(componentsManager: ComponentsManager): Promise { diff --git a/src/logging/LogUtil.ts b/src/logging/LogUtil.ts index 04628a073..2498b09cd 100644 --- a/src/logging/LogUtil.ts +++ b/src/logging/LogUtil.ts @@ -42,6 +42,7 @@ export function getLoggerFor(loggable: string | Instance): Logger { /** * Sets the global logger factory. * This causes loggers created by {@link getLoggerFor} to delegate to a logger from the given factory. + * * @param loggerFactory - A logger factory. */ export function setGlobalLoggerFactory(loggerFactory: LoggerFactory): void { diff --git a/src/logging/Logger.ts b/src/logging/Logger.ts index 5bcbb81e8..62f69e593 100644 --- a/src/logging/Logger.ts +++ b/src/logging/Logger.ts @@ -17,6 +17,7 @@ export interface SimpleLogger { /** * Log the given message at the given level. * If the internal level is higher than the given level, the message may be voided. + * * @param level - The level to log at. * @param message - The message to log. * @param meta - Optional metadata to include in the log message. @@ -33,6 +34,7 @@ export interface Logger extends SimpleLogger { /** * Log the given message at the given level. * If the internal level is higher than the given level, the message may be voided. + * * @param level - The level to log at. * @param message - The message to log. * @param meta - Optional metadata to include in the log message. @@ -41,6 +43,7 @@ export interface Logger extends SimpleLogger { /** * Log a message at the 'error' level. + * * @param message - The message to log. * @param meta - Optional metadata to include in the log message. */ @@ -48,6 +51,7 @@ export interface Logger extends SimpleLogger { /** * Log a message at the 'warn' level. + * * @param message - The message to log. * @param meta - Optional metadata to include in the log message. */ @@ -55,6 +59,7 @@ export interface Logger extends SimpleLogger { /** * Log a message at the 'info' level. + * * @param message - The message to log. * @param meta - Optional metadata to include in the log message. */ @@ -62,6 +67,7 @@ export interface Logger extends SimpleLogger { /** * Log a message at the 'verbose' level. + * * @param message - The message to log. * @param meta - Optional metadata to include in the log message. */ @@ -69,6 +75,7 @@ export interface Logger extends SimpleLogger { /** * Log a message at the 'debug' level. + * * @param message - The message to log. * @param meta - Optional metadata to include in the log message. */ @@ -76,6 +83,7 @@ export interface Logger extends SimpleLogger { /** * Log a message at the 'silly' level. + * * @param message - The message to log. * @param meta - Optional metadata to include in the log message. */ diff --git a/src/logging/LoggerFactory.ts b/src/logging/LoggerFactory.ts index 4abe886e3..34dd279c1 100644 --- a/src/logging/LoggerFactory.ts +++ b/src/logging/LoggerFactory.ts @@ -6,6 +6,7 @@ import type { Logger } from './Logger'; export interface LoggerFactory { /** * Create a logger instance for the given label. + * * @param label - A label that is used to identify the given logger. */ createLogger: (label: string) => Logger; diff --git a/src/pods/PodManager.ts b/src/pods/PodManager.ts index b696faaeb..1881c2686 100644 --- a/src/pods/PodManager.ts +++ b/src/pods/PodManager.ts @@ -7,6 +7,7 @@ import type { PodSettings } from './settings/PodSettings'; export interface PodManager { /** * Creates a pod for the given settings. + * * @param settings - Settings describing the pod. * @param overwrite - If the creation should proceed if there already is a resource there. */ diff --git a/src/pods/generate/BaseComponentsJsFactory.ts b/src/pods/generate/BaseComponentsJsFactory.ts index d49ac8e88..00ba376d5 100644 --- a/src/pods/generate/BaseComponentsJsFactory.ts +++ b/src/pods/generate/BaseComponentsJsFactory.ts @@ -29,6 +29,7 @@ export class BaseComponentsJsFactory implements ComponentsJsFactory { /** * Calls Components.js to instantiate a new object. + * * @param configPath - Location of the config to instantiate. * @param componentIri - Iri of the object in the config that will be the result. * @param variables - Variables to send to Components.js diff --git a/src/pods/generate/ComponentsJsFactory.ts b/src/pods/generate/ComponentsJsFactory.ts index 6ce82bcc4..978217e8f 100644 --- a/src/pods/generate/ComponentsJsFactory.ts +++ b/src/pods/generate/ComponentsJsFactory.ts @@ -4,6 +4,7 @@ export interface ComponentsJsFactory { /** * Instantiates a new object using Components.js. + * * @param configPath - Location of the config to instantiate. * @param componentIri - Iri of the object in the config that will be the result. * @param variables - Variables to send to Components.js diff --git a/src/pods/generate/GenerateUtil.ts b/src/pods/generate/GenerateUtil.ts index e20cabdec..e1834beb8 100644 --- a/src/pods/generate/GenerateUtil.ts +++ b/src/pods/generate/GenerateUtil.ts @@ -4,6 +4,7 @@ import type { ResourcesGenerator } from './ResourcesGenerator'; /** * Generates resources with the given generator and adds them to the given store. + * * @param settings - Settings from which the pod is being created. * @param generator - Generator to be used. * @param store - Store to be updated. diff --git a/src/pods/generate/ResourcesGenerator.ts b/src/pods/generate/ResourcesGenerator.ts index b8089c16a..492f4ab19 100644 --- a/src/pods/generate/ResourcesGenerator.ts +++ b/src/pods/generate/ResourcesGenerator.ts @@ -15,6 +15,7 @@ export interface ResourcesGenerator { /** * Generates resources with the given options. * The output Iterable should be sorted so that containers always appear before their contents. + * * @param location - Base identifier. * @param options - Options that can be used when generating resources. * diff --git a/src/pods/generate/TemplatedResourcesGenerator.ts b/src/pods/generate/TemplatedResourcesGenerator.ts index f097ba952..840563331 100644 --- a/src/pods/generate/TemplatedResourcesGenerator.ts +++ b/src/pods/generate/TemplatedResourcesGenerator.ts @@ -11,6 +11,7 @@ export interface TemplatedResourcesGenerator { /** * Generates resources with the given options, based on the given template folder. * The output Iterable should be sorted so that containers always appear before their contents. + * * @param templateFolder - Folder where the templates are located. * @param location - Base identifier. * @param options - Options that can be used when generating resources. diff --git a/src/server/middleware/StaticAssetHandler.ts b/src/server/middleware/StaticAssetHandler.ts index 5b6358e27..33b58c8f9 100644 --- a/src/server/middleware/StaticAssetHandler.ts +++ b/src/server/middleware/StaticAssetHandler.ts @@ -39,6 +39,7 @@ export class StaticAssetHandler extends HttpHandler { /** * Creates a handler for the provided static resources. + * * @param assets - A list of {@link StaticAssetEntry}. * @param baseUrl - The base URL of the server. * @param options - Specific options. diff --git a/src/server/notifications/NotificationChannelStorage.ts b/src/server/notifications/NotificationChannelStorage.ts index 796df6be2..ac72514f5 100644 --- a/src/server/notifications/NotificationChannelStorage.ts +++ b/src/server/notifications/NotificationChannelStorage.ts @@ -11,6 +11,7 @@ export interface NotificationChannelStorage { /** * Returns the requested channel. * `undefined` if no match was found or if the notification channel expired. + * * @param id - The identifier of the notification channel. */ get: (id: string) => Promise; @@ -18,12 +19,14 @@ export interface NotificationChannelStorage { /** * Returns the identifiers of all notification channel entries that have the given identifier as their topic. * The identifiers can potentially correspond to expired channels. + * * @param topic - The identifier that is the topic. */ getAll: (topic: ResourceIdentifier) => Promise; /** * Adds the given channel to the storage. + * * @param channel - Channel to add. */ add: (channel: NotificationChannel) => Promise; @@ -31,6 +34,7 @@ export interface NotificationChannelStorage { /** * Updates the given notification channel. * The `id` and the `topic` can not be updated. + * * @param channel - The channel to update. */ update: (channel: NotificationChannel) => Promise; @@ -38,6 +42,7 @@ export interface NotificationChannelStorage { /** * Deletes the given notification channel from the storage. * Returns true if the channel existed. + * * @param id - The identifier of the notification channel */ delete: (id: string) => Promise; diff --git a/src/server/notifications/NotificationChannelType.ts b/src/server/notifications/NotificationChannelType.ts index 53a92e108..54f4fab29 100644 --- a/src/server/notifications/NotificationChannelType.ts +++ b/src/server/notifications/NotificationChannelType.ts @@ -31,6 +31,7 @@ export interface NotificationChannelType { /** * Validate and convert the input quads into a {@link NotificationChannel}. + * * @param data - The input quads. * @param credentials - The credentials of the agent doing the request. */ @@ -38,12 +39,14 @@ export interface NotificationChannelType { /** * Converts a {@link NotificationChannel} to a serialized JSON-LD representation. + * * @param channel - The notification channel to serialize. */ toJsonLd: (channel: NotificationChannel) => Promise>; /** * Determines which modes are required to allow the given notification channel. + * * @param channel - The notification channel to verify. * * @returns The required modes. @@ -53,6 +56,7 @@ export interface NotificationChannelType { /** * This function will be called after the serialized channel is sent back as a response, * allowing for any final actions that need to happen. + * * @param channel - The notification channel that is completed. */ completeChannel: (channel: NotificationChannel) => Promise; diff --git a/src/server/notifications/WebSocketChannel2023/WebSocket2023Util.ts b/src/server/notifications/WebSocketChannel2023/WebSocket2023Util.ts index dd39b802e..4394dc2f8 100644 --- a/src/server/notifications/WebSocketChannel2023/WebSocket2023Util.ts +++ b/src/server/notifications/WebSocketChannel2023/WebSocket2023Util.ts @@ -3,6 +3,7 @@ import { BadRequestHttpError } from '../../../util/errors/BadRequestHttpError'; /** * Generates a WebSocket URL by converting an HTTP(S) URL into a WS(S) URL. + * * @param id - The identifier of the channel. Needs to be a URL. */ export function generateWebSocketUrl(id: string): string { diff --git a/src/server/util/RedirectingHttpHandler.ts b/src/server/util/RedirectingHttpHandler.ts index 2cf766dd5..44e8d6071 100644 --- a/src/server/util/RedirectingHttpHandler.ts +++ b/src/server/util/RedirectingHttpHandler.ts @@ -37,6 +37,7 @@ export class RedirectingHttpHandler extends HttpHandler { /** * Creates a handler for the provided redirects. + * * @param redirects - A mapping between URL patterns. * @param baseUrl - Base URL of the server. * @param targetExtractor - To extract the target from the request. diff --git a/src/storage/DataAccessorBasedStore.ts b/src/storage/DataAccessorBasedStore.ts index 28b71d7e2..d0d232122 100644 --- a/src/storage/DataAccessorBasedStore.ts +++ b/src/storage/DataAccessorBasedStore.ts @@ -376,6 +376,7 @@ export class DataAccessorBasedStore implements ResourceStore { * * First the identifier gets requested and if no result is found * the identifier with differing trailing slash is requested. + * * @param identifier - Identifier that needs to be checked. */ protected async getNormalizedMetadata(identifier: ResourceIdentifier): Promise { @@ -411,6 +412,7 @@ export class DataAccessorBasedStore implements ResourceStore { /** * Write the given metadata resource to the DataAccessor. + * * @param identifier - Identifier of the metadata. * @param representation - Corresponding Representation. * @@ -451,6 +453,7 @@ export class DataAccessorBasedStore implements ResourceStore { /** * Write the given resource to the DataAccessor. Metadata will be updated with necessary triples. * In case of containers `handleContainerData` will be used to verify the data. + * * @param identifier - Identifier of the resource. * @param representation - Corresponding Representation. * @param isContainer - Is the incoming resource a container? @@ -576,6 +579,7 @@ export class DataAccessorBasedStore implements ResourceStore { /** * Validates if the slug and headers are valid. * Errors if slug exists, ends on slash, but ContainerType Link header is NOT present + * * @param isContainer - Is the slug supposed to represent a container? * @param slug - Is the requested slug (if any). */ @@ -588,6 +592,7 @@ export class DataAccessorBasedStore implements ResourceStore { /** * Clean http Slug to be compatible with the server. Makes sure there are no unwanted characters * e.g.: cleanslug('&%26') returns '%26%26' + * * @param slug - the slug to clean */ protected cleanSlug(slug: string): string { @@ -633,6 +638,7 @@ export class DataAccessorBasedStore implements ResourceStore { /** * Checks if the given metadata represents a (potential) container, * based on the metadata. + * * @param metadata - Metadata of the (new) resource. */ protected isContainerType(metadata: RepresentationMetadata): boolean { @@ -687,6 +693,7 @@ export class DataAccessorBasedStore implements ResourceStore { /** * Create containers starting from the root until the given identifier corresponds to an existing container. * Will throw errors if the identifier of the last existing "container" corresponds to an existing document. + * * @param container - Identifier of the container which will need to exist. */ protected async createRecursiveContainers(container: ResourceIdentifier): Promise { @@ -719,6 +726,7 @@ export class DataAccessorBasedStore implements ResourceStore { /** * Generates activity metadata for a resource and adds it to the {@link ChangeMap} + * * @param map - ChangeMap to update. * @param id - Identifier of the resource being changed. * @param activity - Which activity is taking place. @@ -729,6 +737,7 @@ export class DataAccessorBasedStore implements ResourceStore { /** * Generates activity metadata specifically for Add/Remove events on a container. + * * @param map - ChangeMap to update. * @param id - Identifier of the container. * @param add - If there is a resource being added (`true`) or removed (`false`). diff --git a/src/storage/ResourceSet.ts b/src/storage/ResourceSet.ts index 05b8fec73..c093000bc 100644 --- a/src/storage/ResourceSet.ts +++ b/src/storage/ResourceSet.ts @@ -6,6 +6,7 @@ import type { ResourceIdentifier } from '../http/representation/ResourceIdentifi export interface ResourceSet { /** * Check if a resource exists in this ResourceSet. + * * @param identifier - Identifier of resource to check. * * @returns A promise resolving if the resource already exists. diff --git a/src/storage/ResourceStore.ts b/src/storage/ResourceStore.ts index 7f3d00e4d..141b5f93d 100644 --- a/src/storage/ResourceStore.ts +++ b/src/storage/ResourceStore.ts @@ -28,6 +28,7 @@ export type ChangeMap = IdentifierMap; export interface ResourceStore extends ResourceSet { /** * Retrieves a representation of a resource. + * * @param identifier - Identifier of the resource to read. * @param preferences - Preferences indicating desired representations. * @param conditions - Optional conditions under which to proceed. @@ -43,6 +44,7 @@ export interface ResourceStore extends ResourceSet { /** * Sets or replaces the representation of a resource, * creating a new resource and intermediary containers as needed. + * * @param identifier - Identifier of resource to update. * @param representation - New representation of the resource. * @param conditions - Optional conditions under which to proceed. @@ -57,6 +59,7 @@ export interface ResourceStore extends ResourceSet { /** * Creates a new resource in the container. + * * @param container - Container in which to create a resource. * @param representation - Representation of the new resource * @param conditions - Optional conditions under which to proceed. @@ -71,6 +74,7 @@ export interface ResourceStore extends ResourceSet { /** * Deletes a resource. + * * @param identifier - Identifier of resource to delete. * @param conditions - Optional conditions under which to proceed. * @@ -84,6 +88,7 @@ export interface ResourceStore extends ResourceSet { /** * Sets or updates the representation of a resource, * creating a new resource and intermediary containers as needed. + * * @param identifier - Identifier of resource to update. * @param patch - Description of which parts to update. * @param conditions - Optional conditions under which to proceed. diff --git a/src/storage/accessors/DataAccessor.ts b/src/storage/accessors/DataAccessor.ts index 59e3636fb..6037df74b 100644 --- a/src/storage/accessors/DataAccessor.ts +++ b/src/storage/accessors/DataAccessor.ts @@ -16,6 +16,7 @@ import type { Guarded } from '../../util/GuardedStream'; export interface DataAccessor { /** * Should throw a NotImplementedHttpError if the DataAccessor does not support storing the given Representation. + * * @param representation - Incoming Representation. * * @throws BadRequestHttpError @@ -26,6 +27,7 @@ export interface DataAccessor { /** * Returns a data stream stored for the given identifier. * It can be assumed that the incoming identifier will always correspond to a document. + * * @param identifier - Identifier for which the data is requested. */ getData: (identifier: ResourceIdentifier) => Promise>; @@ -56,6 +58,7 @@ export interface DataAccessor { /** * Writes data and metadata for a document. * If any data and/or metadata exist for the given identifier, it should be overwritten. + * * @param identifier - Identifier of the resource. * @param data - Data to store. * @param metadata - Metadata to store. @@ -67,6 +70,7 @@ export interface DataAccessor { * Writes metadata for a container. * If the container does not exist yet it should be created, * if it does its metadata should be overwritten, except for the containment triples. + * * @param identifier - Identifier of the container. * @param metadata - Metadata to store. */ @@ -75,6 +79,7 @@ export interface DataAccessor { /** * Writes metadata for a resource. * It can safely be assumed that the subject resource already exists. + * * @param identifier - Identifier of the subject resource. * @param metadata - Metadata to store. */ diff --git a/src/storage/accessors/FileDataAccessor.ts b/src/storage/accessors/FileDataAccessor.ts index 4545689df..d409004b8 100644 --- a/src/storage/accessors/FileDataAccessor.ts +++ b/src/storage/accessors/FileDataAccessor.ts @@ -139,6 +139,7 @@ export class FileDataAccessor implements DataAccessor { /** * Gets the Stats object corresponding to the given file path, * resolving symbolic links. + * * @param path - File path to get info from. * * @throws NotFoundHttpError @@ -188,6 +189,7 @@ export class FileDataAccessor implements DataAccessor { /** * Writes the metadata of the resource to a meta file. + * * @param link - Path related metadata of the resource. * @param metadata - Metadata to write. * @@ -226,6 +228,7 @@ export class FileDataAccessor implements DataAccessor { /** * Generates metadata relevant for any resources stored by this accessor. + * * @param link - Path related metadata. * @param stats - Stats objects of the corresponding directory. * @param isContainer - If the path points to a container (directory) or not. @@ -319,6 +322,7 @@ export class FileDataAccessor implements DataAccessor { /** * Helper function to add file system related metadata. + * * @param metadata - metadata object to add to * @param stats - Stats of the file/directory corresponding to the resource. */ @@ -351,6 +355,7 @@ export class FileDataAccessor implements DataAccessor { /** * Helper function without extra validation checking to create a data file. + * * @param path - The filepath of the file to be created. * @param data - The data to be put in the file. */ diff --git a/src/storage/accessors/SparqlDataAccessor.ts b/src/storage/accessors/SparqlDataAccessor.ts index 485725df7..9efdb910f 100644 --- a/src/storage/accessors/SparqlDataAccessor.ts +++ b/src/storage/accessors/SparqlDataAccessor.ts @@ -174,6 +174,7 @@ export class SparqlDataAccessor implements DataAccessor { /** * Creates the name for the metadata of a resource. + * * @param name - Name of the (non-metadata) resource. */ private getMetadataNode(name: NamedNode): NamedNode { @@ -189,6 +190,7 @@ export class SparqlDataAccessor implements DataAccessor { /** * Creates a CONSTRUCT query that returns all quads contained within a single resource. + * * @param name - Name of the resource to query. */ private sparqlConstruct(name: NamedNode): ConstructQuery { @@ -213,6 +215,7 @@ export class SparqlDataAccessor implements DataAccessor { /** * Creates an update query that overwrites the data and metadata of a resource. * If there are no triples we assume it's a container (so don't overwrite the main graph with containment triples). + * * @param name - Name of the resource to update. * @param metadata - New metadata of the resource. * @param parent - Name of the parent to update the containment triples. @@ -255,6 +258,7 @@ export class SparqlDataAccessor implements DataAccessor { /** * Creates an update query that overwrites metadata of a resource. + * * @param metaName - Name of the metadata resource to update. * @param metadata - New metadata of the resource. */ @@ -280,6 +284,7 @@ export class SparqlDataAccessor implements DataAccessor { /** * Creates a query that deletes everything related to the given name. + * * @param name - Name of resource to delete. * @param parent - Parent of the resource to delete so the containment triple can be removed (unless root). */ @@ -306,6 +311,7 @@ export class SparqlDataAccessor implements DataAccessor { /** * Helper function for creating SPARQL update queries. * Creates an operation for deleting all triples in a graph. + * * @param name - Name of the graph to delete. */ private sparqlUpdateDeleteAll(name: NamedNode): InsertDeleteOperation { @@ -318,6 +324,7 @@ export class SparqlDataAccessor implements DataAccessor { /** * Helper function for creating SPARQL update queries. * Creates a Graph selector with the given triples. + * * @param name - Name of the graph. * @param triples - Triples/triple patterns to select. */ @@ -327,6 +334,7 @@ export class SparqlDataAccessor implements DataAccessor { /** * Sends a SPARQL CONSTRUCT query to the endpoint and returns a stream of quads. + * * @param sparqlQuery - Query to execute. */ private async sendSparqlConstruct(sparqlQuery: ConstructQuery): Promise> { @@ -342,6 +350,7 @@ export class SparqlDataAccessor implements DataAccessor { /** * Sends a SPARQL update query to the stored endpoint. + * * @param sparqlQuery - Query to send. */ private async sendSparqlUpdate(sparqlQuery: Update): Promise { diff --git a/src/storage/conditions/Conditions.ts b/src/storage/conditions/Conditions.ts index 067eaccb7..e87b8f378 100644 --- a/src/storage/conditions/Conditions.ts +++ b/src/storage/conditions/Conditions.ts @@ -23,6 +23,7 @@ export interface Conditions { /** * Checks validity based on the given metadata. + * * @param metadata - Metadata of the representation. Undefined if the resource does not exist. * @param strict - How to compare the ETag related headers. * If true, the comparison will happen on representation level. diff --git a/src/storage/conditions/ETagHandler.ts b/src/storage/conditions/ETagHandler.ts index c4c26ddf0..1420e8f38 100644 --- a/src/storage/conditions/ETagHandler.ts +++ b/src/storage/conditions/ETagHandler.ts @@ -26,6 +26,7 @@ export interface ETagHandler { /** * Validates whether 2 ETags correspond to the same state of a resource, * independent of the representation the ETags correspond to. + * * @param eTag1 - First ETag to compare. * @param eTag2 - Second ETag to compare. */ diff --git a/src/storage/conversion/ConversionUtil.ts b/src/storage/conversion/ConversionUtil.ts index 3b7dc6fae..8d5eba862 100644 --- a/src/storage/conversion/ConversionUtil.ts +++ b/src/storage/conversion/ConversionUtil.ts @@ -164,6 +164,7 @@ export function matchesMediaPreferences(type: string, preferred?: ValuePreferenc /** * Checks if the given two media types/ranges match each other. * Takes wildcards into account. + * * @param mediaA - Media type to match. * @param mediaB - Media type to match. * @@ -202,6 +203,7 @@ export function isInternalContentType(contentType?: string): boolean { /** * Serializes a preferences object to a string for display purposes. + * * @param preferences - Preferences to serialize */ export function preferencesToString(preferences: ValuePreferences): string { diff --git a/src/storage/keyvalue/JsonFileStorage.ts b/src/storage/keyvalue/JsonFileStorage.ts index 063591bd3..1be62d51b 100644 --- a/src/storage/keyvalue/JsonFileStorage.ts +++ b/src/storage/keyvalue/JsonFileStorage.ts @@ -61,6 +61,7 @@ export class JsonFileStorage implements KeyValueStorage { /** * Updates the data in the JSON file while using a write lock. + * * @param updateFn - A function that updates the JSON object. * * @returns The return value of `updateFn`. diff --git a/src/storage/keyvalue/KeyValueStorage.ts b/src/storage/keyvalue/KeyValueStorage.ts index 4b238274f..e98889865 100644 --- a/src/storage/keyvalue/KeyValueStorage.ts +++ b/src/storage/keyvalue/KeyValueStorage.ts @@ -6,18 +6,21 @@ export interface KeyValueStorage { /** * Returns the value stored for the given identifier. * `undefined` if no value is stored. + * * @param identifier - Identifier to get the value for. */ get: (key: TKey) => Promise; /** * Checks if there is a value stored for the given key. + * * @param identifier - Identifier to check. */ has: (key: TKey) => Promise; /** * Sets the value for the given key. + * * @param key - Key to set/update. * @param value - Value to store. * @@ -27,6 +30,7 @@ export interface KeyValueStorage { /** * Deletes the value stored for the given key. + * * @param key - Key to delete. * * @returns If there was a value to delete. diff --git a/src/storage/mapping/BaseFileIdentifierMapper.ts b/src/storage/mapping/BaseFileIdentifierMapper.ts index a5440afec..c4c0540c9 100644 --- a/src/storage/mapping/BaseFileIdentifierMapper.ts +++ b/src/storage/mapping/BaseFileIdentifierMapper.ts @@ -36,6 +36,7 @@ export class BaseFileIdentifierMapper implements FileIdentifierMapper { * Maps the given resource identifier / URL to a file path. * Determines the content type if none was provided. * For containers the content-type input is ignored. + * * @param identifier - The input identifier. * @param isMetadata - If we need the data or metadata file path. * @param contentType - The content-type provided with the request. @@ -59,6 +60,7 @@ export class BaseFileIdentifierMapper implements FileIdentifierMapper { /** * Maps the given container identifier to a file path, * possibly making alterations to the direct translation. + * * @param identifier - The input identifier. * @param filePath - The direct translation of the identifier onto the file path. * @@ -74,6 +76,7 @@ export class BaseFileIdentifierMapper implements FileIdentifierMapper { * possibly making alterations to the direct translation * (for instance, based on its content type)). * Determines the content type if none was provided. + * * @param identifier - The input identifier. * @param filePath - The direct translation of the identifier onto the file path. * @param contentType - The content-type provided with the request. @@ -92,6 +95,7 @@ export class BaseFileIdentifierMapper implements FileIdentifierMapper { /** * Determines the content type from the document identifier. + * * @param identifier - The input identifier. * @param contentType - The content-type provided with the request. * @@ -103,6 +107,7 @@ export class BaseFileIdentifierMapper implements FileIdentifierMapper { /** * Maps the given file path to a URL and determines its content type. + * * @param filePath - The input file path. * @param isContainer - If the path corresponds to a file. * @@ -134,6 +139,7 @@ export class BaseFileIdentifierMapper implements FileIdentifierMapper { /** * Maps the given container path to a URL and determines its content type. + * * @param relative - The relative container path. * * @returns A ResourceLink with all the necessary metadata. @@ -144,6 +150,7 @@ export class BaseFileIdentifierMapper implements FileIdentifierMapper { /** * Maps the given document path to a URL and determines its content type. + * * @param relative - The relative document path. * * @returns A ResourceLink with all the necessary metadata. @@ -154,6 +161,7 @@ export class BaseFileIdentifierMapper implements FileIdentifierMapper { /** * Determines the content type from the relative path. + * * @param filePath - The file path of the document. * * @returns The content type of the document. @@ -165,6 +173,7 @@ export class BaseFileIdentifierMapper implements FileIdentifierMapper { /** * Get the absolute file path based on the rootFilepath. + * * @param path - The relative file path. * * @returns Absolute path of the file. @@ -175,12 +184,13 @@ export class BaseFileIdentifierMapper implements FileIdentifierMapper { /** * Strips the baseRequestURI from the identifier. + * * @param identifier - Incoming identifier. * + * @returns A string representing the relative path. + * * @throws NotFoundHttpError * If the identifier does not match the baseRequestURI. - * - * @returns A string representing the relative path. */ protected getRelativePath(identifier: ResourceIdentifier): string { if (!identifier.path.startsWith(this.baseRequestURI)) { @@ -193,11 +203,11 @@ export class BaseFileIdentifierMapper implements FileIdentifierMapper { /** * Check if the given relative path is valid. * - * @throws BadRequestHttpError - * If the relative path is invalid. - * * @param path - A relative path, as generated by {@link getRelativePath}. * @param identifier - A resource identifier. + * + * @throws BadRequestHttpError + * If the relative path is invalid. */ protected validateRelativePath(path: string, identifier: ResourceIdentifier): void { if (!path.startsWith('/')) { diff --git a/src/storage/mapping/FileIdentifierMapper.ts b/src/storage/mapping/FileIdentifierMapper.ts index f56fad618..4c4bf1556 100644 --- a/src/storage/mapping/FileIdentifierMapper.ts +++ b/src/storage/mapping/FileIdentifierMapper.ts @@ -25,6 +25,7 @@ export interface ResourceLink { export interface FileIdentifierMapper { /** * Maps the given file path to an URL and determines the content-type + * * @param filePath - The input file path. * @param isContainer - If the path corresponds to a file. * @@ -36,6 +37,7 @@ export interface FileIdentifierMapper { * Determines the content-type if no content-type was provided by finding the corresponding file. * If there is no corresponding file a file path will be generated. * For containers the content-type input gets ignored. + * * @param identifier - The input identifier. * @param isMetadata - If we are mapping the metadata of the resource instead of its data. * @param contentType - The (optional) content-type of the resource. diff --git a/src/storage/quota/QuotaStrategy.ts b/src/storage/quota/QuotaStrategy.ts index 07efd6095..07324f2f1 100644 --- a/src/storage/quota/QuotaStrategy.ts +++ b/src/storage/quota/QuotaStrategy.ts @@ -33,6 +33,7 @@ export abstract class QuotaStrategy { * as available space. * * @param identifier - the identifier of the resource of which you want the available space + * * @returns the available space and the unit of the space as a Size object */ public async getAvailableSpace(identifier: ResourceIdentifier): Promise { @@ -57,6 +58,7 @@ export abstract class QuotaStrategy { * Get the currently used/occupied space. * * @param identifier - the identifier that should be used to calculate the total + * * @returns a Size object containing the requested value. * If quota is not relevant for this identifier, Size.amount should be Number.MAX_SAFE_INTEGER */ @@ -66,6 +68,7 @@ export abstract class QuotaStrategy { * Get an estimated size of the resource * * @param metadata - the metadata that might include the size + * * @returns a Size object containing the estimated size and unit of the resource */ public async estimateSize(metadata: RepresentationMetadata): Promise { @@ -79,6 +82,7 @@ export abstract class QuotaStrategy { * Like other Passthrough instances this will simply pass on the chunks, when the quota isn't exceeded. * * @param identifier - the identifier of the resource in question + * * @returns a Passthrough instance that errors when quota is exceeded */ public async createQuotaGuard(identifier: ResourceIdentifier): Promise> { diff --git a/src/storage/routing/BaseUrlRouterRule.ts b/src/storage/routing/BaseUrlRouterRule.ts index fd59ba515..11fe9d12d 100644 --- a/src/storage/routing/BaseUrlRouterRule.ts +++ b/src/storage/routing/BaseUrlRouterRule.ts @@ -11,6 +11,7 @@ import { RouterRule } from './RouterRule'; * * Part of the dynamic pod creation. * Uses the identifiers that were added to the routing storage. + * * @see {@link TemplatedPodGenerator}, {@link ConfigPodInitializer}, {@link ConfigPodManager} */ export class BaseUrlRouterRule extends RouterRule { diff --git a/src/storage/size-reporter/FileSizeReporter.ts b/src/storage/size-reporter/FileSizeReporter.ts index 78f120f28..d26ce8363 100644 --- a/src/storage/size-reporter/FileSizeReporter.ts +++ b/src/storage/size-reporter/FileSizeReporter.ts @@ -49,6 +49,7 @@ export class FileSizeReporter implements SizeReporter { * Get the total size of a resource and its children if present * * @param fileLocation - the resource of which you want the total size of ( on disk ) + * * @returns a number specifying how many bytes are used by the resource */ private async getTotalSize(fileLocation: string): Promise { diff --git a/src/storage/size-reporter/SizeReporter.ts b/src/storage/size-reporter/SizeReporter.ts index 30ec5d59b..d18b91a45 100644 --- a/src/storage/size-reporter/SizeReporter.ts +++ b/src/storage/size-reporter/SizeReporter.ts @@ -20,6 +20,7 @@ export interface SizeReporter { * Get the size of a given resource * * @param identifier - the resource of which you want the size + * * @returns The size of the resource as a Size object calculated recursively * if the identifier leads to a container */ @@ -29,6 +30,7 @@ export interface SizeReporter { * Calculate the size of a chunk based on which SizeReporter is being used * * @param chunk - the chunk of which you want the size + * * @returns the size of the passed chunk as a number */ calculateChunkSize: (chunk: T) => Promise; @@ -37,6 +39,7 @@ export interface SizeReporter { * Estimate the size of a body / request by looking at its metadata * * @param metadata - the metadata of the resource you want an estimated size of + * * @returns the estimated size of the body / request or undefined if no * meaningful estimation can be made */ diff --git a/src/util/Header.ts b/src/util/Header.ts index 06f43b259..dd5102633 100644 --- a/src/util/Header.ts +++ b/src/util/Header.ts @@ -55,6 +55,7 @@ export class ContentType { /** * Serialize this ContentType object to a ContentType header appropriate value string. + * * @returns The value string, including parameters, if present. */ public toHeaderValueString(): string { diff --git a/src/util/HeaderUtil.ts b/src/util/HeaderUtil.ts index 5c9ea8ffd..00cf20f84 100644 --- a/src/util/HeaderUtil.ts +++ b/src/util/HeaderUtil.ts @@ -29,12 +29,13 @@ const logger = getLoggerFor('HeaderUtil'); // HELPER FUNCTIONS /** * Replaces all double quoted strings in the input string with `"0"`, `"1"`, etc. + * * @param input - The Accept header string. * + * @returns The transformed string and a map with keys `"0"`, etc. and values the original string that was there. + * * @throws BadRequestHttpError * Thrown if invalid characters are detected in a quoted string. - * - * @returns The transformed string and a map with keys `"0"`, etc. and values the original string that was there. */ export function transformQuotedStrings(input: string): { result: string; replacements: Record } { let idx = 0; @@ -200,6 +201,7 @@ function parseAcceptPart(part: string, replacements: Record, str /** * Parses an Accept-* header where each part is only a value and a weight, so roughly /.*(q=.*)?/ separated by commas. * The returned weights default to 1 if no q value is found or the q value is invalid. + * * @param input - Input header string. * @param strict - Determines if invalid values throw errors (`true`) or log warnings (`false`). Defaults to `false`. * @@ -371,10 +373,10 @@ export function addHeader(response: HttpResponse, name: string, value: string | * * @param input - The Content-Type header string. * + * @returns A {@link ContentType} object containing the value and optional parameters. + * * @throws BadRequestHttpError * Thrown on invalid header syntax. - * - * @returns A {@link ContentType} object containing the value and optional parameters. */ export function parseContentType(input: string): ContentType { // Quoted strings could prevent split from having correct results @@ -438,6 +440,7 @@ export function parseForwarded(headers: IncomingHttpHeaders): Forwarded { * Parses the link header(s) and returns an array of LinkEntry objects. * * @param link - A single link header or an array of link headers + * * @returns A LinkEntry array, LinkEntry contains a link and a params Record<string,string> */ export function parseLinkHeader(link: string | string[] = []): LinkEntry[] { @@ -484,6 +487,7 @@ const authSchemeRegexCache: Map = new Map(); * * @param scheme - Name of the authorization scheme (case insensitive). * @param authorization - The value of the Authorization header (may be undefined). + * * @returns True if the Authorization header uses the specified scheme, false otherwise. */ export function matchesAuthorizationScheme(scheme: string, authorization?: string): boolean { @@ -500,6 +504,7 @@ export function matchesAuthorizationScheme(scheme: string, authorization?: strin * * @param url - A string representing the URL. * @param schemes - Scheme value options (the function will check if at least one matches the URL scheme). + * * @returns True if the URL scheme matches at least one of the provided options, false otherwise. */ export function hasScheme(url: string, ...schemes: string[]): boolean { diff --git a/src/util/IterableUtil.ts b/src/util/IterableUtil.ts index 79a57ebeb..81a0d7bfc 100644 --- a/src/util/IterableUtil.ts +++ b/src/util/IterableUtil.ts @@ -48,6 +48,7 @@ export function* filter( /** * Creates a new iterable that is a concatenation of all the iterables in the input. + * * @param iterables - An iterable of which the contents will be concatenated into a new iterable. */ export function* concat(iterables: Iterable>): Iterable { diff --git a/src/util/LockUtils.ts b/src/util/LockUtils.ts index 5df47f554..d363ff245 100644 --- a/src/util/LockUtils.ts +++ b/src/util/LockUtils.ts @@ -5,8 +5,10 @@ const logger = getLoggerFor('LockUtil'); /** * Waits a set amount of time, without consuming cpu, with a set amount of jitter. + * * @param delay - How long to wait. * @param jitter - A fraction of this jitter will be added to the delay. + * * @returns A promise that resolves after the specified amount of time. */ export async function setJitterTimeout(delay: number, jitter = 0): Promise { @@ -28,8 +30,8 @@ export interface AttemptSettings { * Will execute the given function until one of the following cases occurs: * * The function resolves to a value: the value is returned. * * The function errors: the rejected error is thrown. - * * The function did not resolve after the set amount of retries: - * the rejected error is returned. + * * The function did not resolve after the set amount of retries: the rejected error is returned. + * * @param fn - The function to retry. **This function must return a value!** * @param settings - The options on how to retry the function */ diff --git a/src/util/PathUtil.ts b/src/util/PathUtil.ts index c9c9e6de1..d6ede69b9 100644 --- a/src/util/PathUtil.ts +++ b/src/util/PathUtil.ts @@ -113,6 +113,7 @@ export function trimLeadingSlashes(path: string): string { /** * Extracts the extension (without dot) from a path. * Custom function since `path.extname` does not work on all cases (e.g. ".acl") + * * @param path - Input path to parse. */ export function getExtension(path: string): string { @@ -150,6 +151,7 @@ function transformPathComponents(path: string, transform: (part: string) => stri * the provided path. * * @param path - The path to convert to its canonical URI path form. + * * @returns The canonical URI path form of the provided path. */ export function toCanonicalUriPath(path: string): string { @@ -178,6 +180,7 @@ const forbiddenRegex = new RegExp(`[${Object.keys(forbiddenSymbols).join('')}]`, * Characters that would result in an illegal file path remain percent encoded. * * @param path - The path to decode the URI path components of. + * * @returns A decoded copy of the provided URI path (ignoring encoded slash characters). */ export function decodeUriPathComponents(path: string): string { @@ -192,6 +195,7 @@ export function decodeUriPathComponents(path: string): string { * lead to unnecessary double encoding, resulting in a URI that differs from the expected result. * * @param path - The path to encode the URI path components of. + * * @returns An encoded copy of the provided URI path (ignoring encoded slash characters). */ export function encodeUriPathComponents(path: string): string { @@ -200,6 +204,7 @@ export function encodeUriPathComponents(path: string): string { /** * Checks if the path corresponds to a container path (ending in a /). + * * @param path - Path to check. */ export function isContainerPath(path: string): boolean { @@ -210,6 +215,7 @@ export function isContainerPath(path: string): boolean { /** * Checks if the identifier corresponds to a container identifier. + * * @param identifier - Identifier to check. */ export function isContainerIdentifier(identifier: ResourceIdentifier): boolean { @@ -219,6 +225,7 @@ export function isContainerIdentifier(identifier: ResourceIdentifier): boolean { /** * Splits a URL (or similar) string into a part containing its scheme and one containing the rest. * E.g., `http://test.com/` results in `{ scheme: 'http://', rest: 'test.com/' }`. + * * @param url - String to parse. */ export function extractScheme(url: string): { scheme: string; rest: string } { @@ -229,6 +236,7 @@ export function extractScheme(url: string): { scheme: string; rest: string } { /** * Creates a relative URL by removing the base URL. * Will throw an error in case the resulting target is not withing the base URL scope. + * * @param baseUrl - Base URL. * @param request - Incoming request of which the target needs to be extracted. * @param targetExtractor - Will extract the target from the request. @@ -251,11 +259,12 @@ Promise { * In case there is a subdomain, the first match of the regular expression will be that subdomain. * * Examples with baseUrl `http://test.com/foo/`: - * - Will match `http://test.com/foo/` - * - Will match `http://test.com/foo/bar/baz` - * - Will match `http://alice.bob.test.com/foo/bar/baz`, first match result will be `alice.bob` - * - Will not match `http://test.com/` - * - Will not match `http://alicetest.com/foo/` + * - Will match `http://test.com/foo/` + * - Will match `http://test.com/foo/bar/baz` + * - Will match `http://alice.bob.test.com/foo/bar/baz`, first match result will be `alice.bob` + * - Will not match `http://test.com/` + * - Will not match `http://alicetest.com/foo/` + * * @param baseUrl - Base URL for the regular expression. */ export function createSubdomainRegexp(baseUrl: string): RegExp { diff --git a/src/util/PromiseUtil.ts b/src/util/PromiseUtil.ts index 690123cc6..e44bd78a5 100644 --- a/src/util/PromiseUtil.ts +++ b/src/util/PromiseUtil.ts @@ -5,6 +5,7 @@ export type PromiseOrValue = T | Promise; /** * Verifies if the given value is a Promise or not. + * * @param object - Object to check. */ export function isPromise(object: PromiseOrValue): object is Promise { diff --git a/src/util/QuadUtil.ts b/src/util/QuadUtil.ts index 494bbfdbc..19e2130ba 100644 --- a/src/util/QuadUtil.ts +++ b/src/util/QuadUtil.ts @@ -9,6 +9,7 @@ import { toNamedTerm } from './TermUtil'; /** * Helper function for serializing an array of quads, with as result a Readable object. + * * @param quads - The array of quads. * @param contentType - The content-type to serialize to. * @@ -20,6 +21,7 @@ export function serializeQuads(quads: Quad[], contentType?: string): Guarded, options: ParserOpt /** * Filter out duplicate quads from an array. + * * @param quads - Quads to filter. * * @returns A new array containing the unique quads. diff --git a/src/util/ResourceUtil.ts b/src/util/ResourceUtil.ts index 72d6f09fa..925c5c8f3 100644 --- a/src/util/ResourceUtil.ts +++ b/src/util/ResourceUtil.ts @@ -13,6 +13,7 @@ import namedNode = DataFactory.namedNode; /** * Helper function to generate type quads for a Container or Resource. + * * @param metadata - Metadata to add to. * @param isContainer - If the identifier corresponds to a container. */ @@ -26,6 +27,7 @@ export function addResourceMetadata(metadata: RepresentationMetadata, isContaine /** * Updates the dc:modified time to the given time. + * * @param metadata - Metadata to update. * @param date - Last modified date. Defaults to current time. */ @@ -38,6 +40,7 @@ export function updateModifiedDate(metadata: RepresentationMetadata, date = new /** * Links a template file with a given content-type to the metadata using the SOLID_META.template predicate. + * * @param metadata - Metadata to update. * @param templateFile - Path to the template. * @param contentType - Content-type of the template after it is rendered. @@ -52,6 +55,7 @@ void { /** * Helper function to clone a representation, the original representation can still be used. * This function loads the entire stream in memory. + * * @param representation - The representation to clone. * * @returns The cloned representation. diff --git a/src/util/StreamUtil.ts b/src/util/StreamUtil.ts index 03524ff0c..3bfa47aab 100644 --- a/src/util/StreamUtil.ts +++ b/src/util/StreamUtil.ts @@ -19,6 +19,7 @@ const logger = getLoggerFor('StreamUtil'); /** * Joins all strings of a stream. + * * @param stream - Stream of strings. * * @returns The joined string. @@ -29,6 +30,7 @@ export async function readableToString(stream: Readable): Promise { /** * Imports quads from a stream into a Store. + * * @param stream - Stream of quads. * * @returns A Store containing all the quads. @@ -42,6 +44,7 @@ export async function readableToQuads(stream: Readable): Promise { /** * Interprets the stream as JSON and converts it to a Dict. + * * @param stream - Stream of JSON data. * * @returns The parsed object. @@ -55,6 +58,7 @@ export async function readJsonStream(stream: Readable): Promise { * Converts the stream to a single object. * This assumes the stream is in object mode and only contains a single element, * otherwise an error will be thrown. + * * @param stream - Object stream with single entry. */ export async function getSingleItem(stream: Readable): Promise { @@ -78,6 +82,7 @@ const safeErrors = new Set([ * Pipes one stream into another and emits errors of the first stream with the second. * In case of an error in the first stream the second one will be destroyed with the given error. * This will also make the stream {@link Guarded}. + * * @param readable - Initial readable stream. * @param destination - The destination for writing data. * @param mapError - Optional function that takes the error and converts it to a new error. @@ -134,6 +139,7 @@ export interface AsyncTransformOptions extends DuplexOptions { /** * Transforms a stream, ensuring that all errors are forwarded. + * * @param source - The stream to be transformed. * @param options - The transformation options. * @param options.transform - The transform function to use. @@ -177,6 +183,7 @@ export function transformSafely( /** * Converts a string or array to a stream and applies an error guard so that it is {@link Guarded}. + * * @param contents - Data to stream. * @param options - Options to pass to the Readable constructor. See {@link Readable.from}. */ diff --git a/src/util/StringUtil.ts b/src/util/StringUtil.ts index 484ee7cd1..fdfcaab52 100644 --- a/src/util/StringUtil.ts +++ b/src/util/StringUtil.ts @@ -13,6 +13,7 @@ export function splitCommaSeparated(input: string): string[] { * Sanitizes part of a URL by replacing non-word content with a '-'. * * @param urlPart - The URL part to sanitize. + * * @returns The sanitized output. */ export function sanitizeUrlPart(urlPart: string): string { @@ -23,6 +24,7 @@ export function sanitizeUrlPart(urlPart: string): string { * Checks the validity of a file name. A valid name consists of word characters, '-' or '.'. * * @param name - The name of the file to validate. + * * @returns True if the filename is valid, false otherwise. */ export function isValidFileName(name: string): boolean { @@ -33,6 +35,7 @@ export function isValidFileName(name: string): boolean { * Checks if the given string is a valid URL. * * @param url - String to check. + * * @returns True if the string is a valid URL. */ export function isUrl(url: string): boolean { @@ -49,6 +52,7 @@ export function isUrl(url: string): boolean { * Converts milliseconds to an ISO 8601 duration string. * The only categories used are days, hours, minutes, and seconds, * because months have no fixed size in milliseconds. + * * @param ms - The duration in ms to convert. */ export function msToDuration(ms: number): string { diff --git a/src/util/TermUtil.ts b/src/util/TermUtil.ts index 14474cf32..caed50f45 100644 --- a/src/util/TermUtil.ts +++ b/src/util/TermUtil.ts @@ -12,6 +12,7 @@ export function isTerm(input?: unknown): input is Term { /** * Converts a string to a named node when needed. + * * @param subject - Subject to potentially transform. */ export function toNamedTerm(subject: string): NamedNode; @@ -25,6 +26,7 @@ export const toPredicateTerm = toNamedTerm; /** * Converts an object term when needed. + * * @param object - Object to potentially transform. * @param preferLiteral - Whether strings are converted to literals or named nodes. */ @@ -40,6 +42,7 @@ export function toObjectTerm(object: Term | string, preferLiteral = false): Term /** * Creates a literal by first converting the dataType string to a named node. + * * @param object - Object value. * @param dataType - Object data type (as string). */ diff --git a/src/util/Vocabularies.ts b/src/util/Vocabularies.ts index 594f5b558..4ab5b2737 100644 --- a/src/util/Vocabularies.ts +++ b/src/util/Vocabularies.ts @@ -88,6 +88,7 @@ string extends TLocal ? PartialVocabulary : Vocabulary { /** * Creates a new {@link Vocabulary} that extends an existing one by adding new local names. + * * @param vocabulary - The {@link Vocabulary} to extend. * @param newNames - The new local names that need to be added. */ diff --git a/src/util/errors/BadRequestHttpError.ts b/src/util/errors/BadRequestHttpError.ts index 87c330fe8..ac982897e 100644 --- a/src/util/errors/BadRequestHttpError.ts +++ b/src/util/errors/BadRequestHttpError.ts @@ -11,6 +11,7 @@ const BaseHttpError = generateHttpErrorClass(400, 'BadRequestHttpError'); export class BadRequestHttpError extends BaseHttpError { /** * Default message is 'The given input is not supported by the server configuration.'. + * * @param message - Optional, more specific, message. * @param options - Optional error options. */ diff --git a/src/util/errors/HttpError.ts b/src/util/errors/HttpError.ts index ed039c105..8a6a42b55 100644 --- a/src/util/errors/HttpError.ts +++ b/src/util/errors/HttpError.ts @@ -29,6 +29,7 @@ export class HttpError extends Error implements HttpE /** * Creates a new HTTP error. Subclasses should call this with their fixed status code. + * * @param statusCode - HTTP status code needed for the HTTP response. * @param name - Error name. Useful for logging and stack tracing. * @param message - Error message. diff --git a/src/util/errors/PayloadHttpError.ts b/src/util/errors/PayloadHttpError.ts index 865f484e6..87f473060 100644 --- a/src/util/errors/PayloadHttpError.ts +++ b/src/util/errors/PayloadHttpError.ts @@ -10,6 +10,7 @@ const BaseHttpError = generateHttpErrorClass(413, 'PayloadHttpError'); export class PayloadHttpError extends BaseHttpError { /** * Default message is 'Storage quota was exceeded.'. + * * @param message - Optional, more specific, message. * @param options - Optional error options. */ diff --git a/src/util/errors/RangeNotSatisfiedHttpError.ts b/src/util/errors/RangeNotSatisfiedHttpError.ts index 0ee723a88..eec45ed2c 100644 --- a/src/util/errors/RangeNotSatisfiedHttpError.ts +++ b/src/util/errors/RangeNotSatisfiedHttpError.ts @@ -10,6 +10,7 @@ const BaseHttpError = generateHttpErrorClass(416, 'RangeNotSatisfiedHttpError'); export class RangeNotSatisfiedHttpError extends BaseHttpError { /** * Default message is 'The requested range is not supported.'. + * * @param message - Optional, more specific, message. * @param options - Optional error options. */ diff --git a/src/util/handlers/AsyncHandler.ts b/src/util/handlers/AsyncHandler.ts index a454d2ab9..b8110563c 100644 --- a/src/util/handlers/AsyncHandler.ts +++ b/src/util/handlers/AsyncHandler.ts @@ -9,6 +9,7 @@ export abstract class AsyncHandler { /** * Checks if the input can be handled by this class. * If it cannot handle the input, rejects with an error explaining why. + * * @param input - Input that could potentially be handled. * * @returns A promise resolving if the input can be handled, rejecting with an Error if not. @@ -21,6 +22,7 @@ export abstract class AsyncHandler { /** * Handles the given input. This may only be called if {@link canHandle} did not reject. * When unconditionally calling both in sequence, consider {@link handleSafe} instead. + * * @param input - Input that needs to be handled. * * @returns A promise resolving when handling is finished. @@ -31,6 +33,7 @@ export abstract class AsyncHandler { * Helper function that first runs {@link canHandle} followed by {@link handle}. * Throws the error of {@link canHandle} if the data cannot be handled, * or returns the result of {@link handle} otherwise. + * * @param input - Input data that will be handled if it can be handled. * * @returns A promise resolving if the input can be handled, rejecting with an Error if not. diff --git a/src/util/handlers/BooleanHandler.ts b/src/util/handlers/BooleanHandler.ts index 010d71a9e..acc5cffd1 100644 --- a/src/util/handlers/BooleanHandler.ts +++ b/src/util/handlers/BooleanHandler.ts @@ -15,6 +15,7 @@ export class BooleanHandler extends AsyncHandler { /** * Creates a new BooleanHandler that stores the given handlers. + * * @param handlers - Handlers over which it will run. */ public constructor(handlers: AsyncHandler[]) { diff --git a/src/util/handlers/ProcessHandler.ts b/src/util/handlers/ProcessHandler.ts index 2711ee4e3..43dc90e12 100644 --- a/src/util/handlers/ProcessHandler.ts +++ b/src/util/handlers/ProcessHandler.ts @@ -14,6 +14,7 @@ export class ProcessHandler extends AsyncHandler { /** * Creates a new ProcessHandler + * * @param source - The wrapped handler * @param clusterManager - The ClusterManager in use * @param executeOnPrimary - Whether to execute the source handler when the process is the _primary_ or a _worker_. diff --git a/src/util/handlers/WaterfallHandler.ts b/src/util/handlers/WaterfallHandler.ts index b3ef570b6..e0973c468 100644 --- a/src/util/handlers/WaterfallHandler.ts +++ b/src/util/handlers/WaterfallHandler.ts @@ -16,6 +16,7 @@ export class WaterfallHandler implements AsyncHandler { /** * Creates a new WaterfallHandler that stores the given handlers. + * * @param handlers - Handlers over which it will run. */ public constructor(handlers: AsyncHandler[]) { @@ -24,6 +25,7 @@ export class WaterfallHandler implements AsyncHandler { /** * Checks if any of the stored handlers can handle the given input. + * * @param input - The data that would need to be handled. * * @returns A promise resolving if at least 1 handler supports to input, or rejecting if none do. @@ -34,6 +36,7 @@ export class WaterfallHandler implements AsyncHandler { /** * Finds a handler that supports the given input and then lets it handle the given data. + * * @param input - The data that needs to be handled. * * @returns A promise corresponding to the handle call of a handler that supports the input. @@ -55,6 +58,7 @@ export class WaterfallHandler implements AsyncHandler { /** * Identical to {@link AsyncHandler.handleSafe} but optimized for composite * by only needing 1 canHandle call on members. + * * @param input - The input data. * * @returns A promise corresponding to the handle call of a handler that supports the input. diff --git a/src/util/locking/BaseReadWriteLocker.ts b/src/util/locking/BaseReadWriteLocker.ts index 5746f00fd..1f907a6c4 100644 --- a/src/util/locking/BaseReadWriteLocker.ts +++ b/src/util/locking/BaseReadWriteLocker.ts @@ -88,6 +88,7 @@ export abstract class BaseReadWriteLocker extends EqualReadWriteLocker { /** * Update the counter that keeps track of having open read locks there currently are. + * * @param identifier - Identifier on which to update the number of read locks. * @param mod - `+1` or `-1`. */ diff --git a/src/util/locking/EqualReadWriteLocker.ts b/src/util/locking/EqualReadWriteLocker.ts index 77e96c852..176efaa31 100644 --- a/src/util/locking/EqualReadWriteLocker.ts +++ b/src/util/locking/EqualReadWriteLocker.ts @@ -24,6 +24,7 @@ export class EqualReadWriteLocker implements ReadWriteLocker { /** * Acquires a new lock for the requested identifier. * Will resolve when the input function resolves. + * * @param identifier - Identifier of resource that needs to be locked. * @param whileLocked - Function to resolve while the resource is locked. */ diff --git a/src/util/locking/FileSystemResourceLocker.ts b/src/util/locking/FileSystemResourceLocker.ts index 2a738f41b..3173ba8cc 100644 --- a/src/util/locking/FileSystemResourceLocker.ts +++ b/src/util/locking/FileSystemResourceLocker.ts @@ -71,6 +71,7 @@ export class FileSystemResourceLocker implements ResourceLocker, Initializable, /** * Create a new FileSystemResourceLocker + * * @param args - Configures the locker using the specified FileSystemResourceLockerArgs instance. */ public constructor(args: FileSystemResourceLockerArgs) { @@ -85,7 +86,9 @@ export class FileSystemResourceLocker implements ResourceLocker, Initializable, * Wrapper function for all (un)lock operations. Any errors coming from the `fn()` will be swallowed. * Only `ENOTACQUIRED` errors wills be thrown (trying to release lock that didn't exist). * This wrapper returns undefined because {@link retryFunction} expects that when a retry needs to happen. + * * @param fn - The function reference to swallow errors from. + * * @returns Boolean or undefined. */ private swallowErrors(fn: () => Promise): () => Promise { @@ -138,7 +141,9 @@ export class FileSystemResourceLocker implements ResourceLocker, Initializable, /** * Map the identifier path to a unique path inside the {@link lockFolder}. + * * @param identifier - ResourceIdentifier to generate (Un)LockOptions for. + * * @returns Full path. */ private toLockfilePath(identifier: ResourceIdentifier): string { @@ -150,8 +155,10 @@ export class FileSystemResourceLocker implements ResourceLocker, Initializable, /** * Generate LockOptions or UnlockOptions depending on the type of defauls given. * A custom lockFilePath mapping strategy will be used. + * * @param identifier - ResourceIdentifier to generate (Un)LockOptions for * @param defaults - The default options. (lockFilePath will get overwritten) + * * @returns LockOptions or UnlockOptions */ private generateOptions(identifier: ResourceIdentifier, defaults: T): T { diff --git a/src/util/locking/RedisLocker.ts b/src/util/locking/RedisLocker.ts index 78176318e..377f30b8e 100644 --- a/src/util/locking/RedisLocker.ts +++ b/src/util/locking/RedisLocker.ts @@ -67,6 +67,7 @@ export class RedisLocker implements ReadWriteLocker, ResourceLocker, Initializab /** * Creates a new RedisClient + * * @param redisClient - Redis connection string of a standalone Redis node * @param attemptSettings - Override default AttemptSettings * @param redisSettings - Addition settings used to create the Redis client or to interact with the Redis server @@ -93,6 +94,7 @@ export class RedisLocker implements ReadWriteLocker, ResourceLocker, Initializab /** * Generate and return a RedisClient based on the provided string + * * @param redisClientString - A string that contains either a host address and a * port number like '127.0.0.1:6379' or just a port number like '6379'. */ @@ -116,7 +118,9 @@ export class RedisLocker implements ReadWriteLocker, ResourceLocker, Initializab /** * Create a scoped Redis key for Read-Write locking. + * * @param identifier - The identifier object to create a Redis key for + * * @returns A scoped Redis key that allows cleanup afterwards without affecting other keys. */ private getReadWriteKey(identifier: ResourceIdentifier): string { @@ -125,7 +129,9 @@ export class RedisLocker implements ReadWriteLocker, ResourceLocker, Initializab /** * Create a scoped Redis key for Resource locking. + * * @param identifier - The identifier object to create a Redis key for + * * @returns A scoped Redis key that allows cleanup afterwards without affecting other keys. */ private getResourceKey(identifier: ResourceIdentifier): string { @@ -138,6 +144,7 @@ export class RedisLocker implements ReadWriteLocker, ResourceLocker, Initializab * Wrapper function for all (un)lock operations. If the `fn()` resolves to false (after applying * {@link fromResp2ToBool}, the result will be swallowed. When `fn()` resolves to true, this wrapper * will return true. Any error coming from `fn()` will be thrown. + * * @param fn - The function reference to swallow false from. */ private swallowFalse(fn: () => Promise): () => Promise { diff --git a/src/util/locking/ResourceLocker.ts b/src/util/locking/ResourceLocker.ts index eb2fd8325..575200ab7 100644 --- a/src/util/locking/ResourceLocker.ts +++ b/src/util/locking/ResourceLocker.ts @@ -9,6 +9,7 @@ export interface ResourceLocker { /** * Acquires a lock on the requested identifier. * The promise will resolve when the lock has been acquired. + * * @param identifier - Resource to acquire a lock on. */ acquire: (identifier: ResourceIdentifier) => Promise; @@ -17,6 +18,7 @@ export interface ResourceLocker { * Releases a lock on the requested identifier. * The promise will resolve when the lock has been released. * In case there is no lock on the resource an error should be thrown. + * * @param identifier - Resource to release the lock on. */ release: (identifier: ResourceIdentifier) => Promise; diff --git a/src/util/locking/scripts/RedisLuaScripts.ts b/src/util/locking/scripts/RedisLuaScripts.ts index 1a99566b4..ccab3ff89 100644 --- a/src/util/locking/scripts/RedisLuaScripts.ts +++ b/src/util/locking/scripts/RedisLuaScripts.ts @@ -79,10 +79,13 @@ export type RedisAnswer = 0 | 1 | null | 'OK' | string; /** * Convert a RESP2 response to a boolean. + * * @param result - The Promise-wrapped result of a RESP2 Redis function. + * * @returns * `1`, `'OK'`: return `true` * * `0`: returns `false` * * `-ERR`: throw error + * * @throws On `-ERR*` `null` or any other value */ export async function fromResp2ToBool(result: Promise): Promise { @@ -123,12 +126,14 @@ export interface RedisReadWriteLock extends Redis { /** * Release readLock. This means decrementing the read counter with 1. + * * @returns 1 if succeeded. '-ERR' if read count goes below 0 */ releaseReadLock: (resourceIdentifierPath: string, callback?: Callback) => Promise; /** * Release writeLock. This means deleting the write lock. + * * @returns 1 if succeeded. '-ERR' if write lock was non-existing. */ releaseWriteLock: (resourceIdentifierPath: string, callback?: Callback) => Promise; @@ -145,6 +150,7 @@ export interface RedisResourceLock extends Redis { /** * Release lock. This means deleting the lock. + * * @returns 1 if succeeded. '-ERR' if lock was non-existing. */ releaseLock: (resourceIdentifierPath: string, callback?: Callback) => Promise; diff --git a/templates/scripts/util.js b/templates/scripts/util.js index f55e7716f..36b8d2172 100644 --- a/templates/scripts/util.js +++ b/templates/scripts/util.js @@ -71,6 +71,7 @@ function addPostListener(callback, formId = 'mainForm', errorId = 'error') { /** * Shows or hides the given element. + * * @param id - ID of the element. * @param visible - If it should be visible. */ @@ -88,6 +89,7 @@ function setVisibility(id, visible) { /** * Obtains all children, grandchildren, etc. of the given element. + * * @param element - Element to get all descendants from. */ function getDescendants(element) { @@ -96,6 +98,7 @@ function getDescendants(element) { /** * Updates the inner text and href field of an element. + * * @param id - ID of the element. * @param text - Text to put in the field(s). If this is undefined, instead the element will be hidden. * @param options - Indicates which fields should be updated. @@ -117,6 +120,7 @@ function updateElement(id, text, options) { /** * Fetches JSON from the url and converts it to an object. + * * @param url - URL to fetch JSON from. * @param redirectUrl - URL to redirect to in case the response code is >= 400. No redirect happens if undefined. */ @@ -159,6 +163,7 @@ function setError(message, errorId = 'error') { /** * Causes the page to redirect to a specific page when a button is clicked. + * * @param element - The id of the button. * @param url - The URL to redirect to. */ diff --git a/test/deploy/createAccountCredentials.ts b/test/deploy/createAccountCredentials.ts index 4e8949088..769c6c03f 100644 --- a/test/deploy/createAccountCredentials.ts +++ b/test/deploy/createAccountCredentials.ts @@ -29,6 +29,7 @@ const bob: User = { /** * Registers a user with the server and provides them with a pod. + * * @param user - The user settings necessary to register a user. */ async function register(user: User): Promise<{ webId: string; authorization: string }> { @@ -78,8 +79,10 @@ async function register(user: User): Promise<{ webId: string; authorization: str /** * Requests a client credentials API token. + * * @param webId - WebID to create credentials for. * @param authorization - Authorization header for the account that tries to create credentials. + * * @returns The id/secret for the client credentials request. */ async function createCredentials(webId: string, authorization: string): Promise<{ id: string; secret: string }> { @@ -104,6 +107,7 @@ async function createCredentials(webId: string, authorization: string): Promise< * Generates all the necessary data and outputs the necessary lines * that need to be added to the CTH environment file * so it can use client credentials. + * * @param user - User for which data needs to be generated. */ async function outputCredentials(user: User): Promise { diff --git a/test/integration/IdentityTestState.ts b/test/integration/IdentityTestState.ts index bd9439e1e..f320a9013 100644 --- a/test/integration/IdentityTestState.ts +++ b/test/integration/IdentityTestState.ts @@ -28,6 +28,7 @@ export class IdentityTestState { /** * Performs a fetch call while keeping track of the stored cookies and preventing redirects. + * * @param url - URL to call. * @param method - Method to use. * @param body - Body to send along. If this is not a string it will be JSONified. diff --git a/test/util/AccountUtil.ts b/test/util/AccountUtil.ts index aab8c1547..b683305b5 100644 --- a/test/util/AccountUtil.ts +++ b/test/util/AccountUtil.ts @@ -10,6 +10,7 @@ export type User = { /** * Registers an account for the given user details and creates one or more pods. + * * @param baseUrl - Base URL of the server. * @param user - User details to register. */ diff --git a/test/util/NotificationUtil.ts b/test/util/NotificationUtil.ts index cfafc2651..30dea393b 100644 --- a/test/util/NotificationUtil.ts +++ b/test/util/NotificationUtil.ts @@ -2,6 +2,7 @@ import { fetch } from 'cross-fetch'; /** * Subscribes to a notification channel. + * * @param type - The type of the notification channel, e.g., "NOTIFY.WebhookChannel2023". * @param webId - The WebID to spoof in the authorization header. This assumes the config uses the debug auth import. * @param subscriptionUrl - The subscription URL to which the request needs to be sent. @@ -36,6 +37,7 @@ export async function subscribe( /** * Verifies if a notification has the expected format. + * * @param notification - The (parsed) notification. * @param topic - The topic of the notification. * @param type - What type of notification is expected. From fa060b86f370d57fbef4037594e8b91782dc458f Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Thu, 14 Mar 2024 11:29:17 +0100 Subject: [PATCH 30/71] refactor: Remove eslint-disable when possible --- .../interaction/account/util/AccountStore.ts | 5 ++-- .../account/util/BaseLoginAccountStorage.ts | 2 +- src/init/AppRunner.ts | 2 +- src/init/cli/YargsCliExtractor.ts | 5 ++-- src/init/migration/V6MigrationInitializer.ts | 3 ++- src/server/HandlerServerConfigurator.ts | 5 ++-- src/storage/keyvalue/IndexedStorage.ts | 25 +++++++++---------- src/storage/keyvalue/WrappedIndexedStorage.ts | 13 +++++----- src/storage/quota/QuotaStrategy.ts | 2 +- src/util/errors/ErrorUtil.ts | 3 +-- src/util/handlers/StaticHandler.ts | 4 +-- test/integration/V6Migration.test.ts | 4 +-- 12 files changed, 35 insertions(+), 38 deletions(-) diff --git a/src/identity/interaction/account/util/AccountStore.ts b/src/identity/interaction/account/util/AccountStore.ts index d5cc94bd1..6582f1294 100644 --- a/src/identity/interaction/account/util/AccountStore.ts +++ b/src/identity/interaction/account/util/AccountStore.ts @@ -5,7 +5,6 @@ export const ACCOUNT_SETTINGS_REMEMBER_LOGIN = 'rememberLogin'; export type AccountSettings = { [ACCOUNT_SETTINGS_REMEMBER_LOGIN]?: boolean }; -/* eslint-disable ts/method-signature-style */ /** * Used to store account data. */ @@ -24,7 +23,7 @@ export interface AccountStore { * @param id - The account identifier. * @param setting - The setting to find the value of. */ - getSetting(id: string, setting: T): Promise; + getSetting: (id: string, setting: T) => Promise; /** * Updates the settings for the account with the given identifier to the new values. @@ -33,5 +32,5 @@ export interface AccountStore { * @param setting - The setting to update. * @param value - The new value for the setting. */ - updateSetting(id: string, setting: T, value: AccountSettings[T]): Promise; + updateSetting: (id: string, setting: T, value: AccountSettings[T]) => Promise; } diff --git a/src/identity/interaction/account/util/BaseLoginAccountStorage.ts b/src/identity/interaction/account/util/BaseLoginAccountStorage.ts index fbfbd4c94..f33452ff3 100644 --- a/src/identity/interaction/account/util/BaseLoginAccountStorage.ts +++ b/src/identity/interaction/account/util/BaseLoginAccountStorage.ts @@ -61,7 +61,7 @@ export class BaseLoginAccountStorage> implement return this.storage.defineType(type, description); } - public async createIndex>(type: TType, key: StringKey): Promise { + public async createIndex>(type: TType, key: StringKey): Promise { return this.storage.createIndex(type, key); } diff --git a/src/init/AppRunner.ts b/src/init/AppRunner.ts index d3b1ebd77..ed5bca6ba 100644 --- a/src/init/AppRunner.ts +++ b/src/init/AppRunner.ts @@ -1,4 +1,3 @@ -/* eslint-disable unicorn/no-process-exit */ import { existsSync } from 'node:fs'; import type { WriteStream } from 'node:tty'; import type { IComponentsManagerBuilderOptions } from 'componentsjs'; @@ -145,6 +144,7 @@ export class AppRunner { public runCliSync({ argv, stderr = process.stderr }: { argv?: CliArgv; stderr?: WriteStream }): void { this.runCli(argv).catch((error): never => { stderr.write(createErrorMessage(error)); + // eslint-disable-next-line unicorn/no-process-exit process.exit(1); }); } diff --git a/src/init/cli/YargsCliExtractor.ts b/src/init/cli/YargsCliExtractor.ts index 5b8922701..08c0d61af 100644 --- a/src/init/cli/YargsCliExtractor.ts +++ b/src/init/cli/YargsCliExtractor.ts @@ -76,8 +76,9 @@ export class YargsCliExtractor extends CliExtractor { yArgv.check((args): boolean => { for (const [ name, options ] of Object.entries(this.yargsArgOptions)) { if (options.type !== 'array' && Array.isArray(args[name])) { - // eslint-disable-next-line ts/restrict-template-expressions - throw new Error(`Multiple values for --${name} (-${options.alias}) were provided where only one is allowed`); + throw new Error( + `Multiple values for --${name} (-${options.alias as string}) were provided where only one is allowed`, + ); } } return true; diff --git a/src/init/migration/V6MigrationInitializer.ts b/src/init/migration/V6MigrationInitializer.ts index a6da3e52f..cff64ed34 100644 --- a/src/init/migration/V6MigrationInitializer.ts +++ b/src/init/migration/V6MigrationInitializer.ts @@ -68,7 +68,8 @@ export interface V6MigrationInitializerArgs { /** * Storages for which all entries need to be removed. */ - cleanupStorages: KeyValueStorage[]; + // eslint-disable-next-line ts/no-explicit-any + cleanupStorages: KeyValueStorage[]; /** * The storage that will contain the account data in the new format. * Wrong typings to prevent Components.js typing issues. diff --git a/src/server/HandlerServerConfigurator.ts b/src/server/HandlerServerConfigurator.ts index 08c67f983..d46596bef 100644 --- a/src/server/HandlerServerConfigurator.ts +++ b/src/server/HandlerServerConfigurator.ts @@ -61,10 +61,9 @@ export class HandlerServerConfigurator extends ServerConfigurator { */ private createErrorMessage(error: unknown): string { if (!isError(error)) { - // eslint-disable-next-line ts/restrict-template-expressions - return `Unknown error: ${error}.\n`; + return `Unknown error: ${error as string}.\n`; } - if (this.showStackTrace && error.stack) { + if (this.showStackTrace && isError(error) && error.stack) { return `${error.stack}\n`; } return `${error.name}: ${error.message}\n`; diff --git a/src/storage/keyvalue/IndexedStorage.ts b/src/storage/keyvalue/IndexedStorage.ts index 9ecff8c1a..0388f5cbd 100644 --- a/src/storage/keyvalue/IndexedStorage.ts +++ b/src/storage/keyvalue/IndexedStorage.ts @@ -86,7 +86,6 @@ export type IndexedQuery, TType extends keyof T (T[TType][K] extends `${typeof INDEX_ID_KEY}:${infer U}` ? IndexedQuery : never) }; -/* eslint-disable ts/method-signature-style */ /** * A storage solution that allows for more complex queries than a key/value storage * and allows setting indexes on specific keys. @@ -101,7 +100,7 @@ export interface IndexedStorage> { * @param type - The type to define. * @param description - A description of the values stored in objects of that type. */ - defineType>(type: TType, description: T[TType]): Promise; + defineType: >(type: TType, description: T[TType]) => Promise; /** * Creates an index on a key of the given type, to allow for better queries involving those keys. @@ -110,7 +109,7 @@ export interface IndexedStorage> { * @param type - The type to create an index on. * @param key - The key of that type to create an index on. */ - createIndex>(type: TType, key: StringKey): Promise; + createIndex: >(type: TType, key: StringKey) => Promise; /** * Creates an object of the given type. @@ -121,7 +120,7 @@ export interface IndexedStorage> { * * @returns A representation of the newly created object, including its new identifier. */ - create>(type: TType, value: CreateTypeObject): Promise>; + create: >(type: TType, value: CreateTypeObject) => Promise>; /** * Returns `true` if the object of the given type with the given identifier exists. @@ -131,7 +130,7 @@ export interface IndexedStorage> { * * @returns Whether this object exists. */ - has>(type: TType, id: string): Promise; + has: >(type: TType, id: string) => Promise; /** * Returns the object of the given type with the given identifier. @@ -141,7 +140,7 @@ export interface IndexedStorage> { * * @returns A representation of the object, or `undefined` if there is no object of that type with that identifier. */ - get>(type: TType, id: string): Promise | undefined>; + get: >(type: TType, id: string) => Promise | undefined>; /** * Finds all objects matching a specific {@link IndexedQuery}. @@ -151,7 +150,7 @@ export interface IndexedStorage> { * * @returns A list of objects matching the query. */ - find>(type: TType, query: IndexedQuery): Promise<(TypeObject)[]>; + find: >(type: TType, query: IndexedQuery) => Promise<(TypeObject)[]>; /** * Similar to {@link IndexedStorage.find}, but only returns the identifiers of the found objects. @@ -161,7 +160,7 @@ export interface IndexedStorage> { * * @returns A list of identifiers of the matching objects. */ - findIds>(type: TType, query: IndexedQuery): Promise; + findIds: >(type: TType, query: IndexedQuery) => Promise; /** * Sets the value of a specific object. @@ -170,7 +169,7 @@ export interface IndexedStorage> { * @param type - The type of the object to set. * @param value - The new value for the object. */ - set>(type: TType, value: TypeObject): Promise; + set: >(type: TType, value: TypeObject) => Promise; /** * Sets the value of one specific field in an object. @@ -180,8 +179,8 @@ export interface IndexedStorage> { * @param key - The key to update. * @param value - The new value for the given key. */ - setField, TKey extends StringKey>( - type: TType, id: string, key: TKey, value: ValueType): Promise; + setField: , TKey extends StringKey>( + type: TType, id: string, key: TKey, value: ValueType) => Promise; /** * Deletes the given object. @@ -190,12 +189,12 @@ export interface IndexedStorage> { * @param type - The type of the object to delete. * @param id - The identifier of the object. */ - delete>(type: TType, id: string): Promise; + delete: >(type: TType, id: string) => Promise; /** * Returns an iterator over all objects of the given type. * * @param type - The type to iterate over. */ - entries>(type: TType): AsyncIterableIterator>; + entries: >(type: TType) => AsyncIterableIterator>; } diff --git a/src/storage/keyvalue/WrappedIndexedStorage.ts b/src/storage/keyvalue/WrappedIndexedStorage.ts index 9e9130319..b2fefb47b 100644 --- a/src/storage/keyvalue/WrappedIndexedStorage.ts +++ b/src/storage/keyvalue/WrappedIndexedStorage.ts @@ -386,8 +386,9 @@ export class WrappedIndexedStorage> implements if (relation) { const objs = this.getContainingRecord(root, type, id); if (partial[relation.child.key] && objs[id][relation.child.key] !== partial[relation.child.key]) { - // eslint-disable-next-line ts/restrict-template-expressions - this.logger.error(`Trying to modify reference key ${objs[id][relation.child.key]} on "${type}" ${id}`); + this.logger.error( + `Trying to modify reference key ${objs[id][relation.child.key] as string} on "${type}" ${id}`, + ); throw new NotImplementedHttpError('Changing reference keys of existing objects is not supported.'); } oldObj = objs[id]; @@ -545,8 +546,7 @@ export class WrappedIndexedStorage> implements query: IndexedQuery, rootIds?: string[], ): Promise { - // eslint-disable-next-line ts/restrict-template-expressions - this.logger.debug(`Executing "${type}" query ${JSON.stringify(query)}. Already found roots ${rootIds}.`); + this.logger.debug(`Executing "${type}" query ${JSON.stringify(query)}. Already found roots ${rootIds?.join(',')}.`); const indexedRoots = await this.findIndexedRoots(type, query, rootIds); @@ -665,8 +665,9 @@ export class WrappedIndexedStorage> implements Promise { const indexKey = this.getIndexKey(type, key, value); const indexValues = await this.indexStorage.get(indexKey) ?? []; - // eslint-disable-next-line ts/restrict-template-expressions - this.logger.debug(`Updating index ${indexKey} by ${add ? 'adding' : 'removing'} ${rootId} from ${indexValues}`); + this.logger.debug( + `Updating index ${indexKey} by ${add ? 'adding' : 'removing'} ${rootId} from ${indexValues.join(',')}`, + ); if (add) { if (!indexValues.includes(rootId)) { diff --git a/src/storage/quota/QuotaStrategy.ts b/src/storage/quota/QuotaStrategy.ts index 07324f2f1..5fac80beb 100644 --- a/src/storage/quota/QuotaStrategy.ts +++ b/src/storage/quota/QuotaStrategy.ts @@ -1,6 +1,5 @@ // These two eslint lines are needed to store 'this' in a variable so it can be used // in the PassThrough of createQuotaGuard -/* eslint-disable ts/no-this-alias */ import { PassThrough } from 'node:stream'; import type { RepresentationMetadata } from '../../http/representation/RepresentationMetadata'; import type { ResourceIdentifier } from '../../http/representation/ResourceIdentifier'; @@ -87,6 +86,7 @@ export abstract class QuotaStrategy { */ public async createQuotaGuard(identifier: ResourceIdentifier): Promise> { let total = 0; + // eslint-disable-next-line ts/no-this-alias const that = this; const { reporter } = this; diff --git a/src/util/errors/ErrorUtil.ts b/src/util/errors/ErrorUtil.ts index 6ab51b10f..b6965e65e 100644 --- a/src/util/errors/ErrorUtil.ts +++ b/src/util/errors/ErrorUtil.ts @@ -15,6 +15,5 @@ export function isError(error: unknown): error is Error { * Creates a string representing the error message of this object. */ export function createErrorMessage(error: unknown): string { - // eslint-disable-next-line ts/restrict-template-expressions - return isError(error) ? error.message : `Unknown error: ${error}`; + return isError(error) ? error.message : `Unknown error: ${error as string}`; } diff --git a/src/util/handlers/StaticHandler.ts b/src/util/handlers/StaticHandler.ts index 5c49ca1aa..4edec30c8 100644 --- a/src/util/handlers/StaticHandler.ts +++ b/src/util/handlers/StaticHandler.ts @@ -6,8 +6,7 @@ import { AsyncHandler } from './AsyncHandler'; * * The generic type extends `any` due to Components.js requirements. */ -// eslint-disable-next-line ts/no-unnecessary-type-constraint -export class StaticHandler extends AsyncHandler { +export class StaticHandler extends AsyncHandler { private readonly value?: T; public constructor(value?: T) { @@ -16,7 +15,6 @@ export class StaticHandler extends AsyncHandler { - // eslint-disable-next-line ts/no-unnecessary-type-assertion return this.value!; } } diff --git a/test/integration/V6Migration.test.ts b/test/integration/V6Migration.test.ts index 5c2b72e4a..2d18ebdcc 100644 --- a/test/integration/V6Migration.test.ts +++ b/test/integration/V6Migration.test.ts @@ -138,8 +138,8 @@ describe('A server migrating from v6', (): void => { it('still supports the existing client credentials.', async(): Promise => { // These are the values stored in the original assets const id = 'token_fd13b73d-2527-4280-82af-278e5b8fe607'; - // eslint-disable-next-line max-len - const secret = 'a809d7ce5daf0e9acd457c91d712ff05038e4a87192e27191c837602bd4b370c633282864c133650b0e9a35b59018b064157532642f628affb2f79e81999e898'; + const secret = 'a809d7ce5daf0e9acd457c91d712ff05038e4a87192e27191c837602bd4b' + + '370c633282864c133650b0e9a35b59018b064157532642f628affb2f79e81999e898'; const tokenUrl = joinUrl(baseUrl, '.oidc/token'); const dpopHeader = await createDpopHeader(tokenUrl, 'POST', await generateDpopKeyPair()); const authString = `${encodeURIComponent(id)}:${encodeURIComponent(secret)}`; From 7abca33b67cbfef56aa8e32e11b3cba39a78d249 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Fri, 29 Mar 2024 10:18:21 +0100 Subject: [PATCH 31/71] chore: Update @antfu/eslint-config dependency to 2.11.4 --- .../features/accounts/controls.md | 2 +- .../features/accounts/overview.md | 6 +- .../architecture/features/initialization.md | 6 +- .../architecture/features/notifications.md | 6 +- .../features/protocol/patching.md | 6 +- .../markdown/usage/client-credentials.md | 2 +- eslint.config.js | 6 + eslint/unicorn.js | 4 + package-lock.json | 3151 ++++++++++++----- package.json | 2 +- .../representation/RepresentationMetadata.ts | 2 +- src/storage/mapping/ExtensionBasedMapper.ts | 2 +- src/util/GuardedStream.ts | 2 +- src/util/errors/ErrorUtil.ts | 4 +- src/util/errors/HttpError.ts | 2 +- .../util/RedirectingHttpHandler.test.ts | 2 +- test/unit/server/util/RouterHandler.test.ts | 2 +- test/unit/util/PathUtil.test.ts | 2 +- 18 files changed, 2353 insertions(+), 856 deletions(-) diff --git a/documentation/markdown/architecture/features/accounts/controls.md b/documentation/markdown/architecture/features/accounts/controls.md index 62eaafa6c..564d0d288 100644 --- a/documentation/markdown/architecture/features/accounts/controls.md +++ b/documentation/markdown/architecture/features/accounts/controls.md @@ -17,7 +17,7 @@ flowchart LR ControlHandler --password--> PasswordControlHandler("PasswordControlHandler
ControlHandler") ControlHandler --"oidc"--> OidcControlHandler("OidcControlHandler
OidcControlHandler") ControlHandler --html--> HtmlControlHandler("HtmlControlHandler
ControlHandler") - + HtmlControlHandler --main--> MainHtmlControlHandler("MainHtmlControlHandler
ControlHandler") HtmlControlHandler --account--> AccountHtmlControlHandler("AccountHtmlControlHandler
ControlHandler") HtmlControlHandler --password--> PasswordHtmlControlHandler("PasswordHtmlControlHandler
ControlHandler") diff --git a/documentation/markdown/architecture/features/accounts/overview.md b/documentation/markdown/architecture/features/accounts/overview.md index f0e3f99b1..6ef7dd46d 100644 --- a/documentation/markdown/architecture/features/accounts/overview.md +++ b/documentation/markdown/architecture/features/accounts/overview.md @@ -10,7 +10,7 @@ flowchart LR Handler("IdentityProviderHandler
RouterHandler") ParsingHandler("IdentityProviderParsingHandler
AuthorizingHttpHandler") AuthorizingHandler("IdentityProviderAuthorizingHandler
AuthorizingHttpHandler") - + Handler --> ParsingHandler ParsingHandler --> AuthorizingHandler AuthorizingHandler --> HttpHandler("IdentityProviderHttpHandler
IdentityProviderHttpHandler") @@ -26,12 +26,12 @@ flowchart TD HttpHandler("IdentityProviderHttpHandler
IdentityProviderHttpHandler") HttpHandler --> InteractionHandler("InteractionHandler
WaterfallHandler") InteractionHandler --> InteractionHandlerArgs - + subgraph InteractionHandlerArgs[" "] HtmlViewHandler("HtmlViewHandler
HtmlViewHandler") LockingInteractionHandler("LockingInteractionHandler
LockingInteractionHandler") end - + LockingInteractionHandler --> JsonConversionHandler("JsonConversionHandler
JsonConversionHandler") JsonConversionHandler --> VersionHandler("VersionHandler
VersionHandler") VersionHandler --> CookieInteractionHandler("CookieInteractionHandler
CookieInteractionHandler") diff --git a/documentation/markdown/architecture/features/initialization.md b/documentation/markdown/architecture/features/initialization.md index f5bb8f8e7..6ba829f80 100644 --- a/documentation/markdown/architecture/features/initialization.md +++ b/documentation/markdown/architecture/features/initialization.md @@ -114,15 +114,15 @@ It takes as input 2 components: a `HttpServerFactory` and a `ServerListener`. flowchart TD ServerInitializer("ServerInitializer
ServerInitializer") ServerInitializer --> ServerInitializerArgs - + subgraph ServerInitializerArgs[" "] direction LR ServerFactory("ServerFactory
BaseServerFactory") ServerListener("ServerListener
ParallelHandler") end - + ServerListener --> HandlerServerListener("HandlerServerListener
HandlerServerListener") - + HandlerServerListener --> HttpHandler("HttpHandler
HttpHandler") ``` diff --git a/documentation/markdown/architecture/features/notifications.md b/documentation/markdown/architecture/features/notifications.md index 431cd5caa..1e20d0695 100644 --- a/documentation/markdown/architecture/features/notifications.md +++ b/documentation/markdown/architecture/features/notifications.md @@ -78,7 +78,7 @@ flowchart TB ResourceStore("ResourceStore
ActivityEmitter") NotificationHandler("NotificationHandler
WaterfallHandler") end - + NotificationHandler --> NotificationHandlerArgs subgraph NotificationHandlerArgs[" "] direction TB @@ -154,9 +154,9 @@ flowchart TB NotificationChannelStorage("NotificationChannelStorage
NotificationChannelStorage") SequenceHandler("
SequenceHandler") end - + SequenceHandler --> SequenceHandlerArgs - + subgraph SequenceHandlerArgs[" "] direction TB WebSocket2023Storer("WebSocket2023Storer
WebSocket2023Storer") diff --git a/documentation/markdown/architecture/features/protocol/patching.md b/documentation/markdown/architecture/features/protocol/patching.md index 6d36adafc..a389d6e25 100644 --- a/documentation/markdown/architecture/features/protocol/patching.md +++ b/documentation/markdown/architecture/features/protocol/patching.md @@ -27,15 +27,15 @@ flowchart LR RdfPatcher("RdfPatcher
RdfPatcher") RdfPatcher --> RDFStore("PatchHandler_RDFStore
WaterfallHandler") RDFStore --> RDFStoreArgs - + subgraph RDFStoreArgs[" "] Immutable("PatchHandler_ImmutableMetadata
ImmutableMetadataPatcher") RDF("PatchHandler_RDF
WaterfallHandler") Immutable --> RDF end - + RDF --> RDFArgs - + subgraph RDFArgs[" "] direction LR N3("
N3Patcher") diff --git a/documentation/markdown/usage/client-credentials.md b/documentation/markdown/usage/client-credentials.md index 4e7561b05..eb12a2f57 100644 --- a/documentation/markdown/usage/client-credentials.md +++ b/documentation/markdown/usage/client-credentials.md @@ -56,7 +56,7 @@ The next step generates the token and assumes you have an authorization value as ```ts // Now that we are logged in, we need to request the updated controls from the server. // These will now have more values than in the previous example. -const indexResponse = await fetch('http://localhost:3000/.account/', { +const indexResponse = await fetch('http://localhost:3000/.account/', { headers: { authorization: `CSS-Account-Token ${authorization}` } }); const { controls } = await indexResponse.json(); diff --git a/eslint.config.js b/eslint.config.js index dc2d3ed7b..1952bfbbf 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -42,4 +42,10 @@ module.exports = antfu.default( 'unicorn/filename-case': 'off', }, }, + { + files: [ '**/*.md' ], + rules: { + 'no-irregular-whitespace': 'off', + }, + }, ); diff --git a/eslint/unicorn.js b/eslint/unicorn.js index 337464d7f..7ccb36155 100644 --- a/eslint/unicorn.js +++ b/eslint/unicorn.js @@ -16,6 +16,10 @@ module.exports = { kebabCase: true, snakeCase: false, }, + ignore: [ + // CODE_OF_CONDUCT.md, etc. + /[A-Z_]+\.md$/u, + ], }], 'unicorn/new-for-builtins': 'error', 'unicorn/no-array-for-each': 'error', diff --git a/package-lock.json b/package-lock.json index 47ff48ea2..c4c23023d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -82,7 +82,7 @@ "community-solid-server": "bin/server.js" }, "devDependencies": { - "@antfu/eslint-config": "2.3.4", + "@antfu/eslint-config": "2.11.4", "@commitlint/cli": "^17.7.2", "@commitlint/config-conventional": "^17.7.0", "@inrupt/solid-client-authn-core": "^2.0.0", @@ -137,41 +137,42 @@ } }, "node_modules/@antfu/eslint-config": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/@antfu/eslint-config/-/eslint-config-2.3.4.tgz", - "integrity": "sha512-5uPgbcn88QqIALeZpZeVOwFPbMLWYpOkyV8yZZXfV45tMAb9gLcg2Zodo/L0v+bW8xFcu6l2xm5LCNmjkWERrg==", + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@antfu/eslint-config/-/eslint-config-2.11.4.tgz", + "integrity": "sha512-kQC8XFKih5igRodfDBpXIi3KFsjYuCfX2F9VK4hk79+KkDETUF/14ymai4O+Y+vmSNdRFwjtDL5YhcRoaD0rAg==", "dev": true, "dependencies": { - "@antfu/eslint-define-config": "^1.23.0-2", "@antfu/install-pkg": "^0.3.1", - "@eslint-types/jsdoc": "46.8.2-1", - "@eslint-types/typescript-eslint": "^6.12.0", - "@eslint-types/unicorn": "^49.0.0", - "@stylistic/eslint-plugin": "^1.5.0", - "@typescript-eslint/eslint-plugin": "^6.13.2", - "@typescript-eslint/parser": "^6.13.2", - "eslint-config-flat-gitignore": "^0.1.2", - "eslint-plugin-antfu": "^2.0.0", + "@clack/prompts": "^0.7.0", + "@stylistic/eslint-plugin": "^1.7.0", + "@typescript-eslint/eslint-plugin": "^7.4.0", + "@typescript-eslint/parser": "^7.4.0", + "eslint-config-flat-gitignore": "^0.1.3", + "eslint-flat-config-utils": "^0.1.1", + "eslint-merge-processors": "^0.1.0", + "eslint-plugin-antfu": "^2.1.2", "eslint-plugin-eslint-comments": "^3.2.0", - "eslint-plugin-i": "^2.29.0", - "eslint-plugin-jsdoc": "^46.9.0", - "eslint-plugin-jsonc": "^2.10.0", - "eslint-plugin-markdown": "^3.0.1", - "eslint-plugin-n": "^16.3.1", + "eslint-plugin-import-x": "^0.4.4", + "eslint-plugin-jsdoc": "^48.2.1", + "eslint-plugin-jsonc": "^2.14.1", + "eslint-plugin-markdown": "^4.0.1", + "eslint-plugin-n": "^16.6.2", "eslint-plugin-no-only-tests": "^3.1.0", - "eslint-plugin-perfectionist": "^2.5.0", - "eslint-plugin-unicorn": "^49.0.0", - "eslint-plugin-unused-imports": "^3.0.0", - "eslint-plugin-vitest": "^0.3.10", - "eslint-plugin-vue": "^9.19.2", - "eslint-plugin-yml": "^1.10.0", - "globals": "^13.23.0", + "eslint-plugin-perfectionist": "^2.7.0", + "eslint-plugin-toml": "^0.10.0", + "eslint-plugin-unicorn": "^51.0.1", + "eslint-plugin-unused-imports": "^3.1.0", + "eslint-plugin-vitest": "^0.4.0", + "eslint-plugin-vue": "^9.24.0", + "eslint-plugin-yml": "^1.13.2", + "eslint-processor-vue-blocks": "^0.1.1", + "globals": "^15.0.0", "jsonc-eslint-parser": "^2.4.0", "local-pkg": "^0.5.0", "parse-gitignore": "^2.0.0", "picocolors": "^1.0.0", - "prompts": "^2.4.2", - "vue-eslint-parser": "^9.3.2", + "toml-eslint-parser": "^0.9.3", + "vue-eslint-parser": "^9.4.2", "yaml-eslint-parser": "^1.2.2", "yargs": "^17.7.2" }, @@ -183,16 +184,28 @@ }, "peerDependencies": { "@unocss/eslint-plugin": ">=0.50.0", + "astro-eslint-parser": "^0.16.3", "eslint": ">=8.40.0", + "eslint-plugin-astro": "^0.31.4", "eslint-plugin-format": ">=0.1.0", "eslint-plugin-react": "^7.33.2", "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-react-refresh": "^0.4.4" + "eslint-plugin-react-refresh": "^0.4.4", + "eslint-plugin-svelte": "^2.35.1", + "prettier-plugin-astro": "^0.13.0", + "prettier-plugin-slidev": "^1.0.5", + "svelte-eslint-parser": "^0.33.1" }, "peerDependenciesMeta": { "@unocss/eslint-plugin": { "optional": true }, + "astro-eslint-parser": { + "optional": true + }, + "eslint-plugin-astro": { + "optional": true + }, "eslint-plugin-format": { "optional": true }, @@ -204,49 +217,233 @@ }, "eslint-plugin-react-refresh": { "optional": true - } - } - }, - "node_modules/@antfu/eslint-config/node_modules/eslint-plugin-unused-imports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-3.0.0.tgz", - "integrity": "sha512-sduiswLJfZHeeBJ+MQaG+xYzSWdRXoSw61DpU13mzWumCkR0ufD0HmO4kdNokjrkluMHpj/7PJeN35pgbhW3kw==", - "dev": true, - "dependencies": { - "eslint-rule-composer": "^0.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^6.0.0", - "eslint": "^8.0.0" - }, - "peerDependenciesMeta": { - "@typescript-eslint/eslint-plugin": { + }, + "eslint-plugin-svelte": { + "optional": true + }, + "prettier-plugin-astro": { + "optional": true + }, + "prettier-plugin-slidev": { + "optional": true + }, + "svelte-eslint-parser": { "optional": true } } }, - "node_modules/@antfu/eslint-define-config": { - "version": "1.23.0-2", - "resolved": "https://registry.npmjs.org/@antfu/eslint-define-config/-/eslint-define-config-1.23.0-2.tgz", - "integrity": "sha512-LvxY21+ZhpuBf/aHeBUtGQhSEfad4PkNKXKvDOSvukaM3XVTfBhwmHX2EKwAsdq5DlfjbT3qqYyMiueBIO5iDQ==", + "node_modules/@antfu/eslint-config/node_modules/@typescript-eslint/eslint-plugin": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.4.0.tgz", + "integrity": "sha512-yHMQ/oFaM7HZdVrVm/M2WHaNPgyuJH4WelkSVEWSSsir34kxW2kDJCxlXRhhGWEsMN0WAW/vLpKfKVcm8k+MPw==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/Shinigami92" - }, - { - "type": "paypal", - "url": "https://www.paypal.com/donate/?hosted_button_id=L7GY729FBKTZY" - } - ], + "dependencies": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "7.4.0", + "@typescript-eslint/type-utils": "7.4.0", + "@typescript-eslint/utils": "7.4.0", + "@typescript-eslint/visitor-keys": "7.4.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, "engines": { - "node": ">=18.0.0", - "npm": ">=9.0.0", - "pnpm": ">= 8.6.0" + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@antfu/eslint-config/node_modules/@typescript-eslint/parser": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.4.0.tgz", + "integrity": "sha512-ZvKHxHLusweEUVwrGRXXUVzFgnWhigo4JurEj0dGF1tbcGh6buL+ejDdjxOQxv6ytcY1uhun1p2sm8iWStlgLQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "7.4.0", + "@typescript-eslint/types": "7.4.0", + "@typescript-eslint/typescript-estree": "7.4.0", + "@typescript-eslint/visitor-keys": "7.4.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@antfu/eslint-config/node_modules/@typescript-eslint/scope-manager": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.4.0.tgz", + "integrity": "sha512-68VqENG5HK27ypafqLVs8qO+RkNc7TezCduYrx8YJpXq2QGZ30vmNZGJJJC48+MVn4G2dCV8m5ZTVnzRexTVtw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.4.0", + "@typescript-eslint/visitor-keys": "7.4.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@antfu/eslint-config/node_modules/@typescript-eslint/type-utils": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.4.0.tgz", + "integrity": "sha512-247ETeHgr9WTRMqHbbQdzwzhuyaJ8dPTuyuUEMANqzMRB1rj/9qFIuIXK7l0FX9i9FXbHeBQl/4uz6mYuCE7Aw==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "7.4.0", + "@typescript-eslint/utils": "7.4.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@antfu/eslint-config/node_modules/@typescript-eslint/types": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.4.0.tgz", + "integrity": "sha512-mjQopsbffzJskos5B4HmbsadSJQWaRK0UxqQ7GuNA9Ga4bEKeiO6b2DnB6cM6bpc8lemaPseh0H9B/wyg+J7rw==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@antfu/eslint-config/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.4.0.tgz", + "integrity": "sha512-A99j5AYoME/UBQ1ucEbbMEmGkN7SE0BvZFreSnTd1luq7yulcHdyGamZKizU7canpGDWGJ+Q6ZA9SyQobipePg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.4.0", + "@typescript-eslint/visitor-keys": "7.4.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@antfu/eslint-config/node_modules/@typescript-eslint/utils": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.4.0.tgz", + "integrity": "sha512-NQt9QLM4Tt8qrlBVY9lkMYzfYtNz8/6qwZg8pI3cMGlPnj6mOpRxxAm7BMJN9K0AiY+1BwJ5lVC650YJqYOuNg==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "7.4.0", + "@typescript-eslint/types": "7.4.0", + "@typescript-eslint/typescript-estree": "7.4.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/@antfu/eslint-config/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.4.0.tgz", + "integrity": "sha512-0zkC7YM0iX5Y41homUUeW1CHtZR01K3ybjM1l6QczoMuay0XKtrb93kv95AxUGwdjGr64nNqnOCwmEl616N8CA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.4.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@antfu/eslint-config/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@antfu/eslint-config/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@antfu/install-pkg": { @@ -777,9 +974,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", - "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.1.tgz", + "integrity": "sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -1057,6 +1254,43 @@ "buffer": "^6.0.3" } }, + "node_modules/@clack/core": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@clack/core/-/core-0.3.4.tgz", + "integrity": "sha512-H4hxZDXgHtWTwV3RAVenqcC4VbJZNegbBjlPvzOzCouXtS2y3sDvlO3IsbrPNWuLWPPlYVYPghQdSF64683Ldw==", + "dev": true, + "dependencies": { + "picocolors": "^1.0.0", + "sisteransi": "^1.0.5" + } + }, + "node_modules/@clack/prompts": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-0.7.0.tgz", + "integrity": "sha512-0MhX9/B4iL6Re04jPrttDm+BsP8y6mS7byuv0BvXgdXhbV5PdlsHt55dvNsuBCPZ7xq1oTAOOuotR9NFbQyMSA==", + "bundleDependencies": [ + "is-unicode-supported" + ], + "dev": true, + "dependencies": { + "@clack/core": "^0.3.3", + "is-unicode-supported": "*", + "picocolors": "^1.0.0", + "sisteransi": "^1.0.5" + } + }, + "node_modules/@clack/prompts/node_modules/is-unicode-supported": { + "version": "1.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -4091,9 +4325,9 @@ } }, "node_modules/@es-joy/jsdoccomment": { - "version": "0.41.0", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.41.0.tgz", - "integrity": "sha512-aKUhyn1QI5Ksbqcr3fFJj16p99QdjUxXAEuFst1Z47DRyoiMwivIH9MV/ARcJOCXVjPfjITciej8ZD2O/6qUmw==", + "version": "0.42.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.42.0.tgz", + "integrity": "sha512-R1w57YlVA6+YE01wch3GPYn6bCsrOV3YW/5oGGE2tmX6JcL9Nr+b5IikrjMPF+v9CV3ay+obImEdsDhovhJrzw==", "dev": true, "dependencies": { "comment-parser": "1.4.1", @@ -4137,30 +4371,11 @@ "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "node_modules/@eslint-types/jsdoc": { - "version": "46.8.2-1", - "resolved": "https://registry.npmjs.org/@eslint-types/jsdoc/-/jsdoc-46.8.2-1.tgz", - "integrity": "sha512-FwD7V0xX0jyaqj8Ul5ZY+TAAPohDfVqtbuXJNHb+OIv1aTIqZi5+Zn3F2UwQ5O3BnQd2mTduyK0+HjGx3/AMFg==", - "dev": true - }, - "node_modules/@eslint-types/typescript-eslint": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/@eslint-types/typescript-eslint/-/typescript-eslint-6.12.0.tgz", - "integrity": "sha512-N8cbOYjyFl2BFgDhDgHhTGpgiMkFg0CoITG5hdBm9ZGmcEgUvFBnHvHG7qJl3qVEmFnoKUdfSAcr7MRb2/Jxvw==", - "dev": true - }, - "node_modules/@eslint-types/unicorn": { - "version": "49.0.0", - "resolved": "https://registry.npmjs.org/@eslint-types/unicorn/-/unicorn-49.0.0.tgz", - "integrity": "sha512-NfXSZIsPFRD2fwTDZQj8SaXqS/rXjB5foxMraLovyrYGXiQK2y0780drDKYYSVbqvco29QIYoZNmnKTUkzZMvQ==", - "dev": true - }, "node_modules/@eslint/eslintrc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, - "peer": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -4183,15 +4398,28 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, - "peer": true + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/@eslint/eslintrc/node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, - "peer": true, "dependencies": { "argparse": "^2.0.1" }, @@ -4199,10 +4427,22 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@eslint/js": { - "version": "8.52.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.52.0.tgz", - "integrity": "sha512-mjZVbpaeMZludF2fsWLD0Z9gCref1Tk4i9+wddjRvpUNqqcndPkBD09N/Mapey0b3jaXbLm2kICwFv2E64QinA==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true, "peer": true, "engines": { @@ -4210,14 +4450,14 @@ } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.13", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", - "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "peer": true, "dependencies": { - "@humanwhocodes/object-schema": "^2.0.1", - "debug": "^4.1.1", + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", "minimatch": "^3.0.5" }, "engines": { @@ -4239,9 +4479,9 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", - "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", "dev": true, "peer": true }, @@ -4903,15 +5143,16 @@ } }, "node_modules/@stylistic/eslint-plugin": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-1.5.0.tgz", - "integrity": "sha512-XmlB5nxk06nlnx1/ka0l+WNqHcjnnXfDts4ZaCvrpCY/6l8lNtHwLwdCKF/UpBYNuRWI/HLWCTtQc0jjfwrfBA==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-1.7.0.tgz", + "integrity": "sha512-ThMUjGIi/jeWYNvOdjZkoLw1EOVs0tEuKXDgWvTn8uWaEz55HuPlajKxjKLpv19C+qRDbKczJfzUODfCdME53A==", "dev": true, "dependencies": { - "@stylistic/eslint-plugin-js": "1.5.0", - "@stylistic/eslint-plugin-jsx": "1.5.0", - "@stylistic/eslint-plugin-plus": "1.5.0", - "@stylistic/eslint-plugin-ts": "1.5.0" + "@stylistic/eslint-plugin-js": "1.7.0", + "@stylistic/eslint-plugin-jsx": "1.7.0", + "@stylistic/eslint-plugin-plus": "1.7.0", + "@stylistic/eslint-plugin-ts": "1.7.0", + "@types/eslint": "^8.56.2" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -4921,16 +5162,16 @@ } }, "node_modules/@stylistic/eslint-plugin-js": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-1.5.0.tgz", - "integrity": "sha512-TuGQv1bsIshkbJUInCewp4IUWy24W5RFiVNMV0quPSkuZ8gsYoqq6kLHvvaxpjxN9TvwSoOIwnhgrYKei2Tgcw==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-1.7.0.tgz", + "integrity": "sha512-PN6On/+or63FGnhhMKSQfYcWutRlzOiYlVdLM6yN7lquoBTqUJHYnl4TA4MHwiAt46X5gRxDr1+xPZ1lOLcL+Q==", "dev": true, "dependencies": { - "acorn": "^8.11.2", + "@types/eslint": "^8.56.2", + "acorn": "^8.11.3", "escape-string-regexp": "^4.0.0", "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "graphemer": "^1.4.0" + "espree": "^9.6.1" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -4940,13 +5181,15 @@ } }, "node_modules/@stylistic/eslint-plugin-jsx": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-jsx/-/eslint-plugin-jsx-1.5.0.tgz", - "integrity": "sha512-sqFdA1mS0jwovAatS8xFAiwxPbcy69S2AUjrGMxyhxaKbELPjvqbxPYJL+35ylT0xqirUlm118xZIFDooC8koQ==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-jsx/-/eslint-plugin-jsx-1.7.0.tgz", + "integrity": "sha512-BACdBwXakQvjYIST5N2WWhRbvhRsIxa/F59BiZol+0IH4FSmDXhie7v/yaxDIIA9CbfElzOmIA5nWNYTVXcnwQ==", "dev": true, "dependencies": { - "@stylistic/eslint-plugin-js": "^1.5.0", - "estraverse": "^5.3.0" + "@stylistic/eslint-plugin-js": "^1.7.0", + "@types/eslint": "^8.56.2", + "estraverse": "^5.3.0", + "picomatch": "^4.0.1" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -4964,26 +5207,39 @@ "node": ">=4.0" } }, + "node_modules/@stylistic/eslint-plugin-jsx/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/@stylistic/eslint-plugin-plus": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-plus/-/eslint-plugin-plus-1.5.0.tgz", - "integrity": "sha512-+A4qXFuM6V7x25Hj+xqfVIUbEckG+MUSvL6m83M6YtRq3d5zLW+giKKEL7eSCAw12MwnoDwPcEhqIJK6BRDR3w==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-plus/-/eslint-plugin-plus-1.7.0.tgz", + "integrity": "sha512-AabDw8sXsc70Ydx3qnbeTlRHZnIwY6UKEenBPURPhY3bfYWX+/pDpZH40HkOu94v8D0DUrocPkeeEUxl4e0JDg==", "dev": true, "dependencies": { - "@typescript-eslint/utils": "^6.13.2" + "@types/eslint": "^8.56.2", + "@typescript-eslint/utils": "^6.21.0" }, "peerDependencies": { "eslint": "*" } }, "node_modules/@stylistic/eslint-plugin-plus/node_modules/@typescript-eslint/scope-manager": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.13.2.tgz", - "integrity": "sha512-CXQA0xo7z6x13FeDYCgBkjWzNqzBn8RXaE3QVQVIUm74fWJLkJkaHmHdKStrxQllGh6Q4eUGyNpMe0b1hMkXFA==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.13.2", - "@typescript-eslint/visitor-keys": "6.13.2" + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -4994,9 +5250,9 @@ } }, "node_modules/@stylistic/eslint-plugin-plus/node_modules/@typescript-eslint/types": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.13.2.tgz", - "integrity": "sha512-7sxbQ+EMRubQc3wTfTsycgYpSujyVbI1xw+3UMRUcrhSy+pN09y/lWzeKDbvhoqcRbHdc+APLs/PWYi/cisLPg==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -5007,16 +5263,17 @@ } }, "node_modules/@stylistic/eslint-plugin-plus/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.13.2.tgz", - "integrity": "sha512-SuD8YLQv6WHnOEtKv8D6HZUzOub855cfPnPMKvdM/Bh1plv1f7Q/0iFUDLKKlxHcEstQnaUU4QZskgQq74t+3w==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.13.2", - "@typescript-eslint/visitor-keys": "6.13.2", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", + "minimatch": "9.0.3", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" }, @@ -5034,17 +5291,17 @@ } }, "node_modules/@stylistic/eslint-plugin-plus/node_modules/@typescript-eslint/utils": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.13.2.tgz", - "integrity": "sha512-b9Ptq4eAZUym4idijCRzl61oPCwwREcfDI8xGk751Vhzig5fFZR9CyzDz4Sp/nxSLBYxUPyh4QdIDqWykFhNmQ==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.13.2", - "@typescript-eslint/types": "6.13.2", - "@typescript-eslint/typescript-estree": "6.13.2", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", "semver": "^7.5.4" }, "engines": { @@ -5059,12 +5316,12 @@ } }, "node_modules/@stylistic/eslint-plugin-plus/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.13.2.tgz", - "integrity": "sha512-OGznFs0eAQXJsp+xSd6k/O1UbFi/K/L7WjqeRoFE7vadjAF9y0uppXhYNQNEqygjou782maGClOoZwPqF0Drlw==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.13.2", + "@typescript-eslint/types": "6.21.0", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -5075,15 +5332,39 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@stylistic/eslint-plugin-ts": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-ts/-/eslint-plugin-ts-1.5.0.tgz", - "integrity": "sha512-OusNGWRXnOV+ywnoXmBFoMtU6Ig/MX1bEu5Jigqmy2cIT8GRMMn7jUl/bXevkv2o66MYnC7PT1Q/3GvN7t0/eg==", + "node_modules/@stylistic/eslint-plugin-plus/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "dependencies": { - "@stylistic/eslint-plugin-js": "1.5.0", - "@typescript-eslint/utils": "^6.13.2", - "graphemer": "^1.4.0" + "balanced-match": "^1.0.0" + } + }, + "node_modules/@stylistic/eslint-plugin-plus/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@stylistic/eslint-plugin-ts": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-ts/-/eslint-plugin-ts-1.7.0.tgz", + "integrity": "sha512-QsHv98mmW1xaucVYQTyLDgEpybPJ/6jPPxVBrIchntWWwj74xCWKUiw79hu+TpYj/Pbhd9rkqJYLNq3pQGYuyA==", + "dev": true, + "dependencies": { + "@stylistic/eslint-plugin-js": "1.7.0", + "@types/eslint": "^8.56.2", + "@typescript-eslint/utils": "^6.21.0" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -5093,13 +5374,13 @@ } }, "node_modules/@stylistic/eslint-plugin-ts/node_modules/@typescript-eslint/scope-manager": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.13.2.tgz", - "integrity": "sha512-CXQA0xo7z6x13FeDYCgBkjWzNqzBn8RXaE3QVQVIUm74fWJLkJkaHmHdKStrxQllGh6Q4eUGyNpMe0b1hMkXFA==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.13.2", - "@typescript-eslint/visitor-keys": "6.13.2" + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -5110,9 +5391,9 @@ } }, "node_modules/@stylistic/eslint-plugin-ts/node_modules/@typescript-eslint/types": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.13.2.tgz", - "integrity": "sha512-7sxbQ+EMRubQc3wTfTsycgYpSujyVbI1xw+3UMRUcrhSy+pN09y/lWzeKDbvhoqcRbHdc+APLs/PWYi/cisLPg==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -5123,16 +5404,17 @@ } }, "node_modules/@stylistic/eslint-plugin-ts/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.13.2.tgz", - "integrity": "sha512-SuD8YLQv6WHnOEtKv8D6HZUzOub855cfPnPMKvdM/Bh1plv1f7Q/0iFUDLKKlxHcEstQnaUU4QZskgQq74t+3w==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.13.2", - "@typescript-eslint/visitor-keys": "6.13.2", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", + "minimatch": "9.0.3", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" }, @@ -5150,17 +5432,17 @@ } }, "node_modules/@stylistic/eslint-plugin-ts/node_modules/@typescript-eslint/utils": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.13.2.tgz", - "integrity": "sha512-b9Ptq4eAZUym4idijCRzl61oPCwwREcfDI8xGk751Vhzig5fFZR9CyzDz4Sp/nxSLBYxUPyh4QdIDqWykFhNmQ==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.13.2", - "@typescript-eslint/types": "6.13.2", - "@typescript-eslint/typescript-estree": "6.13.2", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", "semver": "^7.5.4" }, "engines": { @@ -5175,12 +5457,12 @@ } }, "node_modules/@stylistic/eslint-plugin-ts/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.13.2.tgz", - "integrity": "sha512-OGznFs0eAQXJsp+xSd6k/O1UbFi/K/L7WjqeRoFE7vadjAF9y0uppXhYNQNEqygjou782maGClOoZwPqF0Drlw==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.13.2", + "@typescript-eslint/types": "6.21.0", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -5191,6 +5473,30 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@stylistic/eslint-plugin-ts/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@stylistic/eslint-plugin-ts/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@szmarczak/http-timer": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", @@ -5364,6 +5670,22 @@ "@types/node": "*" } }, + "node_modules/@types/eslint": { + "version": "8.56.6", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.6.tgz", + "integrity": "sha512-ymwc+qb1XkjT/gfoQwxIeHZ6ixH23A+tCT2ADSA/DPVKzAjwYkTXBMCQ/f6fe4wEa85Lhp26VPeUxI7wMhAi7A==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, "node_modules/@types/express": { "version": "4.17.11", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.11.tgz", @@ -5522,9 +5844,9 @@ "dev": true }, "node_modules/@types/mdast": { - "version": "3.0.14", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.14.tgz", - "integrity": "sha512-gVZ04PGgw1qLZKsnWnyFv4ORnaJ+DXLdHTVSFbU8yX6xZ34Bjg4Q32yPkmveUP1yItXReKfB0Aknlh/3zxTKAw==", + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", "dev": true, "dependencies": { "@types/unist": "^2" @@ -5708,9 +6030,9 @@ } }, "node_modules/@types/unist": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.9.tgz", - "integrity": "sha512-zC0iXxAv1C1ERURduJueYzkzZ2zaGyc+P2c95hgkikHPr3z8EdUZOlgEQ5X0DRmwDZn+hekycQnoeiiRVrmilQ==", + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", + "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==", "dev": true }, "node_modules/@types/uritemplate": { @@ -5754,6 +6076,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.13.2.tgz", "integrity": "sha512-3+9OGAWHhk4O1LlcwLBONbdXsAhLjyCFogJY/cWy2lxdVJ2JrcTF2pTGMaLl2AE7U1l31n8Py4a8bx5DLf/0dQ==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", "@typescript-eslint/scope-manager": "6.13.2", @@ -5789,6 +6113,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.13.2.tgz", "integrity": "sha512-CXQA0xo7z6x13FeDYCgBkjWzNqzBn8RXaE3QVQVIUm74fWJLkJkaHmHdKStrxQllGh6Q4eUGyNpMe0b1hMkXFA==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@typescript-eslint/types": "6.13.2", "@typescript-eslint/visitor-keys": "6.13.2" @@ -5806,6 +6132,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.13.2.tgz", "integrity": "sha512-7sxbQ+EMRubQc3wTfTsycgYpSujyVbI1xw+3UMRUcrhSy+pN09y/lWzeKDbvhoqcRbHdc+APLs/PWYi/cisLPg==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": "^16.0.0 || >=18.0.0" }, @@ -5819,6 +6147,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.13.2.tgz", "integrity": "sha512-SuD8YLQv6WHnOEtKv8D6HZUzOub855cfPnPMKvdM/Bh1plv1f7Q/0iFUDLKKlxHcEstQnaUU4QZskgQq74t+3w==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@typescript-eslint/types": "6.13.2", "@typescript-eslint/visitor-keys": "6.13.2", @@ -5846,6 +6176,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.13.2.tgz", "integrity": "sha512-b9Ptq4eAZUym4idijCRzl61oPCwwREcfDI8xGk751Vhzig5fFZR9CyzDz4Sp/nxSLBYxUPyh4QdIDqWykFhNmQ==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", @@ -5871,6 +6203,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.13.2.tgz", "integrity": "sha512-OGznFs0eAQXJsp+xSd6k/O1UbFi/K/L7WjqeRoFE7vadjAF9y0uppXhYNQNEqygjou782maGClOoZwPqF0Drlw==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@typescript-eslint/types": "6.13.2", "eslint-visitor-keys": "^3.4.1" @@ -5888,6 +6222,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.13.2.tgz", "integrity": "sha512-MUkcC+7Wt/QOGeVlM8aGGJZy1XV5YKjTpq9jK6r6/iLsGXhBVaGP5N0UYvFsu9BFlSpwY9kMretzdBH01rkRXg==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "6.13.2", "@typescript-eslint/types": "6.13.2", @@ -5916,6 +6252,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.13.2.tgz", "integrity": "sha512-CXQA0xo7z6x13FeDYCgBkjWzNqzBn8RXaE3QVQVIUm74fWJLkJkaHmHdKStrxQllGh6Q4eUGyNpMe0b1hMkXFA==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@typescript-eslint/types": "6.13.2", "@typescript-eslint/visitor-keys": "6.13.2" @@ -5933,6 +6271,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.13.2.tgz", "integrity": "sha512-7sxbQ+EMRubQc3wTfTsycgYpSujyVbI1xw+3UMRUcrhSy+pN09y/lWzeKDbvhoqcRbHdc+APLs/PWYi/cisLPg==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": "^16.0.0 || >=18.0.0" }, @@ -5946,6 +6286,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.13.2.tgz", "integrity": "sha512-SuD8YLQv6WHnOEtKv8D6HZUzOub855cfPnPMKvdM/Bh1plv1f7Q/0iFUDLKKlxHcEstQnaUU4QZskgQq74t+3w==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@typescript-eslint/types": "6.13.2", "@typescript-eslint/visitor-keys": "6.13.2", @@ -5973,6 +6315,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.13.2.tgz", "integrity": "sha512-OGznFs0eAQXJsp+xSd6k/O1UbFi/K/L7WjqeRoFE7vadjAF9y0uppXhYNQNEqygjou782maGClOoZwPqF0Drlw==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@typescript-eslint/types": "6.13.2", "eslint-visitor-keys": "^3.4.1" @@ -6007,6 +6351,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.13.2.tgz", "integrity": "sha512-Qr6ssS1GFongzH2qfnWKkAQmMUyZSyOr0W54nZNU1MDfo+U4Mv3XveeLZzadc/yq8iYhQZHYT+eoXJqnACM1tw==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@typescript-eslint/typescript-estree": "6.13.2", "@typescript-eslint/utils": "6.13.2", @@ -6034,6 +6380,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.13.2.tgz", "integrity": "sha512-CXQA0xo7z6x13FeDYCgBkjWzNqzBn8RXaE3QVQVIUm74fWJLkJkaHmHdKStrxQllGh6Q4eUGyNpMe0b1hMkXFA==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@typescript-eslint/types": "6.13.2", "@typescript-eslint/visitor-keys": "6.13.2" @@ -6051,6 +6399,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.13.2.tgz", "integrity": "sha512-7sxbQ+EMRubQc3wTfTsycgYpSujyVbI1xw+3UMRUcrhSy+pN09y/lWzeKDbvhoqcRbHdc+APLs/PWYi/cisLPg==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": "^16.0.0 || >=18.0.0" }, @@ -6064,6 +6414,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.13.2.tgz", "integrity": "sha512-SuD8YLQv6WHnOEtKv8D6HZUzOub855cfPnPMKvdM/Bh1plv1f7Q/0iFUDLKKlxHcEstQnaUU4QZskgQq74t+3w==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@typescript-eslint/types": "6.13.2", "@typescript-eslint/visitor-keys": "6.13.2", @@ -6091,6 +6443,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.13.2.tgz", "integrity": "sha512-b9Ptq4eAZUym4idijCRzl61oPCwwREcfDI8xGk751Vhzig5fFZR9CyzDz4Sp/nxSLBYxUPyh4QdIDqWykFhNmQ==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", @@ -6116,6 +6470,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.13.2.tgz", "integrity": "sha512-OGznFs0eAQXJsp+xSd6k/O1UbFi/K/L7WjqeRoFE7vadjAF9y0uppXhYNQNEqygjou782maGClOoZwPqF0Drlw==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@typescript-eslint/types": "6.13.2", "eslint-visitor-keys": "^3.4.1" @@ -6218,6 +6574,80 @@ "dev": true, "peer": true }, + "node_modules/@vue/compiler-core": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.21.tgz", + "integrity": "sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/parser": "^7.23.9", + "@vue/shared": "3.4.21", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.0.2" + } + }, + "node_modules/@vue/compiler-core/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.21.tgz", + "integrity": "sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==", + "dev": true, + "peer": true, + "dependencies": { + "@vue/compiler-core": "3.4.21", + "@vue/shared": "3.4.21" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.21.tgz", + "integrity": "sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/parser": "^7.23.9", + "@vue/compiler-core": "3.4.21", + "@vue/compiler-dom": "3.4.21", + "@vue/compiler-ssr": "3.4.21", + "@vue/shared": "3.4.21", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.7", + "postcss": "^8.4.35", + "source-map-js": "^1.0.2" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.21.tgz", + "integrity": "sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==", + "dev": true, + "peer": true, + "dependencies": { + "@vue/compiler-dom": "3.4.21", + "@vue/shared": "3.4.21" + } + }, + "node_modules/@vue/shared": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.21.tgz", + "integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==", + "dev": true, + "peer": true + }, "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -6248,9 +6678,9 @@ } }, "node_modules/acorn": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", - "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -6288,7 +6718,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -6637,9 +7066,9 @@ } }, "node_modules/browserslist": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", - "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", "dev": true, "funding": [ { @@ -6656,9 +7085,9 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001541", - "electron-to-chromium": "^1.4.535", - "node-releases": "^2.0.13", + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", "update-browserslist-db": "^1.0.13" }, "bin": { @@ -6834,9 +7263,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001546", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001546.tgz", - "integrity": "sha512-zvtSJwuQFpewSyRrI3AsftF6rM0X80mZkChIt1spBGEvRglCrjTniXvinc8JKRoqTwXAgvqTImaN9igfSMtUBw==", + "version": "1.0.30001600", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001600.tgz", + "integrity": "sha512-+2S9/2JFhYmYaDpZvo0lKkfvuKIglrx68MwOBqMGHhQsNkLjB5xtc/TGoEPs+MxjSyN/72qer2g97nzR641mOQ==", "dev": true, "funding": [ { @@ -7910,6 +8339,19 @@ "node": ">= 0.8" } }, + "node_modules/core-js-compat": { + "version": "3.36.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.1.tgz", + "integrity": "sha512-Dk997v9ZCt3X/npqzyGdTlq6t7lDBhZwGvV94PKzDArjp7BTRm7WlDAXYd/OWdeFHO8OChQYRJNJvUCqCbrtKA==", + "dev": true, + "dependencies": { + "browserslist": "^4.23.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", @@ -8274,7 +8716,6 @@ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, - "peer": true, "dependencies": { "esutils": "^2.0.2" }, @@ -8435,9 +8876,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.542", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.542.tgz", - "integrity": "sha512-6+cpa00G09N3sfh2joln4VUXHquWrOFx3FLZqiVQvl45+zS9DskDBTPvob+BhvFRmTBkyDSk0vvLMMRo/qc6mQ==", + "version": "1.4.721", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.721.tgz", + "integrity": "sha512-k1x2r6foI8iJOp+1qTxbbrrWMsOiHkzGBYwYigaq+apO1FSqtn44KTo3Sy69qt7CRr7149zTcsDvH7MUKsOuIQ==", "dev": true }, "node_modules/emittery": { @@ -8530,17 +8971,17 @@ } }, "node_modules/eslint": { - "version": "8.52.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.52.0.tgz", - "integrity": "sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.52.0", - "@humanwhocodes/config-array": "^0.11.13", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", @@ -8586,10 +9027,13 @@ } }, "node_modules/eslint-compat-utils": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.1.2.tgz", - "integrity": "sha512-Jia4JDldWnFNIru1Ehx1H5s9/yxiRHY/TimCuUc0jNexew3cF1gI6CYZil1ociakfWO3rRqFjl1mskBblB3RYg==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.0.tgz", + "integrity": "sha512-dc6Y8tzEcSYZMHa+CMPLi/hyo1FzNeonbhJL7Ol0ccuKQkwopJcJBA9YL/xmMTLU1eKigXo9vj9nALElWYSowg==", "dev": true, + "dependencies": { + "semver": "^7.5.4" + }, "engines": { "node": ">=12" }, @@ -8598,17 +9042,113 @@ } }, "node_modules/eslint-config-flat-gitignore": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/eslint-config-flat-gitignore/-/eslint-config-flat-gitignore-0.1.2.tgz", - "integrity": "sha512-PcBsqtd5QHEZH4ROvpnRN4EP0qcHh9voCCHgtyHxnJZHGspJREcZn7oPqRG/GfWt9m3C0fkC2l5CuBtMig2wXQ==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/eslint-config-flat-gitignore/-/eslint-config-flat-gitignore-0.1.3.tgz", + "integrity": "sha512-oQD+dEZv3RThN60tFqGFt+NJcO1DmssUcP+T/nlX+ZzEoEvVUYH0GU9X/VlmDXsbMsS9mONI1HrlxLgtKojw7w==", "dev": true, "dependencies": { + "find-up": "^7.0.0", "parse-gitignore": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/antfu" } }, + "node_modules/eslint-config-flat-gitignore/node_modules/find-up": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz", + "integrity": "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==", + "dev": true, + "dependencies": { + "locate-path": "^7.2.0", + "path-exists": "^5.0.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-config-flat-gitignore/node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-config-flat-gitignore/node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-config-flat-gitignore/node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-config-flat-gitignore/node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/eslint-config-flat-gitignore/node_modules/yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-flat-config-utils": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/eslint-flat-config-utils/-/eslint-flat-config-utils-0.1.2.tgz", + "integrity": "sha512-NfeUJrbARSHGux2no/zz+YOjfMuPXpedcxRTqov3mlx9PJV2CYAJEj2EjbNSEyHMXQwNCfTtQVZXMSiktQTcpA==", + "dev": true, + "dependencies": { + "@types/eslint": "^8.56.6" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/eslint-import-resolver-node": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", @@ -8629,36 +9169,22 @@ "ms": "^2.1.1" } }, - "node_modules/eslint-module-utils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", - "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", + "node_modules/eslint-merge-processors": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/eslint-merge-processors/-/eslint-merge-processors-0.1.0.tgz", + "integrity": "sha512-IvRXXtEajLeyssvW4wJcZ2etxkR9mUf4zpNwgI+m/Uac9RfXHskuJefkHUcawVzePnd6xp24enp5jfgdHzjRdQ==", "dev": true, - "dependencies": { - "debug": "^3.2.7" + "funding": { + "url": "https://github.com/sponsors/antfu" }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" + "peerDependencies": { + "eslint": "*" } }, "node_modules/eslint-plugin-antfu": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-antfu/-/eslint-plugin-antfu-2.0.0.tgz", - "integrity": "sha512-jbJqri3bDxZ3Eel//ncXI3NXRNYbY0ckckmaWxk4I+nxR5PorOVyLHu/QL69UaPI7qvqAlI0B9GmlAA3hypoHQ==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-antfu/-/eslint-plugin-antfu-2.1.2.tgz", + "integrity": "sha512-s7ZTOM3uq0iqpp6gF0UEotnvup7f2PHBUftCytLZX0+6C9j9KadKZQh6bVVngAyFgsmeD9+gcBopOYLClb2oDg==", "dev": true, "funding": { "url": "https://github.com/sponsors/antfu" @@ -8668,14 +9194,14 @@ } }, "node_modules/eslint-plugin-es-x": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.5.0.tgz", - "integrity": "sha512-ODswlDSO0HJDzXU0XvgZ3lF3lS3XAZEossh15Q2UHjwrJggWeBoKqqEsLTZLXl+dh5eOAozG0zRcYtuE35oTuQ==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.6.0.tgz", + "integrity": "sha512-I0AmeNgevgaTR7y2lrVCJmGYF0rjoznpDvqV/kIkZSZbZ8Rw3eu4cGlvBBULScfkSOCzqKbff5LR4CNrV7mZHA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.1.2", "@eslint-community/regexpp": "^4.6.0", - "eslint-compat-utils": "^0.1.2" + "eslint-compat-utils": "^0.5.0" }, "engines": { "node": "^14.18.0 || >=16.0.0" @@ -8715,51 +9241,66 @@ "node": ">=0.8.0" } }, - "node_modules/eslint-plugin-i": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-i/-/eslint-plugin-i-2.29.0.tgz", - "integrity": "sha512-slGeTS3GQzx9267wLJnNYNO8X9EHGsc75AKIAFvnvMYEcTJKotPKL1Ru5PIGVHIVet+2DsugePWp8Oxpx8G22w==", + "node_modules/eslint-plugin-import-x": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-0.4.4.tgz", + "integrity": "sha512-+6vns/GOAL0K5tzQ7ZescD2vFBz3cICZqT9R5CQ9h/bTA+Jkae8DuHT2gYhFb2K97kzsLnmPmKM51Iq9g6vTRA==", "dev": true, "dependencies": { - "debug": "^3.2.7", - "doctrine": "^2.1.0", + "@typescript-eslint/utils": "^5.62.0", + "debug": "^4.3.4", + "doctrine": "^3.0.0", + "eslint-compat-utils": "^0.5.0", "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "get-tsconfig": "^4.6.2", + "get-tsconfig": "^4.7.3", "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "resolve": "^1.22.3", - "semver": "^7.5.3" + "minimatch": "^9.0.3", + "semver": "^7.6.0" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://opencollective.com/unts" + "node": ">=16" }, "peerDependencies": { - "eslint": "^7.2.0 || ^8" + "eslint": "^7.2.0 || ^8 || ^9.0.0-0" } }, - "node_modules/eslint-plugin-i/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "node_modules/eslint-plugin-import-x/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "dependencies": { - "ms": "^2.1.1" + "balanced-match": "^1.0.0" } }, - "node_modules/eslint-plugin-i/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "node_modules/eslint-plugin-import-x/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", "dev": true, "dependencies": { - "esutils": "^2.0.2" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/eslint-plugin-import-x/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/eslint-plugin-jest": { @@ -8788,26 +9329,26 @@ } }, "node_modules/eslint-plugin-jsdoc": { - "version": "46.9.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.9.0.tgz", - "integrity": "sha512-UQuEtbqLNkPf5Nr/6PPRCtr9xypXY+g8y/Q7gPa0YK7eDhh0y2lWprXRnaYbW7ACgIUvpDKy9X2bZqxtGzBG9Q==", + "version": "48.2.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.2.tgz", + "integrity": "sha512-S0Gk+rpT5w/ephKCncUY7kUsix9uE4B9XI8D/fS1/26d8okE+vZsuG1IvIt4B6sJUdQqsnzi+YXfmh+HJG11CA==", "dev": true, "dependencies": { - "@es-joy/jsdoccomment": "~0.41.0", + "@es-joy/jsdoccomment": "~0.42.0", "are-docs-informative": "^0.0.2", "comment-parser": "1.4.1", "debug": "^4.3.4", "escape-string-regexp": "^4.0.0", "esquery": "^1.5.0", "is-builtin-module": "^3.2.1", - "semver": "^7.5.4", - "spdx-expression-parse": "^3.0.1" + "semver": "^7.6.0", + "spdx-expression-parse": "^4.0.0" }, "engines": { - "node": ">=16" + "node": ">=18" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" } }, "node_modules/eslint-plugin-jsdoc/node_modules/comment-parser": { @@ -8819,16 +9360,44 @@ "node": ">= 12.0.0" } }, + "node_modules/eslint-plugin-jsdoc/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-jsdoc/node_modules/spdx-expression-parse": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", + "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, "node_modules/eslint-plugin-jsonc": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsonc/-/eslint-plugin-jsonc-2.10.0.tgz", - "integrity": "sha512-9d//o6Jyh4s1RxC9fNSt1+MMaFN2ruFdXPG9XZcb/mR2KkfjADYiNL/hbU6W0Cyxfg3tS/XSFuhl5LgtMD8hmw==", + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsonc/-/eslint-plugin-jsonc-2.14.1.tgz", + "integrity": "sha512-Tei6G4N7pZulP5MHi0EIdtseiCqUPkDMd0O8Zrw4muMIlsjJ5/B9X+U3Pfo6B7l0mTL9LN9FwuWT70dRJ6z7tg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "eslint-compat-utils": "^0.1.2", + "eslint-compat-utils": "^0.5.0", + "espree": "^9.6.1", + "graphemer": "^1.4.0", "jsonc-eslint-parser": "^2.0.4", - "natural-compare": "^1.4.0" + "natural-compare": "^1.4.0", + "synckit": "^0.6.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -8841,30 +9410,31 @@ } }, "node_modules/eslint-plugin-markdown": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-markdown/-/eslint-plugin-markdown-3.0.1.tgz", - "integrity": "sha512-8rqoc148DWdGdmYF6WSQFT3uQ6PO7zXYgeBpHAOAakX/zpq+NvFYbDA/H7PYzHajwtmaOzAwfxyl++x0g1/N9A==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-markdown/-/eslint-plugin-markdown-4.0.1.tgz", + "integrity": "sha512-5/MnGvYU0i8MbHH5cg8S+Vl3DL+bqRNYshk1xUO86DilNBaxtTkhH+5FD0/yO03AmlI6+lfNFdk2yOw72EPzpA==", "dev": true, "dependencies": { "mdast-util-from-markdown": "^0.8.5" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "eslint": ">=8" } }, "node_modules/eslint-plugin-n": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.3.1.tgz", - "integrity": "sha512-w46eDIkxQ2FaTHcey7G40eD+FhTXOdKudDXPUO2n9WNcslze/i/HT2qJ3GXjHngYSGDISIgPNhwGtgoix4zeOw==", + "version": "16.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.6.2.tgz", + "integrity": "sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "builtins": "^5.0.1", - "eslint-plugin-es-x": "^7.1.0", + "eslint-plugin-es-x": "^7.5.0", "get-tsconfig": "^4.7.0", + "globals": "^13.24.0", "ignore": "^5.2.4", "is-builtin-module": "^3.2.1", "is-core-module": "^2.12.1", @@ -8882,6 +9452,33 @@ "eslint": ">=7.0.0" } }, + "node_modules/eslint-plugin-n/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-n/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/eslint-plugin-no-only-tests": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/eslint-plugin-no-only-tests/-/eslint-plugin-no-only-tests-3.1.0.tgz", @@ -8892,9 +9489,9 @@ } }, "node_modules/eslint-plugin-perfectionist": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-perfectionist/-/eslint-plugin-perfectionist-2.5.0.tgz", - "integrity": "sha512-F6XXcq4mKKUe/SREoMGQqzgw6cgCgf3pFzkFfQVIGtqD1yXVpQjnhTepzhBeZfxZwgMzR9HO4yH4CUhIQ2WBcQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-perfectionist/-/eslint-plugin-perfectionist-2.7.0.tgz", + "integrity": "sha512-RpSMc0T0DT9DlOj4APzwlAjCqQMxFdsIYlupe73eDkKLn1mMK7fVw2z3nj2y822szKOpvHA7bDa56ySOlr4GXw==", "dev": true, "dependencies": { "@typescript-eslint/utils": "^6.13.0", @@ -8924,13 +9521,13 @@ } }, "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/scope-manager": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.13.2.tgz", - "integrity": "sha512-CXQA0xo7z6x13FeDYCgBkjWzNqzBn8RXaE3QVQVIUm74fWJLkJkaHmHdKStrxQllGh6Q4eUGyNpMe0b1hMkXFA==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.13.2", - "@typescript-eslint/visitor-keys": "6.13.2" + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -8941,9 +9538,9 @@ } }, "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/types": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.13.2.tgz", - "integrity": "sha512-7sxbQ+EMRubQc3wTfTsycgYpSujyVbI1xw+3UMRUcrhSy+pN09y/lWzeKDbvhoqcRbHdc+APLs/PWYi/cisLPg==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -8954,16 +9551,17 @@ } }, "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.13.2.tgz", - "integrity": "sha512-SuD8YLQv6WHnOEtKv8D6HZUzOub855cfPnPMKvdM/Bh1plv1f7Q/0iFUDLKKlxHcEstQnaUU4QZskgQq74t+3w==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.13.2", - "@typescript-eslint/visitor-keys": "6.13.2", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", + "minimatch": "9.0.3", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" }, @@ -8980,18 +9578,33 @@ } } }, + "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/utils": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.13.2.tgz", - "integrity": "sha512-b9Ptq4eAZUym4idijCRzl61oPCwwREcfDI8xGk751Vhzig5fFZR9CyzDz4Sp/nxSLBYxUPyh4QdIDqWykFhNmQ==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.13.2", - "@typescript-eslint/types": "6.13.2", - "@typescript-eslint/typescript-estree": "6.13.2", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", "semver": "^7.5.4" }, "engines": { @@ -9006,12 +9619,12 @@ } }, "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.13.2.tgz", - "integrity": "sha512-OGznFs0eAQXJsp+xSd6k/O1UbFi/K/L7WjqeRoFE7vadjAF9y0uppXhYNQNEqygjou782maGClOoZwPqF0Drlw==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.13.2", + "@typescript-eslint/types": "6.21.0", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -9032,9 +9645,9 @@ } }, "node_modules/eslint-plugin-perfectionist/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -9046,16 +9659,39 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/eslint-plugin-toml": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-toml/-/eslint-plugin-toml-0.10.0.tgz", + "integrity": "sha512-HzhRjePs4FDszPRY6ryHXV90MsSEkJsWnP175x33Iop/W6/hb80qjzImO5LlQfqhX3B0TkotOFSIigNI4AdGsw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "eslint-compat-utils": "^0.5.0", + "lodash": "^4.17.19", + "toml-eslint-parser": "^0.9.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, "node_modules/eslint-plugin-unicorn": { - "version": "49.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-49.0.0.tgz", - "integrity": "sha512-0fHEa/8Pih5cmzFW5L7xMEfUTvI9WKeQtjmKpTUmY+BiFCDxkxrTdnURJOHKykhtwIeyYsxnecbGvDCml++z4Q==", + "version": "51.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-51.0.1.tgz", + "integrity": "sha512-MuR/+9VuB0fydoI0nIn2RDA5WISRn4AsJyNSaNKLVwie9/ONvQhxOBbkfSICBPnzKrB77Fh6CZZXjgTt/4Latw==", "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.22.20", "@eslint-community/eslint-utils": "^4.4.0", - "ci-info": "^3.8.0", + "@eslint/eslintrc": "^2.1.4", + "ci-info": "^4.0.0", "clean-regexp": "^1.0.0", + "core-js-compat": "^3.34.0", "esquery": "^1.5.0", "indent-string": "^4.0.0", "is-builtin-module": "^3.2.1", @@ -9074,7 +9710,22 @@ "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" }, "peerDependencies": { - "eslint": ">=8.52.0" + "eslint": ">=8.56.0" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/ci-info": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.0.0.tgz", + "integrity": "sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" } }, "node_modules/eslint-plugin-unicorn/node_modules/jsesc": { @@ -9089,16 +9740,37 @@ "node": ">=6" } }, - "node_modules/eslint-plugin-vitest": { - "version": "0.3.10", - "resolved": "https://registry.npmjs.org/eslint-plugin-vitest/-/eslint-plugin-vitest-0.3.10.tgz", - "integrity": "sha512-08lj4rdhZHYyHk+Py2nJ7SlE6arP8GNfGXl9jVqhe9s5JoZIGiBpIkLGX+VNBiB6vXTn56H6Ant7Koc6XzRjtQ==", + "node_modules/eslint-plugin-unused-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-3.1.0.tgz", + "integrity": "sha512-9l1YFCzXKkw1qtAru1RWUtG2EVDZY0a0eChKXcL+EZ5jitG7qxdctu4RnvhOJHv4xfmUf7h+JJPINlVpGhZMrw==", "dev": true, "dependencies": { - "@typescript-eslint/utils": "^6.11.0" + "eslint-rule-composer": "^0.3.0" }, "engines": { - "node": "14.x || >= 16" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "6 - 7", + "eslint": "8" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-vitest": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vitest/-/eslint-plugin-vitest-0.4.0.tgz", + "integrity": "sha512-3oWgZIwdWVBQ5plvkmOBjreIGLQRdYb7x54OP8uIRHeZyRVJIdOn9o/qWVb9292fDMC8jn7H7d9TSFBZqhrykQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/utils": "^7.2.0" + }, + "engines": { + "node": "^18.0.0 || >= 20.0.0" }, "peerDependencies": { "eslint": ">=8.0.0", @@ -9114,16 +9786,16 @@ } }, "node_modules/eslint-plugin-vitest/node_modules/@typescript-eslint/scope-manager": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.13.2.tgz", - "integrity": "sha512-CXQA0xo7z6x13FeDYCgBkjWzNqzBn8RXaE3QVQVIUm74fWJLkJkaHmHdKStrxQllGh6Q4eUGyNpMe0b1hMkXFA==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.4.0.tgz", + "integrity": "sha512-68VqENG5HK27ypafqLVs8qO+RkNc7TezCduYrx8YJpXq2QGZ30vmNZGJJJC48+MVn4G2dCV8m5ZTVnzRexTVtw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.13.2", - "@typescript-eslint/visitor-keys": "6.13.2" + "@typescript-eslint/types": "7.4.0", + "@typescript-eslint/visitor-keys": "7.4.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -9131,12 +9803,12 @@ } }, "node_modules/eslint-plugin-vitest/node_modules/@typescript-eslint/types": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.13.2.tgz", - "integrity": "sha512-7sxbQ+EMRubQc3wTfTsycgYpSujyVbI1xw+3UMRUcrhSy+pN09y/lWzeKDbvhoqcRbHdc+APLs/PWYi/cisLPg==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.4.0.tgz", + "integrity": "sha512-mjQopsbffzJskos5B4HmbsadSJQWaRK0UxqQ7GuNA9Ga4bEKeiO6b2DnB6cM6bpc8lemaPseh0H9B/wyg+J7rw==", "dev": true, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -9144,21 +9816,22 @@ } }, "node_modules/eslint-plugin-vitest/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.13.2.tgz", - "integrity": "sha512-SuD8YLQv6WHnOEtKv8D6HZUzOub855cfPnPMKvdM/Bh1plv1f7Q/0iFUDLKKlxHcEstQnaUU4QZskgQq74t+3w==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.4.0.tgz", + "integrity": "sha512-A99j5AYoME/UBQ1ucEbbMEmGkN7SE0BvZFreSnTd1luq7yulcHdyGamZKizU7canpGDWGJ+Q6ZA9SyQobipePg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.13.2", - "@typescript-eslint/visitor-keys": "6.13.2", + "@typescript-eslint/types": "7.4.0", + "@typescript-eslint/visitor-keys": "7.4.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", + "minimatch": "9.0.3", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -9171,59 +9844,84 @@ } }, "node_modules/eslint-plugin-vitest/node_modules/@typescript-eslint/utils": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.13.2.tgz", - "integrity": "sha512-b9Ptq4eAZUym4idijCRzl61oPCwwREcfDI8xGk751Vhzig5fFZR9CyzDz4Sp/nxSLBYxUPyh4QdIDqWykFhNmQ==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.4.0.tgz", + "integrity": "sha512-NQt9QLM4Tt8qrlBVY9lkMYzfYtNz8/6qwZg8pI3cMGlPnj6mOpRxxAm7BMJN9K0AiY+1BwJ5lVC650YJqYOuNg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.13.2", - "@typescript-eslint/types": "6.13.2", - "@typescript-eslint/typescript-estree": "6.13.2", + "@typescript-eslint/scope-manager": "7.4.0", + "@typescript-eslint/types": "7.4.0", + "@typescript-eslint/typescript-estree": "7.4.0", "semver": "^7.5.4" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^8.56.0" } }, "node_modules/eslint-plugin-vitest/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.13.2.tgz", - "integrity": "sha512-OGznFs0eAQXJsp+xSd6k/O1UbFi/K/L7WjqeRoFE7vadjAF9y0uppXhYNQNEqygjou782maGClOoZwPqF0Drlw==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.4.0.tgz", + "integrity": "sha512-0zkC7YM0iX5Y41homUUeW1CHtZR01K3ybjM1l6QczoMuay0XKtrb93kv95AxUGwdjGr64nNqnOCwmEl616N8CA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.13.2", + "@typescript-eslint/types": "7.4.0", "eslint-visitor-keys": "^3.4.1" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/eslint-plugin-vitest/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/eslint-plugin-vitest/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/eslint-plugin-vue": { - "version": "9.19.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.19.2.tgz", - "integrity": "sha512-CPDqTOG2K4Ni2o4J5wixkLVNwgctKXFu6oBpVJlpNq7f38lh9I80pRTouZSJ2MAebPJlINU/KTFSXyQfBUlymA==", + "version": "9.24.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.24.0.tgz", + "integrity": "sha512-9SkJMvF8NGMT9aQCwFc5rj8Wo1XWSMSHk36i7ZwdI614BU7sIOR28ZjuFPKp8YGymZN12BSEbiSwa7qikp+PBw==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", + "globals": "^13.24.0", "natural-compare": "^1.4.0", "nth-check": "^2.1.1", - "postcss-selector-parser": "^6.0.13", - "semver": "^7.5.4", - "vue-eslint-parser": "^9.3.1", + "postcss-selector-parser": "^6.0.15", + "semver": "^7.6.0", + "vue-eslint-parser": "^9.4.2", "xml-name-validator": "^4.0.0" }, "engines": { @@ -9233,14 +9931,56 @@ "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/eslint-plugin-vue/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-vue/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-vue/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/eslint-plugin-yml": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-1.10.0.tgz", - "integrity": "sha512-53SUwuNDna97lVk38hL/5++WXDuugPM9SUQ1T645R0EHMRCdBIIxGye/oOX2qO3FQ7aImxaUZJU/ju+NMUBrLQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-1.13.2.tgz", + "integrity": "sha512-1i71VhmsG5UxE41rIJmJjhlTTxYy7upAY5Hqj8AdBc7rfJzRIZr3a2spuOS8+N7ZDCWsHAWY3J6lzQNQHDv6Uw==", "dev": true, "dependencies": { "debug": "^4.3.2", - "eslint-compat-utils": "^0.1.0", + "eslint-compat-utils": "^0.5.0", "lodash": "^4.17.21", "natural-compare": "^1.4.0", "yaml-eslint-parser": "^1.2.1" @@ -9255,6 +9995,19 @@ "eslint": ">=6.0.0" } }, + "node_modules/eslint-processor-vue-blocks": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/eslint-processor-vue-blocks/-/eslint-processor-vue-blocks-0.1.1.tgz", + "integrity": "sha512-9+dU5lU881log570oBwpelaJmOfOzSniben7IWEDRYQPPWwlvaV7NhOtsTuUWDqpYT+dtKKWPsgz4OkOi+aZnA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/compiler-sfc": "^3.3.0", + "eslint": "^8.50.0" + } + }, "node_modules/eslint-rule-composer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz", @@ -9353,6 +10106,22 @@ "node": ">=10.13.0" } }, + "node_modules/eslint/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "peer": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/eslint/node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -9414,6 +10183,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/eslint/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", @@ -9495,6 +10277,13 @@ "node": ">=4.0" } }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "peer": true + }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -10031,9 +10820,9 @@ } }, "node_modules/get-tsconfig": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz", - "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==", + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz", + "integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==", "dev": true, "dependencies": { "resolve-pkg-maps": "^1.0.0" @@ -10153,27 +10942,12 @@ } }, "node_modules/globals": { - "version": "13.23.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", - "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globals/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.0.0.tgz", + "integrity": "sha512-m/C/yR4mjO6pXDTm9/R/SpYTAIyaUB4EOzcaaMEl7mds7Mshct9GfejiJNQGjHHbdMPey13Kpu4TMbYi9ex1pw==", "dev": true, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -11807,8 +12581,7 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -12343,6 +13116,26 @@ "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", "dev": true }, + "node_modules/magic-string": { + "version": "0.30.8", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", + "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", + "dev": true, + "peer": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/magic-string/node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true, + "peer": true + }, "node_modules/make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", @@ -12973,9 +13766,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", "dev": true }, "node_modules/nodemailer": { @@ -13546,10 +14339,39 @@ "node": ">=4" } }, + "node_modules/postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "peer": true, + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, "node_modules/postcss-selector-parser": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", - "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", + "version": "6.0.16", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz", + "integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==", "dev": true, "dependencies": { "cssesc": "^3.0.0", @@ -13559,6 +14381,25 @@ "node": ">=4" } }, + "node_modules/postcss/node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "peer": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -14644,6 +15485,16 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-support": { "version": "0.5.13", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", @@ -15030,6 +15881,24 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/synckit": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.6.2.tgz", + "integrity": "sha512-Vhf+bUa//YSTYKseDiiEuQmhGCoIF3CVBhunm3r/DQnYiGT4JssmnKQc44BIyOZRK2pKjXXAgbhfmbeoC9CJpA==", + "dev": true, + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/synckit/node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -15120,6 +15989,21 @@ "node": ">=0.6" } }, + "node_modules/toml-eslint-parser": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/toml-eslint-parser/-/toml-eslint-parser-0.9.3.tgz", + "integrity": "sha512-moYoCvkNUAPCxSW9jmHmRElhm4tVJpHL8ItC/+uYD0EpPSFXbck7yREz9tNdJVTSpHVod8+HoipcpbQ0oE6gsw==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + } + }, "node_modules/toposort": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", @@ -15441,6 +16325,18 @@ "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", "dev": true }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/unist-util-stringify-position": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", @@ -15592,9 +16488,9 @@ "dev": true }, "node_modules/vue-eslint-parser": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.3.2.tgz", - "integrity": "sha512-q7tWyCVaV9f8iQyIA5Mkj/S6AoJ9KBN8IeUSf3XEmBrOtxOZnfTg5s4KClbZBCK3GtnT/+RyCLZyDHuZwTuBjg==", + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz", + "integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==", "dev": true, "dependencies": { "debug": "^4.3.4", @@ -15839,10 +16735,13 @@ } }, "node_modules/yaml-eslint-parser/node_modules/yaml": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.3.tgz", - "integrity": "sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz", + "integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==", "dev": true, + "bin": { + "yaml": "bin.mjs" + }, "engines": { "node": ">= 14" } @@ -15965,62 +16864,167 @@ } }, "@antfu/eslint-config": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/@antfu/eslint-config/-/eslint-config-2.3.4.tgz", - "integrity": "sha512-5uPgbcn88QqIALeZpZeVOwFPbMLWYpOkyV8yZZXfV45tMAb9gLcg2Zodo/L0v+bW8xFcu6l2xm5LCNmjkWERrg==", + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@antfu/eslint-config/-/eslint-config-2.11.4.tgz", + "integrity": "sha512-kQC8XFKih5igRodfDBpXIi3KFsjYuCfX2F9VK4hk79+KkDETUF/14ymai4O+Y+vmSNdRFwjtDL5YhcRoaD0rAg==", "dev": true, "requires": { - "@antfu/eslint-define-config": "^1.23.0-2", "@antfu/install-pkg": "^0.3.1", - "@eslint-types/jsdoc": "46.8.2-1", - "@eslint-types/typescript-eslint": "^6.12.0", - "@eslint-types/unicorn": "^49.0.0", - "@stylistic/eslint-plugin": "^1.5.0", - "@typescript-eslint/eslint-plugin": "^6.13.2", - "@typescript-eslint/parser": "^6.13.2", - "eslint-config-flat-gitignore": "^0.1.2", - "eslint-plugin-antfu": "^2.0.0", + "@clack/prompts": "^0.7.0", + "@stylistic/eslint-plugin": "^1.7.0", + "@typescript-eslint/eslint-plugin": "^7.4.0", + "@typescript-eslint/parser": "^7.4.0", + "eslint-config-flat-gitignore": "^0.1.3", + "eslint-flat-config-utils": "^0.1.1", + "eslint-merge-processors": "^0.1.0", + "eslint-plugin-antfu": "^2.1.2", "eslint-plugin-eslint-comments": "^3.2.0", - "eslint-plugin-i": "^2.29.0", - "eslint-plugin-jsdoc": "^46.9.0", - "eslint-plugin-jsonc": "^2.10.0", - "eslint-plugin-markdown": "^3.0.1", - "eslint-plugin-n": "^16.3.1", + "eslint-plugin-import-x": "^0.4.4", + "eslint-plugin-jsdoc": "^48.2.1", + "eslint-plugin-jsonc": "^2.14.1", + "eslint-plugin-markdown": "^4.0.1", + "eslint-plugin-n": "^16.6.2", "eslint-plugin-no-only-tests": "^3.1.0", - "eslint-plugin-perfectionist": "^2.5.0", - "eslint-plugin-unicorn": "^49.0.0", - "eslint-plugin-unused-imports": "^3.0.0", - "eslint-plugin-vitest": "^0.3.10", - "eslint-plugin-vue": "^9.19.2", - "eslint-plugin-yml": "^1.10.0", - "globals": "^13.23.0", + "eslint-plugin-perfectionist": "^2.7.0", + "eslint-plugin-toml": "^0.10.0", + "eslint-plugin-unicorn": "^51.0.1", + "eslint-plugin-unused-imports": "^3.1.0", + "eslint-plugin-vitest": "^0.4.0", + "eslint-plugin-vue": "^9.24.0", + "eslint-plugin-yml": "^1.13.2", + "eslint-processor-vue-blocks": "^0.1.1", + "globals": "^15.0.0", "jsonc-eslint-parser": "^2.4.0", "local-pkg": "^0.5.0", "parse-gitignore": "^2.0.0", "picocolors": "^1.0.0", - "prompts": "^2.4.2", - "vue-eslint-parser": "^9.3.2", + "toml-eslint-parser": "^0.9.3", + "vue-eslint-parser": "^9.4.2", "yaml-eslint-parser": "^1.2.2", "yargs": "^17.7.2" }, "dependencies": { - "eslint-plugin-unused-imports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-3.0.0.tgz", - "integrity": "sha512-sduiswLJfZHeeBJ+MQaG+xYzSWdRXoSw61DpU13mzWumCkR0ufD0HmO4kdNokjrkluMHpj/7PJeN35pgbhW3kw==", + "@typescript-eslint/eslint-plugin": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.4.0.tgz", + "integrity": "sha512-yHMQ/oFaM7HZdVrVm/M2WHaNPgyuJH4WelkSVEWSSsir34kxW2kDJCxlXRhhGWEsMN0WAW/vLpKfKVcm8k+MPw==", "dev": true, "requires": { - "eslint-rule-composer": "^0.3.0" + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "7.4.0", + "@typescript-eslint/type-utils": "7.4.0", + "@typescript-eslint/utils": "7.4.0", + "@typescript-eslint/visitor-keys": "7.4.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/parser": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.4.0.tgz", + "integrity": "sha512-ZvKHxHLusweEUVwrGRXXUVzFgnWhigo4JurEj0dGF1tbcGh6buL+ejDdjxOQxv6ytcY1uhun1p2sm8iWStlgLQ==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "7.4.0", + "@typescript-eslint/types": "7.4.0", + "@typescript-eslint/typescript-estree": "7.4.0", + "@typescript-eslint/visitor-keys": "7.4.0", + "debug": "^4.3.4" + } + }, + "@typescript-eslint/scope-manager": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.4.0.tgz", + "integrity": "sha512-68VqENG5HK27ypafqLVs8qO+RkNc7TezCduYrx8YJpXq2QGZ30vmNZGJJJC48+MVn4G2dCV8m5ZTVnzRexTVtw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "7.4.0", + "@typescript-eslint/visitor-keys": "7.4.0" + } + }, + "@typescript-eslint/type-utils": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.4.0.tgz", + "integrity": "sha512-247ETeHgr9WTRMqHbbQdzwzhuyaJ8dPTuyuUEMANqzMRB1rj/9qFIuIXK7l0FX9i9FXbHeBQl/4uz6mYuCE7Aw==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "7.4.0", + "@typescript-eslint/utils": "7.4.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/types": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.4.0.tgz", + "integrity": "sha512-mjQopsbffzJskos5B4HmbsadSJQWaRK0UxqQ7GuNA9Ga4bEKeiO6b2DnB6cM6bpc8lemaPseh0H9B/wyg+J7rw==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.4.0.tgz", + "integrity": "sha512-A99j5AYoME/UBQ1ucEbbMEmGkN7SE0BvZFreSnTd1luq7yulcHdyGamZKizU7canpGDWGJ+Q6ZA9SyQobipePg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "7.4.0", + "@typescript-eslint/visitor-keys": "7.4.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/utils": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.4.0.tgz", + "integrity": "sha512-NQt9QLM4Tt8qrlBVY9lkMYzfYtNz8/6qwZg8pI3cMGlPnj6mOpRxxAm7BMJN9K0AiY+1BwJ5lVC650YJqYOuNg==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "7.4.0", + "@typescript-eslint/types": "7.4.0", + "@typescript-eslint/typescript-estree": "7.4.0", + "semver": "^7.5.4" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.4.0.tgz", + "integrity": "sha512-0zkC7YM0iX5Y41homUUeW1CHtZR01K3ybjM1l6QczoMuay0XKtrb93kv95AxUGwdjGr64nNqnOCwmEl616N8CA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "7.4.0", + "eslint-visitor-keys": "^3.4.1" + } + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" } } } }, - "@antfu/eslint-define-config": { - "version": "1.23.0-2", - "resolved": "https://registry.npmjs.org/@antfu/eslint-define-config/-/eslint-define-config-1.23.0-2.tgz", - "integrity": "sha512-LvxY21+ZhpuBf/aHeBUtGQhSEfad4PkNKXKvDOSvukaM3XVTfBhwmHX2EKwAsdq5DlfjbT3qqYyMiueBIO5iDQ==", - "dev": true - }, "@antfu/install-pkg": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-0.3.1.tgz", @@ -16402,9 +17406,9 @@ } }, "@babel/parser": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", - "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.1.tgz", + "integrity": "sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==", "dev": true }, "@babel/plugin-syntax-async-generators": { @@ -16606,6 +17610,35 @@ "buffer": "^6.0.3" } }, + "@clack/core": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@clack/core/-/core-0.3.4.tgz", + "integrity": "sha512-H4hxZDXgHtWTwV3RAVenqcC4VbJZNegbBjlPvzOzCouXtS2y3sDvlO3IsbrPNWuLWPPlYVYPghQdSF64683Ldw==", + "dev": true, + "requires": { + "picocolors": "^1.0.0", + "sisteransi": "^1.0.5" + } + }, + "@clack/prompts": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-0.7.0.tgz", + "integrity": "sha512-0MhX9/B4iL6Re04jPrttDm+BsP8y6mS7byuv0BvXgdXhbV5PdlsHt55dvNsuBCPZ7xq1oTAOOuotR9NFbQyMSA==", + "dev": true, + "requires": { + "@clack/core": "^0.3.3", + "is-unicode-supported": "*", + "picocolors": "^1.0.0", + "sisteransi": "^1.0.5" + }, + "dependencies": { + "is-unicode-supported": { + "version": "1.3.0", + "bundled": true, + "dev": true + } + } + }, "@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -19473,9 +20506,9 @@ } }, "@es-joy/jsdoccomment": { - "version": "0.41.0", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.41.0.tgz", - "integrity": "sha512-aKUhyn1QI5Ksbqcr3fFJj16p99QdjUxXAEuFst1Z47DRyoiMwivIH9MV/ARcJOCXVjPfjITciej8ZD2O/6qUmw==", + "version": "0.42.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.42.0.tgz", + "integrity": "sha512-R1w57YlVA6+YE01wch3GPYn6bCsrOV3YW/5oGGE2tmX6JcL9Nr+b5IikrjMPF+v9CV3ay+obImEdsDhovhJrzw==", "dev": true, "requires": { "comment-parser": "1.4.1", @@ -19506,30 +20539,11 @@ "integrity": "sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==", "dev": true }, - "@eslint-types/jsdoc": { - "version": "46.8.2-1", - "resolved": "https://registry.npmjs.org/@eslint-types/jsdoc/-/jsdoc-46.8.2-1.tgz", - "integrity": "sha512-FwD7V0xX0jyaqj8Ul5ZY+TAAPohDfVqtbuXJNHb+OIv1aTIqZi5+Zn3F2UwQ5O3BnQd2mTduyK0+HjGx3/AMFg==", - "dev": true - }, - "@eslint-types/typescript-eslint": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/@eslint-types/typescript-eslint/-/typescript-eslint-6.12.0.tgz", - "integrity": "sha512-N8cbOYjyFl2BFgDhDgHhTGpgiMkFg0CoITG5hdBm9ZGmcEgUvFBnHvHG7qJl3qVEmFnoKUdfSAcr7MRb2/Jxvw==", - "dev": true - }, - "@eslint-types/unicorn": { - "version": "49.0.0", - "resolved": "https://registry.npmjs.org/@eslint-types/unicorn/-/unicorn-49.0.0.tgz", - "integrity": "sha512-NfXSZIsPFRD2fwTDZQj8SaXqS/rXjB5foxMraLovyrYGXiQK2y0780drDKYYSVbqvco29QIYoZNmnKTUkzZMvQ==", - "dev": true - }, "@eslint/eslintrc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, - "peer": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -19546,37 +20560,50 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, - "peer": true + "requires": { + "type-fest": "^0.20.2" + } }, "js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, - "peer": true, "requires": { "argparse": "^2.0.1" } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true } } }, "@eslint/js": { - "version": "8.52.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.52.0.tgz", - "integrity": "sha512-mjZVbpaeMZludF2fsWLD0Z9gCref1Tk4i9+wddjRvpUNqqcndPkBD09N/Mapey0b3jaXbLm2kICwFv2E64QinA==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true, "peer": true }, "@humanwhocodes/config-array": { - "version": "0.11.13", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", - "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "peer": true, "requires": { - "@humanwhocodes/object-schema": "^2.0.1", - "debug": "^4.1.1", + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", "minimatch": "^3.0.5" } }, @@ -19588,9 +20615,9 @@ "peer": true }, "@humanwhocodes/object-schema": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", - "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", "dev": true, "peer": true }, @@ -20132,38 +21159,41 @@ } }, "@stylistic/eslint-plugin": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-1.5.0.tgz", - "integrity": "sha512-XmlB5nxk06nlnx1/ka0l+WNqHcjnnXfDts4ZaCvrpCY/6l8lNtHwLwdCKF/UpBYNuRWI/HLWCTtQc0jjfwrfBA==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-1.7.0.tgz", + "integrity": "sha512-ThMUjGIi/jeWYNvOdjZkoLw1EOVs0tEuKXDgWvTn8uWaEz55HuPlajKxjKLpv19C+qRDbKczJfzUODfCdME53A==", "dev": true, "requires": { - "@stylistic/eslint-plugin-js": "1.5.0", - "@stylistic/eslint-plugin-jsx": "1.5.0", - "@stylistic/eslint-plugin-plus": "1.5.0", - "@stylistic/eslint-plugin-ts": "1.5.0" + "@stylistic/eslint-plugin-js": "1.7.0", + "@stylistic/eslint-plugin-jsx": "1.7.0", + "@stylistic/eslint-plugin-plus": "1.7.0", + "@stylistic/eslint-plugin-ts": "1.7.0", + "@types/eslint": "^8.56.2" } }, "@stylistic/eslint-plugin-js": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-1.5.0.tgz", - "integrity": "sha512-TuGQv1bsIshkbJUInCewp4IUWy24W5RFiVNMV0quPSkuZ8gsYoqq6kLHvvaxpjxN9TvwSoOIwnhgrYKei2Tgcw==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-1.7.0.tgz", + "integrity": "sha512-PN6On/+or63FGnhhMKSQfYcWutRlzOiYlVdLM6yN7lquoBTqUJHYnl4TA4MHwiAt46X5gRxDr1+xPZ1lOLcL+Q==", "dev": true, "requires": { - "acorn": "^8.11.2", + "@types/eslint": "^8.56.2", + "acorn": "^8.11.3", "escape-string-regexp": "^4.0.0", "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "graphemer": "^1.4.0" + "espree": "^9.6.1" } }, "@stylistic/eslint-plugin-jsx": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-jsx/-/eslint-plugin-jsx-1.5.0.tgz", - "integrity": "sha512-sqFdA1mS0jwovAatS8xFAiwxPbcy69S2AUjrGMxyhxaKbELPjvqbxPYJL+35ylT0xqirUlm118xZIFDooC8koQ==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-jsx/-/eslint-plugin-jsx-1.7.0.tgz", + "integrity": "sha512-BACdBwXakQvjYIST5N2WWhRbvhRsIxa/F59BiZol+0IH4FSmDXhie7v/yaxDIIA9CbfElzOmIA5nWNYTVXcnwQ==", "dev": true, "requires": { - "@stylistic/eslint-plugin-js": "^1.5.0", - "estraverse": "^5.3.0" + "@stylistic/eslint-plugin-js": "^1.7.0", + "@types/eslint": "^8.56.2", + "estraverse": "^5.3.0", + "picomatch": "^4.0.1" }, "dependencies": { "estraverse": { @@ -20171,142 +21201,187 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true + }, + "picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true } } }, "@stylistic/eslint-plugin-plus": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-plus/-/eslint-plugin-plus-1.5.0.tgz", - "integrity": "sha512-+A4qXFuM6V7x25Hj+xqfVIUbEckG+MUSvL6m83M6YtRq3d5zLW+giKKEL7eSCAw12MwnoDwPcEhqIJK6BRDR3w==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-plus/-/eslint-plugin-plus-1.7.0.tgz", + "integrity": "sha512-AabDw8sXsc70Ydx3qnbeTlRHZnIwY6UKEenBPURPhY3bfYWX+/pDpZH40HkOu94v8D0DUrocPkeeEUxl4e0JDg==", "dev": true, "requires": { - "@typescript-eslint/utils": "^6.13.2" + "@types/eslint": "^8.56.2", + "@typescript-eslint/utils": "^6.21.0" }, "dependencies": { "@typescript-eslint/scope-manager": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.13.2.tgz", - "integrity": "sha512-CXQA0xo7z6x13FeDYCgBkjWzNqzBn8RXaE3QVQVIUm74fWJLkJkaHmHdKStrxQllGh6Q4eUGyNpMe0b1hMkXFA==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", "dev": true, "requires": { - "@typescript-eslint/types": "6.13.2", - "@typescript-eslint/visitor-keys": "6.13.2" + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" } }, "@typescript-eslint/types": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.13.2.tgz", - "integrity": "sha512-7sxbQ+EMRubQc3wTfTsycgYpSujyVbI1xw+3UMRUcrhSy+pN09y/lWzeKDbvhoqcRbHdc+APLs/PWYi/cisLPg==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.13.2.tgz", - "integrity": "sha512-SuD8YLQv6WHnOEtKv8D6HZUzOub855cfPnPMKvdM/Bh1plv1f7Q/0iFUDLKKlxHcEstQnaUU4QZskgQq74t+3w==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", "dev": true, "requires": { - "@typescript-eslint/types": "6.13.2", - "@typescript-eslint/visitor-keys": "6.13.2", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", + "minimatch": "9.0.3", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" } }, "@typescript-eslint/utils": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.13.2.tgz", - "integrity": "sha512-b9Ptq4eAZUym4idijCRzl61oPCwwREcfDI8xGk751Vhzig5fFZR9CyzDz4Sp/nxSLBYxUPyh4QdIDqWykFhNmQ==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.13.2", - "@typescript-eslint/types": "6.13.2", - "@typescript-eslint/typescript-estree": "6.13.2", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", "semver": "^7.5.4" } }, "@typescript-eslint/visitor-keys": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.13.2.tgz", - "integrity": "sha512-OGznFs0eAQXJsp+xSd6k/O1UbFi/K/L7WjqeRoFE7vadjAF9y0uppXhYNQNEqygjou782maGClOoZwPqF0Drlw==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", "dev": true, "requires": { - "@typescript-eslint/types": "6.13.2", + "@typescript-eslint/types": "6.21.0", "eslint-visitor-keys": "^3.4.1" } + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } } } }, "@stylistic/eslint-plugin-ts": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-ts/-/eslint-plugin-ts-1.5.0.tgz", - "integrity": "sha512-OusNGWRXnOV+ywnoXmBFoMtU6Ig/MX1bEu5Jigqmy2cIT8GRMMn7jUl/bXevkv2o66MYnC7PT1Q/3GvN7t0/eg==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-ts/-/eslint-plugin-ts-1.7.0.tgz", + "integrity": "sha512-QsHv98mmW1xaucVYQTyLDgEpybPJ/6jPPxVBrIchntWWwj74xCWKUiw79hu+TpYj/Pbhd9rkqJYLNq3pQGYuyA==", "dev": true, "requires": { - "@stylistic/eslint-plugin-js": "1.5.0", - "@typescript-eslint/utils": "^6.13.2", - "graphemer": "^1.4.0" + "@stylistic/eslint-plugin-js": "1.7.0", + "@types/eslint": "^8.56.2", + "@typescript-eslint/utils": "^6.21.0" }, "dependencies": { "@typescript-eslint/scope-manager": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.13.2.tgz", - "integrity": "sha512-CXQA0xo7z6x13FeDYCgBkjWzNqzBn8RXaE3QVQVIUm74fWJLkJkaHmHdKStrxQllGh6Q4eUGyNpMe0b1hMkXFA==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", "dev": true, "requires": { - "@typescript-eslint/types": "6.13.2", - "@typescript-eslint/visitor-keys": "6.13.2" + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" } }, "@typescript-eslint/types": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.13.2.tgz", - "integrity": "sha512-7sxbQ+EMRubQc3wTfTsycgYpSujyVbI1xw+3UMRUcrhSy+pN09y/lWzeKDbvhoqcRbHdc+APLs/PWYi/cisLPg==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.13.2.tgz", - "integrity": "sha512-SuD8YLQv6WHnOEtKv8D6HZUzOub855cfPnPMKvdM/Bh1plv1f7Q/0iFUDLKKlxHcEstQnaUU4QZskgQq74t+3w==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", "dev": true, "requires": { - "@typescript-eslint/types": "6.13.2", - "@typescript-eslint/visitor-keys": "6.13.2", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", + "minimatch": "9.0.3", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" } }, "@typescript-eslint/utils": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.13.2.tgz", - "integrity": "sha512-b9Ptq4eAZUym4idijCRzl61oPCwwREcfDI8xGk751Vhzig5fFZR9CyzDz4Sp/nxSLBYxUPyh4QdIDqWykFhNmQ==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.13.2", - "@typescript-eslint/types": "6.13.2", - "@typescript-eslint/typescript-estree": "6.13.2", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", "semver": "^7.5.4" } }, "@typescript-eslint/visitor-keys": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.13.2.tgz", - "integrity": "sha512-OGznFs0eAQXJsp+xSd6k/O1UbFi/K/L7WjqeRoFE7vadjAF9y0uppXhYNQNEqygjou782maGClOoZwPqF0Drlw==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", "dev": true, "requires": { - "@typescript-eslint/types": "6.13.2", + "@typescript-eslint/types": "6.21.0", "eslint-visitor-keys": "^3.4.1" } + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } } } }, @@ -20480,6 +21555,22 @@ "@types/node": "*" } }, + "@types/eslint": { + "version": "8.56.6", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.6.tgz", + "integrity": "sha512-ymwc+qb1XkjT/gfoQwxIeHZ6ixH23A+tCT2ADSA/DPVKzAjwYkTXBMCQ/f6fe4wEa85Lhp26VPeUxI7wMhAi7A==", + "dev": true, + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, "@types/express": { "version": "4.17.11", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.11.tgz", @@ -20638,9 +21729,9 @@ "dev": true }, "@types/mdast": { - "version": "3.0.14", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.14.tgz", - "integrity": "sha512-gVZ04PGgw1qLZKsnWnyFv4ORnaJ+DXLdHTVSFbU8yX6xZ34Bjg4Q32yPkmveUP1yItXReKfB0Aknlh/3zxTKAw==", + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", "dev": true, "requires": { "@types/unist": "^2" @@ -20826,9 +21917,9 @@ } }, "@types/unist": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.9.tgz", - "integrity": "sha512-zC0iXxAv1C1ERURduJueYzkzZ2zaGyc+P2c95hgkikHPr3z8EdUZOlgEQ5X0DRmwDZn+hekycQnoeiiRVrmilQ==", + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", + "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==", "dev": true }, "@types/uritemplate": { @@ -20872,6 +21963,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.13.2.tgz", "integrity": "sha512-3+9OGAWHhk4O1LlcwLBONbdXsAhLjyCFogJY/cWy2lxdVJ2JrcTF2pTGMaLl2AE7U1l31n8Py4a8bx5DLf/0dQ==", "dev": true, + "optional": true, + "peer": true, "requires": { "@eslint-community/regexpp": "^4.5.1", "@typescript-eslint/scope-manager": "6.13.2", @@ -20891,6 +21984,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.13.2.tgz", "integrity": "sha512-CXQA0xo7z6x13FeDYCgBkjWzNqzBn8RXaE3QVQVIUm74fWJLkJkaHmHdKStrxQllGh6Q4eUGyNpMe0b1hMkXFA==", "dev": true, + "optional": true, + "peer": true, "requires": { "@typescript-eslint/types": "6.13.2", "@typescript-eslint/visitor-keys": "6.13.2" @@ -20900,13 +21995,17 @@ "version": "6.13.2", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.13.2.tgz", "integrity": "sha512-7sxbQ+EMRubQc3wTfTsycgYpSujyVbI1xw+3UMRUcrhSy+pN09y/lWzeKDbvhoqcRbHdc+APLs/PWYi/cisLPg==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "@typescript-eslint/typescript-estree": { "version": "6.13.2", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.13.2.tgz", "integrity": "sha512-SuD8YLQv6WHnOEtKv8D6HZUzOub855cfPnPMKvdM/Bh1plv1f7Q/0iFUDLKKlxHcEstQnaUU4QZskgQq74t+3w==", "dev": true, + "optional": true, + "peer": true, "requires": { "@typescript-eslint/types": "6.13.2", "@typescript-eslint/visitor-keys": "6.13.2", @@ -20922,6 +22021,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.13.2.tgz", "integrity": "sha512-b9Ptq4eAZUym4idijCRzl61oPCwwREcfDI8xGk751Vhzig5fFZR9CyzDz4Sp/nxSLBYxUPyh4QdIDqWykFhNmQ==", "dev": true, + "optional": true, + "peer": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", @@ -20937,6 +22038,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.13.2.tgz", "integrity": "sha512-OGznFs0eAQXJsp+xSd6k/O1UbFi/K/L7WjqeRoFE7vadjAF9y0uppXhYNQNEqygjou782maGClOoZwPqF0Drlw==", "dev": true, + "optional": true, + "peer": true, "requires": { "@typescript-eslint/types": "6.13.2", "eslint-visitor-keys": "^3.4.1" @@ -20949,6 +22052,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.13.2.tgz", "integrity": "sha512-MUkcC+7Wt/QOGeVlM8aGGJZy1XV5YKjTpq9jK6r6/iLsGXhBVaGP5N0UYvFsu9BFlSpwY9kMretzdBH01rkRXg==", "dev": true, + "optional": true, + "peer": true, "requires": { "@typescript-eslint/scope-manager": "6.13.2", "@typescript-eslint/types": "6.13.2", @@ -20962,6 +22067,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.13.2.tgz", "integrity": "sha512-CXQA0xo7z6x13FeDYCgBkjWzNqzBn8RXaE3QVQVIUm74fWJLkJkaHmHdKStrxQllGh6Q4eUGyNpMe0b1hMkXFA==", "dev": true, + "optional": true, + "peer": true, "requires": { "@typescript-eslint/types": "6.13.2", "@typescript-eslint/visitor-keys": "6.13.2" @@ -20971,13 +22078,17 @@ "version": "6.13.2", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.13.2.tgz", "integrity": "sha512-7sxbQ+EMRubQc3wTfTsycgYpSujyVbI1xw+3UMRUcrhSy+pN09y/lWzeKDbvhoqcRbHdc+APLs/PWYi/cisLPg==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "@typescript-eslint/typescript-estree": { "version": "6.13.2", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.13.2.tgz", "integrity": "sha512-SuD8YLQv6WHnOEtKv8D6HZUzOub855cfPnPMKvdM/Bh1plv1f7Q/0iFUDLKKlxHcEstQnaUU4QZskgQq74t+3w==", "dev": true, + "optional": true, + "peer": true, "requires": { "@typescript-eslint/types": "6.13.2", "@typescript-eslint/visitor-keys": "6.13.2", @@ -20993,6 +22104,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.13.2.tgz", "integrity": "sha512-OGznFs0eAQXJsp+xSd6k/O1UbFi/K/L7WjqeRoFE7vadjAF9y0uppXhYNQNEqygjou782maGClOoZwPqF0Drlw==", "dev": true, + "optional": true, + "peer": true, "requires": { "@typescript-eslint/types": "6.13.2", "eslint-visitor-keys": "^3.4.1" @@ -21015,6 +22128,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.13.2.tgz", "integrity": "sha512-Qr6ssS1GFongzH2qfnWKkAQmMUyZSyOr0W54nZNU1MDfo+U4Mv3XveeLZzadc/yq8iYhQZHYT+eoXJqnACM1tw==", "dev": true, + "optional": true, + "peer": true, "requires": { "@typescript-eslint/typescript-estree": "6.13.2", "@typescript-eslint/utils": "6.13.2", @@ -21027,6 +22142,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.13.2.tgz", "integrity": "sha512-CXQA0xo7z6x13FeDYCgBkjWzNqzBn8RXaE3QVQVIUm74fWJLkJkaHmHdKStrxQllGh6Q4eUGyNpMe0b1hMkXFA==", "dev": true, + "optional": true, + "peer": true, "requires": { "@typescript-eslint/types": "6.13.2", "@typescript-eslint/visitor-keys": "6.13.2" @@ -21036,13 +22153,17 @@ "version": "6.13.2", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.13.2.tgz", "integrity": "sha512-7sxbQ+EMRubQc3wTfTsycgYpSujyVbI1xw+3UMRUcrhSy+pN09y/lWzeKDbvhoqcRbHdc+APLs/PWYi/cisLPg==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "@typescript-eslint/typescript-estree": { "version": "6.13.2", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.13.2.tgz", "integrity": "sha512-SuD8YLQv6WHnOEtKv8D6HZUzOub855cfPnPMKvdM/Bh1plv1f7Q/0iFUDLKKlxHcEstQnaUU4QZskgQq74t+3w==", "dev": true, + "optional": true, + "peer": true, "requires": { "@typescript-eslint/types": "6.13.2", "@typescript-eslint/visitor-keys": "6.13.2", @@ -21058,6 +22179,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.13.2.tgz", "integrity": "sha512-b9Ptq4eAZUym4idijCRzl61oPCwwREcfDI8xGk751Vhzig5fFZR9CyzDz4Sp/nxSLBYxUPyh4QdIDqWykFhNmQ==", "dev": true, + "optional": true, + "peer": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", @@ -21073,6 +22196,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.13.2.tgz", "integrity": "sha512-OGznFs0eAQXJsp+xSd6k/O1UbFi/K/L7WjqeRoFE7vadjAF9y0uppXhYNQNEqygjou782maGClOoZwPqF0Drlw==", "dev": true, + "optional": true, + "peer": true, "requires": { "@typescript-eslint/types": "6.13.2", "eslint-visitor-keys": "^3.4.1" @@ -21134,6 +22259,76 @@ "dev": true, "peer": true }, + "@vue/compiler-core": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.21.tgz", + "integrity": "sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==", + "dev": true, + "peer": true, + "requires": { + "@babel/parser": "^7.23.9", + "@vue/shared": "3.4.21", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.0.2" + }, + "dependencies": { + "entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "peer": true + } + } + }, + "@vue/compiler-dom": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.21.tgz", + "integrity": "sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==", + "dev": true, + "peer": true, + "requires": { + "@vue/compiler-core": "3.4.21", + "@vue/shared": "3.4.21" + } + }, + "@vue/compiler-sfc": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.21.tgz", + "integrity": "sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==", + "dev": true, + "peer": true, + "requires": { + "@babel/parser": "^7.23.9", + "@vue/compiler-core": "3.4.21", + "@vue/compiler-dom": "3.4.21", + "@vue/compiler-ssr": "3.4.21", + "@vue/shared": "3.4.21", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.7", + "postcss": "^8.4.35", + "source-map-js": "^1.0.2" + } + }, + "@vue/compiler-ssr": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.21.tgz", + "integrity": "sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==", + "dev": true, + "peer": true, + "requires": { + "@vue/compiler-dom": "3.4.21", + "@vue/shared": "3.4.21" + } + }, + "@vue/shared": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.21.tgz", + "integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==", + "dev": true, + "peer": true + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -21158,9 +22353,9 @@ } }, "acorn": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", - "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true }, "acorn-jsx": { @@ -21187,7 +22382,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "peer": true, "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -21456,14 +22650,14 @@ } }, "browserslist": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", - "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001541", - "electron-to-chromium": "^1.4.535", - "node-releases": "^2.0.13", + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", "update-browserslist-db": "^1.0.13" } }, @@ -21583,9 +22777,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001546", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001546.tgz", - "integrity": "sha512-zvtSJwuQFpewSyRrI3AsftF6rM0X80mZkChIt1spBGEvRglCrjTniXvinc8JKRoqTwXAgvqTImaN9igfSMtUBw==", + "version": "1.0.30001600", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001600.tgz", + "integrity": "sha512-+2S9/2JFhYmYaDpZvo0lKkfvuKIglrx68MwOBqMGHhQsNkLjB5xtc/TGoEPs+MxjSyN/72qer2g97nzR641mOQ==", "dev": true }, "canonicalize": { @@ -22402,6 +23596,15 @@ } } }, + "core-js-compat": { + "version": "3.36.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.1.tgz", + "integrity": "sha512-Dk997v9ZCt3X/npqzyGdTlq6t7lDBhZwGvV94PKzDArjp7BTRm7WlDAXYd/OWdeFHO8OChQYRJNJvUCqCbrtKA==", + "dev": true, + "requires": { + "browserslist": "^4.23.0" + } + }, "core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", @@ -22664,7 +23867,6 @@ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, - "peer": true, "requires": { "esutils": "^2.0.2" } @@ -22778,9 +23980,9 @@ } }, "electron-to-chromium": { - "version": "1.4.542", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.542.tgz", - "integrity": "sha512-6+cpa00G09N3sfh2joln4VUXHquWrOFx3FLZqiVQvl45+zS9DskDBTPvob+BhvFRmTBkyDSk0vvLMMRo/qc6mQ==", + "version": "1.4.721", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.721.tgz", + "integrity": "sha512-k1x2r6foI8iJOp+1qTxbbrrWMsOiHkzGBYwYigaq+apO1FSqtn44KTo3Sy69qt7CRr7149zTcsDvH7MUKsOuIQ==", "dev": true }, "emittery": { @@ -22851,17 +24053,17 @@ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" }, "eslint": { - "version": "8.52.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.52.0.tgz", - "integrity": "sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, "peer": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.52.0", - "@humanwhocodes/config-array": "^0.11.13", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", @@ -22943,6 +24145,16 @@ "is-glob": "^4.0.3" } }, + "globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "peer": true, + "requires": { + "type-fest": "^0.20.2" + } + }, "js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -22982,23 +24194,94 @@ "requires": { "p-limit": "^3.0.2" } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "peer": true } } }, "eslint-compat-utils": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.1.2.tgz", - "integrity": "sha512-Jia4JDldWnFNIru1Ehx1H5s9/yxiRHY/TimCuUc0jNexew3cF1gI6CYZil1ociakfWO3rRqFjl1mskBblB3RYg==", - "dev": true, - "requires": {} - }, - "eslint-config-flat-gitignore": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/eslint-config-flat-gitignore/-/eslint-config-flat-gitignore-0.1.2.tgz", - "integrity": "sha512-PcBsqtd5QHEZH4ROvpnRN4EP0qcHh9voCCHgtyHxnJZHGspJREcZn7oPqRG/GfWt9m3C0fkC2l5CuBtMig2wXQ==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.0.tgz", + "integrity": "sha512-dc6Y8tzEcSYZMHa+CMPLi/hyo1FzNeonbhJL7Ol0ccuKQkwopJcJBA9YL/xmMTLU1eKigXo9vj9nALElWYSowg==", "dev": true, "requires": { + "semver": "^7.5.4" + } + }, + "eslint-config-flat-gitignore": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/eslint-config-flat-gitignore/-/eslint-config-flat-gitignore-0.1.3.tgz", + "integrity": "sha512-oQD+dEZv3RThN60tFqGFt+NJcO1DmssUcP+T/nlX+ZzEoEvVUYH0GU9X/VlmDXsbMsS9mONI1HrlxLgtKojw7w==", + "dev": true, + "requires": { + "find-up": "^7.0.0", "parse-gitignore": "^2.0.0" + }, + "dependencies": { + "find-up": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz", + "integrity": "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==", + "dev": true, + "requires": { + "locate-path": "^7.2.0", + "path-exists": "^5.0.0", + "unicorn-magic": "^0.1.0" + } + }, + "locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "requires": { + "p-locate": "^6.0.0" + } + }, + "p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "requires": { + "yocto-queue": "^1.0.0" + } + }, + "p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "requires": { + "p-limit": "^4.0.0" + } + }, + "path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true + }, + "yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true + } + } + }, + "eslint-flat-config-utils": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/eslint-flat-config-utils/-/eslint-flat-config-utils-0.1.2.tgz", + "integrity": "sha512-NfeUJrbARSHGux2no/zz+YOjfMuPXpedcxRTqov3mlx9PJV2CYAJEj2EjbNSEyHMXQwNCfTtQVZXMSiktQTcpA==", + "dev": true, + "requires": { + "@types/eslint": "^8.56.6" } }, "eslint-import-resolver-node": { @@ -23023,42 +24306,29 @@ } } }, - "eslint-module-utils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", - "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", + "eslint-merge-processors": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/eslint-merge-processors/-/eslint-merge-processors-0.1.0.tgz", + "integrity": "sha512-IvRXXtEajLeyssvW4wJcZ2etxkR9mUf4zpNwgI+m/Uac9RfXHskuJefkHUcawVzePnd6xp24enp5jfgdHzjRdQ==", "dev": true, - "requires": { - "debug": "^3.2.7" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } + "requires": {} }, "eslint-plugin-antfu": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-antfu/-/eslint-plugin-antfu-2.0.0.tgz", - "integrity": "sha512-jbJqri3bDxZ3Eel//ncXI3NXRNYbY0ckckmaWxk4I+nxR5PorOVyLHu/QL69UaPI7qvqAlI0B9GmlAA3hypoHQ==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-antfu/-/eslint-plugin-antfu-2.1.2.tgz", + "integrity": "sha512-s7ZTOM3uq0iqpp6gF0UEotnvup7f2PHBUftCytLZX0+6C9j9KadKZQh6bVVngAyFgsmeD9+gcBopOYLClb2oDg==", "dev": true, "requires": {} }, "eslint-plugin-es-x": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.5.0.tgz", - "integrity": "sha512-ODswlDSO0HJDzXU0XvgZ3lF3lS3XAZEossh15Q2UHjwrJggWeBoKqqEsLTZLXl+dh5eOAozG0zRcYtuE35oTuQ==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.6.0.tgz", + "integrity": "sha512-I0AmeNgevgaTR7y2lrVCJmGYF0rjoznpDvqV/kIkZSZbZ8Rw3eu4cGlvBBULScfkSOCzqKbff5LR4CNrV7mZHA==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.1.2", "@eslint-community/regexpp": "^4.6.0", - "eslint-compat-utils": "^0.1.2" + "eslint-compat-utils": "^0.5.0" } }, "eslint-plugin-eslint-comments": { @@ -23079,39 +24349,48 @@ } } }, - "eslint-plugin-i": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-i/-/eslint-plugin-i-2.29.0.tgz", - "integrity": "sha512-slGeTS3GQzx9267wLJnNYNO8X9EHGsc75AKIAFvnvMYEcTJKotPKL1Ru5PIGVHIVet+2DsugePWp8Oxpx8G22w==", + "eslint-plugin-import-x": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-0.4.4.tgz", + "integrity": "sha512-+6vns/GOAL0K5tzQ7ZescD2vFBz3cICZqT9R5CQ9h/bTA+Jkae8DuHT2gYhFb2K97kzsLnmPmKM51Iq9g6vTRA==", "dev": true, "requires": { - "debug": "^3.2.7", - "doctrine": "^2.1.0", + "@typescript-eslint/utils": "^5.62.0", + "debug": "^4.3.4", + "doctrine": "^3.0.0", + "eslint-compat-utils": "^0.5.0", "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "get-tsconfig": "^4.6.2", + "get-tsconfig": "^4.7.3", "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "resolve": "^1.22.3", - "semver": "^7.5.3" + "minimatch": "^9.0.3", + "semver": "^7.6.0" }, "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "requires": { - "ms": "^2.1.1" + "balanced-match": "^1.0.0" } }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", "dev": true, "requires": { - "esutils": "^2.0.2" + "brace-expansion": "^2.0.1" + } + }, + "semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" } } } @@ -23126,20 +24405,20 @@ } }, "eslint-plugin-jsdoc": { - "version": "46.9.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.9.0.tgz", - "integrity": "sha512-UQuEtbqLNkPf5Nr/6PPRCtr9xypXY+g8y/Q7gPa0YK7eDhh0y2lWprXRnaYbW7ACgIUvpDKy9X2bZqxtGzBG9Q==", + "version": "48.2.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.2.tgz", + "integrity": "sha512-S0Gk+rpT5w/ephKCncUY7kUsix9uE4B9XI8D/fS1/26d8okE+vZsuG1IvIt4B6sJUdQqsnzi+YXfmh+HJG11CA==", "dev": true, "requires": { - "@es-joy/jsdoccomment": "~0.41.0", + "@es-joy/jsdoccomment": "~0.42.0", "are-docs-informative": "^0.0.2", "comment-parser": "1.4.1", "debug": "^4.3.4", "escape-string-regexp": "^4.0.0", "esquery": "^1.5.0", "is-builtin-module": "^3.2.1", - "semver": "^7.5.4", - "spdx-expression-parse": "^3.0.1" + "semver": "^7.6.0", + "spdx-expression-parse": "^4.0.0" }, "dependencies": { "comment-parser": { @@ -23147,46 +24426,86 @@ "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", "dev": true + }, + "semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "spdx-expression-parse": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", + "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } } } }, "eslint-plugin-jsonc": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsonc/-/eslint-plugin-jsonc-2.10.0.tgz", - "integrity": "sha512-9d//o6Jyh4s1RxC9fNSt1+MMaFN2ruFdXPG9XZcb/mR2KkfjADYiNL/hbU6W0Cyxfg3tS/XSFuhl5LgtMD8hmw==", + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsonc/-/eslint-plugin-jsonc-2.14.1.tgz", + "integrity": "sha512-Tei6G4N7pZulP5MHi0EIdtseiCqUPkDMd0O8Zrw4muMIlsjJ5/B9X+U3Pfo6B7l0mTL9LN9FwuWT70dRJ6z7tg==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", - "eslint-compat-utils": "^0.1.2", + "eslint-compat-utils": "^0.5.0", + "espree": "^9.6.1", + "graphemer": "^1.4.0", "jsonc-eslint-parser": "^2.0.4", - "natural-compare": "^1.4.0" + "natural-compare": "^1.4.0", + "synckit": "^0.6.0" } }, "eslint-plugin-markdown": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-markdown/-/eslint-plugin-markdown-3.0.1.tgz", - "integrity": "sha512-8rqoc148DWdGdmYF6WSQFT3uQ6PO7zXYgeBpHAOAakX/zpq+NvFYbDA/H7PYzHajwtmaOzAwfxyl++x0g1/N9A==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-markdown/-/eslint-plugin-markdown-4.0.1.tgz", + "integrity": "sha512-5/MnGvYU0i8MbHH5cg8S+Vl3DL+bqRNYshk1xUO86DilNBaxtTkhH+5FD0/yO03AmlI6+lfNFdk2yOw72EPzpA==", "dev": true, "requires": { "mdast-util-from-markdown": "^0.8.5" } }, "eslint-plugin-n": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.3.1.tgz", - "integrity": "sha512-w46eDIkxQ2FaTHcey7G40eD+FhTXOdKudDXPUO2n9WNcslze/i/HT2qJ3GXjHngYSGDISIgPNhwGtgoix4zeOw==", + "version": "16.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.6.2.tgz", + "integrity": "sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "builtins": "^5.0.1", - "eslint-plugin-es-x": "^7.1.0", + "eslint-plugin-es-x": "^7.5.0", "get-tsconfig": "^4.7.0", + "globals": "^13.24.0", "ignore": "^5.2.4", "is-builtin-module": "^3.2.1", "is-core-module": "^2.12.1", "minimatch": "^3.1.2", "resolve": "^1.22.2", "semver": "^7.5.3" + }, + "dependencies": { + "globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } } }, "eslint-plugin-no-only-tests": { @@ -23196,9 +24515,9 @@ "dev": true }, "eslint-plugin-perfectionist": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-perfectionist/-/eslint-plugin-perfectionist-2.5.0.tgz", - "integrity": "sha512-F6XXcq4mKKUe/SREoMGQqzgw6cgCgf3pFzkFfQVIGtqD1yXVpQjnhTepzhBeZfxZwgMzR9HO4yH4CUhIQ2WBcQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-perfectionist/-/eslint-plugin-perfectionist-2.7.0.tgz", + "integrity": "sha512-RpSMc0T0DT9DlOj4APzwlAjCqQMxFdsIYlupe73eDkKLn1mMK7fVw2z3nj2y822szKOpvHA7bDa56ySOlr4GXw==", "dev": true, "requires": { "@typescript-eslint/utils": "^6.13.0", @@ -23207,58 +24526,215 @@ }, "dependencies": { "@typescript-eslint/scope-manager": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.13.2.tgz", - "integrity": "sha512-CXQA0xo7z6x13FeDYCgBkjWzNqzBn8RXaE3QVQVIUm74fWJLkJkaHmHdKStrxQllGh6Q4eUGyNpMe0b1hMkXFA==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", "dev": true, "requires": { - "@typescript-eslint/types": "6.13.2", - "@typescript-eslint/visitor-keys": "6.13.2" + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" } }, "@typescript-eslint/types": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.13.2.tgz", - "integrity": "sha512-7sxbQ+EMRubQc3wTfTsycgYpSujyVbI1xw+3UMRUcrhSy+pN09y/lWzeKDbvhoqcRbHdc+APLs/PWYi/cisLPg==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.13.2.tgz", - "integrity": "sha512-SuD8YLQv6WHnOEtKv8D6HZUzOub855cfPnPMKvdM/Bh1plv1f7Q/0iFUDLKKlxHcEstQnaUU4QZskgQq74t+3w==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", "dev": true, "requires": { - "@typescript-eslint/types": "6.13.2", - "@typescript-eslint/visitor-keys": "6.13.2", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", + "minimatch": "9.0.3", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" + }, + "dependencies": { + "minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } } }, "@typescript-eslint/utils": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.13.2.tgz", - "integrity": "sha512-b9Ptq4eAZUym4idijCRzl61oPCwwREcfDI8xGk751Vhzig5fFZR9CyzDz4Sp/nxSLBYxUPyh4QdIDqWykFhNmQ==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.13.2", - "@typescript-eslint/types": "6.13.2", - "@typescript-eslint/typescript-estree": "6.13.2", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", "semver": "^7.5.4" } }, "@typescript-eslint/visitor-keys": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.13.2.tgz", - "integrity": "sha512-OGznFs0eAQXJsp+xSd6k/O1UbFi/K/L7WjqeRoFE7vadjAF9y0uppXhYNQNEqygjou782maGClOoZwPqF0Drlw==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", "dev": true, "requires": { - "@typescript-eslint/types": "6.13.2", + "@typescript-eslint/types": "6.21.0", + "eslint-visitor-keys": "^3.4.1" + } + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, + "eslint-plugin-toml": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-toml/-/eslint-plugin-toml-0.10.0.tgz", + "integrity": "sha512-HzhRjePs4FDszPRY6ryHXV90MsSEkJsWnP175x33Iop/W6/hb80qjzImO5LlQfqhX3B0TkotOFSIigNI4AdGsw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "eslint-compat-utils": "^0.5.0", + "lodash": "^4.17.19", + "toml-eslint-parser": "^0.9.0" + } + }, + "eslint-plugin-unicorn": { + "version": "51.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-51.0.1.tgz", + "integrity": "sha512-MuR/+9VuB0fydoI0nIn2RDA5WISRn4AsJyNSaNKLVwie9/ONvQhxOBbkfSICBPnzKrB77Fh6CZZXjgTt/4Latw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.22.20", + "@eslint-community/eslint-utils": "^4.4.0", + "@eslint/eslintrc": "^2.1.4", + "ci-info": "^4.0.0", + "clean-regexp": "^1.0.0", + "core-js-compat": "^3.34.0", + "esquery": "^1.5.0", + "indent-string": "^4.0.0", + "is-builtin-module": "^3.2.1", + "jsesc": "^3.0.2", + "pluralize": "^8.0.0", + "read-pkg-up": "^7.0.1", + "regexp-tree": "^0.1.27", + "regjsparser": "^0.10.0", + "semver": "^7.5.4", + "strip-indent": "^3.0.0" + }, + "dependencies": { + "ci-info": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.0.0.tgz", + "integrity": "sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==", + "dev": true + }, + "jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true + } + } + }, + "eslint-plugin-unused-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-3.1.0.tgz", + "integrity": "sha512-9l1YFCzXKkw1qtAru1RWUtG2EVDZY0a0eChKXcL+EZ5jitG7qxdctu4RnvhOJHv4xfmUf7h+JJPINlVpGhZMrw==", + "dev": true, + "requires": { + "eslint-rule-composer": "^0.3.0" + } + }, + "eslint-plugin-vitest": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vitest/-/eslint-plugin-vitest-0.4.0.tgz", + "integrity": "sha512-3oWgZIwdWVBQ5plvkmOBjreIGLQRdYb7x54OP8uIRHeZyRVJIdOn9o/qWVb9292fDMC8jn7H7d9TSFBZqhrykQ==", + "dev": true, + "requires": { + "@typescript-eslint/utils": "^7.2.0" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.4.0.tgz", + "integrity": "sha512-68VqENG5HK27ypafqLVs8qO+RkNc7TezCduYrx8YJpXq2QGZ30vmNZGJJJC48+MVn4G2dCV8m5ZTVnzRexTVtw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "7.4.0", + "@typescript-eslint/visitor-keys": "7.4.0" + } + }, + "@typescript-eslint/types": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.4.0.tgz", + "integrity": "sha512-mjQopsbffzJskos5B4HmbsadSJQWaRK0UxqQ7GuNA9Ga4bEKeiO6b2DnB6cM6bpc8lemaPseh0H9B/wyg+J7rw==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.4.0.tgz", + "integrity": "sha512-A99j5AYoME/UBQ1ucEbbMEmGkN7SE0BvZFreSnTd1luq7yulcHdyGamZKizU7canpGDWGJ+Q6ZA9SyQobipePg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "7.4.0", + "@typescript-eslint/visitor-keys": "7.4.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/utils": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.4.0.tgz", + "integrity": "sha512-NQt9QLM4Tt8qrlBVY9lkMYzfYtNz8/6qwZg8pI3cMGlPnj6mOpRxxAm7BMJN9K0AiY+1BwJ5lVC650YJqYOuNg==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "7.4.0", + "@typescript-eslint/types": "7.4.0", + "@typescript-eslint/typescript-estree": "7.4.0", + "semver": "^7.5.4" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.4.0.tgz", + "integrity": "sha512-0zkC7YM0iX5Y41homUUeW1CHtZR01K3ybjM1l6QczoMuay0XKtrb93kv95AxUGwdjGr64nNqnOCwmEl616N8CA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "7.4.0", "eslint-visitor-keys": "^3.4.1" } }, @@ -23282,131 +24758,68 @@ } } }, - "eslint-plugin-unicorn": { - "version": "49.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-49.0.0.tgz", - "integrity": "sha512-0fHEa/8Pih5cmzFW5L7xMEfUTvI9WKeQtjmKpTUmY+BiFCDxkxrTdnURJOHKykhtwIeyYsxnecbGvDCml++z4Q==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.22.20", - "@eslint-community/eslint-utils": "^4.4.0", - "ci-info": "^3.8.0", - "clean-regexp": "^1.0.0", - "esquery": "^1.5.0", - "indent-string": "^4.0.0", - "is-builtin-module": "^3.2.1", - "jsesc": "^3.0.2", - "pluralize": "^8.0.0", - "read-pkg-up": "^7.0.1", - "regexp-tree": "^0.1.27", - "regjsparser": "^0.10.0", - "semver": "^7.5.4", - "strip-indent": "^3.0.0" - }, - "dependencies": { - "jsesc": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", - "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", - "dev": true - } - } - }, - "eslint-plugin-vitest": { - "version": "0.3.10", - "resolved": "https://registry.npmjs.org/eslint-plugin-vitest/-/eslint-plugin-vitest-0.3.10.tgz", - "integrity": "sha512-08lj4rdhZHYyHk+Py2nJ7SlE6arP8GNfGXl9jVqhe9s5JoZIGiBpIkLGX+VNBiB6vXTn56H6Ant7Koc6XzRjtQ==", - "dev": true, - "requires": { - "@typescript-eslint/utils": "^6.11.0" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.13.2.tgz", - "integrity": "sha512-CXQA0xo7z6x13FeDYCgBkjWzNqzBn8RXaE3QVQVIUm74fWJLkJkaHmHdKStrxQllGh6Q4eUGyNpMe0b1hMkXFA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.13.2", - "@typescript-eslint/visitor-keys": "6.13.2" - } - }, - "@typescript-eslint/types": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.13.2.tgz", - "integrity": "sha512-7sxbQ+EMRubQc3wTfTsycgYpSujyVbI1xw+3UMRUcrhSy+pN09y/lWzeKDbvhoqcRbHdc+APLs/PWYi/cisLPg==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.13.2.tgz", - "integrity": "sha512-SuD8YLQv6WHnOEtKv8D6HZUzOub855cfPnPMKvdM/Bh1plv1f7Q/0iFUDLKKlxHcEstQnaUU4QZskgQq74t+3w==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.13.2", - "@typescript-eslint/visitor-keys": "6.13.2", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/utils": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.13.2.tgz", - "integrity": "sha512-b9Ptq4eAZUym4idijCRzl61oPCwwREcfDI8xGk751Vhzig5fFZR9CyzDz4Sp/nxSLBYxUPyh4QdIDqWykFhNmQ==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.13.2", - "@typescript-eslint/types": "6.13.2", - "@typescript-eslint/typescript-estree": "6.13.2", - "semver": "^7.5.4" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.13.2.tgz", - "integrity": "sha512-OGznFs0eAQXJsp+xSd6k/O1UbFi/K/L7WjqeRoFE7vadjAF9y0uppXhYNQNEqygjou782maGClOoZwPqF0Drlw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.13.2", - "eslint-visitor-keys": "^3.4.1" - } - } - } - }, "eslint-plugin-vue": { - "version": "9.19.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.19.2.tgz", - "integrity": "sha512-CPDqTOG2K4Ni2o4J5wixkLVNwgctKXFu6oBpVJlpNq7f38lh9I80pRTouZSJ2MAebPJlINU/KTFSXyQfBUlymA==", + "version": "9.24.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.24.0.tgz", + "integrity": "sha512-9SkJMvF8NGMT9aQCwFc5rj8Wo1XWSMSHk36i7ZwdI614BU7sIOR28ZjuFPKp8YGymZN12BSEbiSwa7qikp+PBw==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", + "globals": "^13.24.0", "natural-compare": "^1.4.0", "nth-check": "^2.1.1", - "postcss-selector-parser": "^6.0.13", - "semver": "^7.5.4", - "vue-eslint-parser": "^9.3.1", + "postcss-selector-parser": "^6.0.15", + "semver": "^7.6.0", + "vue-eslint-parser": "^9.4.2", "xml-name-validator": "^4.0.0" + }, + "dependencies": { + "globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } } }, "eslint-plugin-yml": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-1.10.0.tgz", - "integrity": "sha512-53SUwuNDna97lVk38hL/5++WXDuugPM9SUQ1T645R0EHMRCdBIIxGye/oOX2qO3FQ7aImxaUZJU/ju+NMUBrLQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-1.13.2.tgz", + "integrity": "sha512-1i71VhmsG5UxE41rIJmJjhlTTxYy7upAY5Hqj8AdBc7rfJzRIZr3a2spuOS8+N7ZDCWsHAWY3J6lzQNQHDv6Uw==", "dev": true, "requires": { "debug": "^4.3.2", - "eslint-compat-utils": "^0.1.0", + "eslint-compat-utils": "^0.5.0", "lodash": "^4.17.21", "natural-compare": "^1.4.0", "yaml-eslint-parser": "^1.2.1" } }, + "eslint-processor-vue-blocks": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/eslint-processor-vue-blocks/-/eslint-processor-vue-blocks-0.1.1.tgz", + "integrity": "sha512-9+dU5lU881log570oBwpelaJmOfOzSniben7IWEDRYQPPWwlvaV7NhOtsTuUWDqpYT+dtKKWPsgz4OkOi+aZnA==", + "dev": true, + "requires": {} + }, "eslint-rule-composer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz", @@ -23486,6 +24899,13 @@ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true }, + "estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "peer": true + }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -23912,9 +25332,9 @@ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==" }, "get-tsconfig": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz", - "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==", + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz", + "integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==", "dev": true, "requires": { "resolve-pkg-maps": "^1.0.0" @@ -24003,21 +25423,10 @@ } }, "globals": { - "version": "13.23.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", - "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - }, - "dependencies": { - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - } - } + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.0.0.tgz", + "integrity": "sha512-m/C/yR4mjO6pXDTm9/R/SpYTAIyaUB4EOzcaaMEl7mds7Mshct9GfejiJNQGjHHbdMPey13Kpu4TMbYi9ex1pw==", + "dev": true }, "globby": { "version": "11.1.0", @@ -25216,8 +26625,7 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "peer": true + "dev": true }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -25672,6 +27080,25 @@ "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", "dev": true }, + "magic-string": { + "version": "0.30.8", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", + "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", + "dev": true, + "peer": true, + "requires": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "dependencies": { + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true, + "peer": true + } + } + }, "make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", @@ -26140,9 +27567,9 @@ } }, "node-releases": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", "dev": true }, "nodemailer": { @@ -26561,10 +27988,31 @@ "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", "dev": true }, + "postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "dev": true, + "peer": true, + "requires": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "dependencies": { + "nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "peer": true + } + } + }, "postcss-selector-parser": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", - "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", + "version": "6.0.16", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz", + "integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==", "dev": true, "requires": { "cssesc": "^3.0.0", @@ -27429,6 +28877,13 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, + "source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, + "peer": true + }, "source-map-support": { "version": "0.5.13", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", @@ -27748,6 +29203,23 @@ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true }, + "synckit": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.6.2.tgz", + "integrity": "sha512-Vhf+bUa//YSTYKseDiiEuQmhGCoIF3CVBhunm3r/DQnYiGT4JssmnKQc44BIyOZRK2pKjXXAgbhfmbeoC9CJpA==", + "dev": true, + "requires": { + "tslib": "^2.3.1" + }, + "dependencies": { + "tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + } + } + }, "test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -27823,6 +29295,15 @@ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" }, + "toml-eslint-parser": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/toml-eslint-parser/-/toml-eslint-parser-0.9.3.tgz", + "integrity": "sha512-moYoCvkNUAPCxSW9jmHmRElhm4tVJpHL8ItC/+uYD0EpPSFXbck7yREz9tNdJVTSpHVod8+HoipcpbQ0oE6gsw==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^3.0.0" + } + }, "toposort": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", @@ -28030,6 +29511,12 @@ "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", "dev": true }, + "unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true + }, "unist-util-stringify-position": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", @@ -28138,9 +29625,9 @@ "dev": true }, "vue-eslint-parser": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.3.2.tgz", - "integrity": "sha512-q7tWyCVaV9f8iQyIA5Mkj/S6AoJ9KBN8IeUSf3XEmBrOtxOZnfTg5s4KClbZBCK3GtnT/+RyCLZyDHuZwTuBjg==", + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz", + "integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==", "dev": true, "requires": { "debug": "^4.3.4", @@ -28315,9 +29802,9 @@ }, "dependencies": { "yaml": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.3.tgz", - "integrity": "sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz", + "integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==", "dev": true } } diff --git a/package.json b/package.json index 4ff9a9e0a..9ccd97000 100644 --- a/package.json +++ b/package.json @@ -143,7 +143,7 @@ "yup": "^1.3.2" }, "devDependencies": { - "@antfu/eslint-config": "2.3.4", + "@antfu/eslint-config": "2.11.4", "@commitlint/cli": "^17.7.2", "@commitlint/config-conventional": "^17.7.0", "@inrupt/solid-client-authn-core": "^2.0.0", diff --git a/src/http/representation/RepresentationMetadata.ts b/src/http/representation/RepresentationMetadata.ts index 55271ce82..9dc866fc9 100644 --- a/src/http/representation/RepresentationMetadata.ts +++ b/src/http/representation/RepresentationMetadata.ts @@ -300,7 +300,7 @@ export class RepresentationMetadata { predicate: Term | string | null, object: Term | string | null, graph: Term | string | null) => boolean; - }).has(this.id, predicate, object, graph) as boolean; + }).has(this.id, predicate, object, graph); } /** diff --git a/src/storage/mapping/ExtensionBasedMapper.ts b/src/storage/mapping/ExtensionBasedMapper.ts index 98f1a16d3..4b59e77c2 100644 --- a/src/storage/mapping/ExtensionBasedMapper.ts +++ b/src/storage/mapping/ExtensionBasedMapper.ts @@ -84,7 +84,7 @@ export class ExtensionBasedMapper extends BaseFileIdentifierMapper { const extension = getExtension(filePath).toLowerCase(); return mime.lookup(extension) || this.customTypes[extension] || - await super.getContentTypeFromPath(filePath); + await super.getContentTypeFromPath(filePath); } /** diff --git a/src/util/GuardedStream.ts b/src/util/GuardedStream.ts index 3a64c4bc2..a659bffd9 100644 --- a/src/util/GuardedStream.ts +++ b/src/util/GuardedStream.ts @@ -55,7 +55,7 @@ function emitStoredErrors(this: Guarded, event: string, func: (error: Error) => if (event === 'error' && func !== guardingErrorListener) { // Cancel an error timeout if (this[guardedTimeout]) { - clearTimeout(this[guardedTimeout]!); + clearTimeout(this[guardedTimeout]); this[guardedTimeout] = undefined; } diff --git a/src/util/errors/ErrorUtil.ts b/src/util/errors/ErrorUtil.ts index b6965e65e..2ce634cc1 100644 --- a/src/util/errors/ErrorUtil.ts +++ b/src/util/errors/ErrorUtil.ts @@ -7,8 +7,8 @@ export function isError(error: unknown): error is Error { return types.isNativeError(error) || (Boolean(error) && typeof (error as Error).name === 'string' && - typeof (error as Error).message === 'string' && - (typeof (error as Error).stack === 'undefined' || typeof (error as Error).stack === 'string')); + typeof (error as Error).message === 'string' && + (typeof (error as Error).stack === 'undefined' || typeof (error as Error).stack === 'string')); } /** diff --git a/src/util/errors/HttpError.ts b/src/util/errors/HttpError.ts index 8a6a42b55..e1c97e502 100644 --- a/src/util/errors/HttpError.ts +++ b/src/util/errors/HttpError.ts @@ -48,7 +48,7 @@ export class HttpError extends Error implements HttpE public static isInstance(error: unknown): error is HttpError { return isError(error) && typeof (error as HttpError).statusCode === 'number' && - Boolean((error as HttpError).metadata); + Boolean((error as HttpError).metadata); } /** diff --git a/test/unit/server/util/RedirectingHttpHandler.test.ts b/test/unit/server/util/RedirectingHttpHandler.test.ts index 5f043f789..5834c4697 100644 --- a/test/unit/server/util/RedirectingHttpHandler.test.ts +++ b/test/unit/server/util/RedirectingHttpHandler.test.ts @@ -17,7 +17,7 @@ describe('A RedirectingHttpHandler', (): void => { beforeEach(async(): Promise => { targetExtractor = { - handleSafe: jest.fn(({ request: req }): ResourceIdentifier => ({ path: joinUrl(baseUrl, req.url!) })), + handleSafe: jest.fn(({ request: req }): ResourceIdentifier => ({ path: joinUrl(baseUrl, req.url) })), } as any; responseWriter = { handleSafe: jest.fn() } as any; diff --git a/test/unit/server/util/RouterHandler.test.ts b/test/unit/server/util/RouterHandler.test.ts index 418b3c655..638e952ff 100644 --- a/test/unit/server/util/RouterHandler.test.ts +++ b/test/unit/server/util/RouterHandler.test.ts @@ -14,7 +14,7 @@ describe('A RouterHandler', (): void => { request = { method: 'GET', url: '/test' } as any; targetExtractor = { - handleSafe: jest.fn(({ request: req }): ResourceIdentifier => ({ path: joinUrl(baseUrl, req.url!) })), + handleSafe: jest.fn(({ request: req }): ResourceIdentifier => ({ path: joinUrl(baseUrl, req.url) })), } as any; handler = { diff --git a/test/unit/util/PathUtil.test.ts b/test/unit/util/PathUtil.test.ts index b2938d989..36cb10754 100644 --- a/test/unit/util/PathUtil.test.ts +++ b/test/unit/util/PathUtil.test.ts @@ -210,7 +210,7 @@ describe('PathUtil', (): void => { beforeEach((): void => { targetExtractor = { - handleSafe: jest.fn(({ request: req }): ResourceIdentifier => ({ path: joinUrl(baseUrl, req.url!) })), + handleSafe: jest.fn(({ request: req }): ResourceIdentifier => ({ path: joinUrl(baseUrl, req.url) })), } as any; }); From cac70b1f88dcbbb3ebbe0b8e0b082ead4ab27b33 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Fri, 29 Mar 2024 13:27:26 +0100 Subject: [PATCH 32/71] refactor: Simplify eslint configs --- eslint.config.js | 39 ++++++----- eslint/file-names.js | 33 ++++++++++ eslint/general.js | 1 + eslint/test.js | 2 +- eslint/typed.js | 154 ++++++++++++++----------------------------- eslint/unicorn.js | 13 +--- 6 files changed, 109 insertions(+), 133 deletions(-) create mode 100644 eslint/file-names.js diff --git a/eslint.config.js b/eslint.config.js index 1952bfbbf..cc1658728 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,4 +1,5 @@ const antfu = require('@antfu/eslint-config'); +const fileNamesConfig = require('./eslint/file-names'); const generalConfig = require('./eslint/general'); const testConfig = require('./eslint/test'); const typedConfig = require('./eslint/typed'); @@ -16,36 +17,40 @@ module.exports = antfu.default( { // Don't want to lint test assets, or TS snippets in markdown files ignores: [ 'test/assets/*', '**/*.md/**/*.ts' ], + typescript: { + tsconfigPath: [ './tsconfig.json', './scripts/tsconfig.json', './test/tsconfig.json' ], + }, }, - generalConfig, - unicornConfig, - typedConfig({ - project: [ './tsconfig.json', './scripts/tsconfig.json', './test/tsconfig.json' ], - tsconfigRootDir: __dirname, - }), - testConfig, - { - // JSON rules - files: [ '**/*.json' ], +) + .append(generalConfig) + .append(unicornConfig) + .append(fileNamesConfig) + // Using an override here so all the type settings are also applied correctly + .override('antfu:typescript:rules-type-aware', typedConfig) + .append({ + ...testConfig, + files: [ 'test/**/*.ts' ], + }) + .override('antfu:jsonc:rules', { rules: { + // Consistent with how we do it in code 'jsonc/array-bracket-spacing': [ 'error', 'always', { singleValue: true, objectsInArrays: false, arraysInArrays: false, }], }, - }, - { + }) + .append({ // This is necessary to prevent filename checks caused by JSON being present in a README. files: [ '**/README.md/**' ], rules: { 'unicorn/filename-case': 'off', }, - }, - { - files: [ '**/*.md' ], + }) + .override('antfu:markdown:parser', { rules: { + // We want to be able to use these in Markdown text 'no-irregular-whitespace': 'off', }, - }, -); + }); diff --git a/eslint/file-names.js b/eslint/file-names.js new file mode 100644 index 000000000..e67704730 --- /dev/null +++ b/eslint/file-names.js @@ -0,0 +1,33 @@ +module.exports = [ + { + name: 'opinionated:file-names:all', + rules: { + 'unicorn/filename-case': [ 'error', { + cases: { + camelCase: false, + pascalCase: false, + kebabCase: true, + snakeCase: false, + }, + ignore: [ + // CODE_OF_CONDUCT.md, etc. + /[A-Z_]+\.md$/u, + ], + }], + }, + }, + { + name: 'opinionated:file-names:ts', + files: [ '**/*.ts' ], + rules: { + 'unicorn/filename-case': [ 'error', { + cases: { + camelCase: true, + pascalCase: true, + kebabCase: false, + snakeCase: false, + }, + }], + }, + }, +]; diff --git a/eslint/general.js b/eslint/general.js index 182f806ec..04fd2c106 100644 --- a/eslint/general.js +++ b/eslint/general.js @@ -1,4 +1,5 @@ module.exports = { + name: 'opinionated:general', rules: { 'antfu/consistent-list-newline': 'error', diff --git a/eslint/test.js b/eslint/test.js index c62c4efe5..4ea6939e9 100644 --- a/eslint/test.js +++ b/eslint/test.js @@ -2,11 +2,11 @@ const jest = require('eslint-plugin-jest'); // Specifically for tests module.exports = { + name: 'opinionated:test', // See https://github.com/jest-community/eslint-plugin-jest/issues/1408 plugins: { jest, }, - files: [ 'test/**/*.ts' ], rules: { ...jest.configs.all.rules, // Rule is not smart enough to check called function in the test diff --git a/eslint/typed.js b/eslint/typed.js index bf925de74..47a3d0b74 100644 --- a/eslint/typed.js +++ b/eslint/typed.js @@ -1,106 +1,54 @@ -// Copied from https://github.com/antfu/eslint-config/blob/main/src/configs/typescript.ts -// Doing it like this, so we can make sure these only try to trigger on *.ts files, -// Preventing issues with the *.js files. -const typeAwareRules = { - 'dot-notation': 'off', - 'no-implied-eval': 'off', - 'no-throw-literal': 'off', - 'ts/await-thenable': 'error', - 'ts/dot-notation': [ 'error', { allowKeywords: true }], - 'ts/no-floating-promises': 'error', - 'ts/no-for-in-array': 'error', - 'ts/no-implied-eval': 'error', - 'ts/no-misused-promises': 'error', - 'ts/no-throw-literal': 'error', - 'ts/no-unnecessary-type-arguments': 'error', - 'ts/no-unnecessary-type-assertion': 'error', - 'ts/no-unsafe-argument': 'error', - 'ts/no-unsafe-assignment': 'error', - 'ts/no-unsafe-call': 'error', - 'ts/no-unsafe-member-access': 'error', - 'ts/no-unsafe-return': 'error', - 'ts/restrict-plus-operands': 'error', - 'ts/restrict-template-expressions': 'error', - 'ts/unbound-method': 'error', -}; - -const defaults = { - project: [ './tsconfig.json' ], - files: [ '**/*.ts' ], - tsconfigRootDir: process.cwd(), -}; - -module.exports = function(options) { - options = { ...defaults, ...options }; - return { - // By default, antfu also triggers type rules on *.js files which causes all kinds of issues for us - files: options.files, - languageOptions: { - parserOptions: { - tsconfigRootDir: options.tsconfigRootDir, - project: options.project, +module.exports = { + rules: { + 'ts/consistent-type-assertions': [ 'error', { + assertionStyle: 'as', + }], + 'ts/naming-convention': [ + 'error', + { + selector: 'default', + format: [ 'camelCase' ], + leadingUnderscore: 'forbid', + trailingUnderscore: 'forbid', }, - }, - rules: { - ...typeAwareRules, - 'ts/consistent-type-assertions': [ 'error', { - assertionStyle: 'as', - }], - 'ts/naming-convention': [ - 'error', - { - selector: 'default', - format: [ 'camelCase' ], - leadingUnderscore: 'forbid', - trailingUnderscore: 'forbid', - }, - { - selector: 'import', - format: null, - }, - { - selector: 'variable', - format: [ 'camelCase', 'UPPER_CASE' ], - leadingUnderscore: 'forbid', - trailingUnderscore: 'forbid', - }, - { - selector: 'typeLike', - format: [ 'PascalCase' ], - }, - { - selector: [ 'typeParameter' ], - format: [ 'PascalCase' ], - prefix: [ 'T' ], - }, - ], - 'ts/explicit-function-return-type': [ 'error', { - allowExpressions: false, - allowTypedFunctionExpressions: false, - allowHigherOrderFunctions: false, - }], - 'ts/no-base-to-string': 'error', - 'ts/no-floating-promises': [ 'error', { ignoreVoid: false }], - 'ts/promise-function-async': 'error', - 'ts/no-unnecessary-boolean-literal-compare': 'error', - 'ts/no-unnecessary-qualifier': 'error', - 'ts/prefer-nullish-coalescing': 'error', - 'ts/prefer-readonly': 'error', - 'ts/prefer-reduce-type-parameter': 'error', - 'ts/prefer-regexp-exec': 'error', - 'ts/prefer-string-starts-ends-with': 'error', - 'ts/require-array-sort-compare': 'error', + { + selector: 'import', + format: null, + }, + { + selector: 'variable', + format: [ 'camelCase', 'UPPER_CASE' ], + leadingUnderscore: 'forbid', + trailingUnderscore: 'forbid', + }, + { + selector: 'typeLike', + format: [ 'PascalCase' ], + }, + { + selector: [ 'typeParameter' ], + format: [ 'PascalCase' ], + prefix: [ 'T' ], + }, + ], + 'ts/explicit-function-return-type': [ 'error', { + allowExpressions: false, + allowTypedFunctionExpressions: false, + allowHigherOrderFunctions: false, + }], + 'ts/no-base-to-string': 'error', + 'ts/no-floating-promises': [ 'error', { ignoreVoid: false }], + 'ts/promise-function-async': 'error', + 'ts/no-unnecessary-boolean-literal-compare': 'error', + 'ts/no-unnecessary-qualifier': 'error', + 'ts/prefer-nullish-coalescing': 'error', + 'ts/prefer-readonly': 'error', + 'ts/prefer-reduce-type-parameter': 'error', + 'ts/prefer-regexp-exec': 'error', + 'ts/prefer-string-starts-ends-with': 'error', + 'ts/require-array-sort-compare': 'error', - // These are not type specific, but we only care about these in TS files - 'max-len': [ 'error', { code: 120, ignoreUrls: true }], - 'unicorn/filename-case': [ 'error', { - cases: { - camelCase: true, - pascalCase: true, - kebabCase: false, - snakeCase: false, - }, - }], - }, - }; + // These are not type specific, but we only care about these in TS files + 'max-len': [ 'error', { code: 120, ignoreUrls: true }], + }, }; diff --git a/eslint/unicorn.js b/eslint/unicorn.js index 7ccb36155..5371b1a97 100644 --- a/eslint/unicorn.js +++ b/eslint/unicorn.js @@ -1,4 +1,5 @@ module.exports = { + name: 'opinionated:unicorn', rules: { 'unicorn/better-regex': 'error', 'unicorn/empty-brace-spaces': 'error', @@ -9,18 +10,6 @@ module.exports = { allowWarningComments: false, }], 'unicorn/explicit-length-check': 'error', - 'unicorn/filename-case': [ 'error', { - cases: { - camelCase: false, - pascalCase: false, - kebabCase: true, - snakeCase: false, - }, - ignore: [ - // CODE_OF_CONDUCT.md, etc. - /[A-Z_]+\.md$/u, - ], - }], 'unicorn/new-for-builtins': 'error', 'unicorn/no-array-for-each': 'error', 'unicorn/no-array-reduce': 'error', From 486241f3d496a972518474f0be74b79a11e2db2b Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Tue, 2 Apr 2024 09:06:58 +0200 Subject: [PATCH 33/71] docs: Fix language Co-authored-by: Ted Thibodeau Jr --- src/identity/configuration/IdentityProviderFactory.ts | 2 +- src/identity/interaction/YupUtil.ts | 4 ++-- src/identity/interaction/login/ResolveLoginHandler.ts | 2 +- src/init/AppRunner.ts | 2 +- src/pods/generate/ComponentsJsFactory.ts | 2 +- src/storage/DataAccessorBasedStore.ts | 10 +++++----- src/storage/ResourceSet.ts | 2 +- src/storage/conversion/ConversionUtil.ts | 2 +- src/storage/keyvalue/KeyValueStorage.ts | 2 +- src/storage/mapping/BaseFileIdentifierMapper.ts | 2 +- src/storage/mapping/FileIdentifierMapper.ts | 6 +++--- src/util/HeaderUtil.ts | 2 +- src/util/PathUtil.ts | 4 ++-- src/util/StreamUtil.ts | 2 +- src/util/StringUtil.ts | 2 +- src/util/errors/HttpError.ts | 2 +- src/util/handlers/AsyncHandler.ts | 2 +- src/util/handlers/WaterfallHandler.ts | 2 +- src/util/locking/ResourceLocker.ts | 2 +- 19 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/identity/configuration/IdentityProviderFactory.ts b/src/identity/configuration/IdentityProviderFactory.ts index 094750a4a..1f9f48948 100644 --- a/src/identity/configuration/IdentityProviderFactory.ts +++ b/src/identity/configuration/IdentityProviderFactory.ts @@ -260,7 +260,7 @@ export class IdentityProviderFactory implements ProviderFactory { } /** - * Checks if the given token is an access token. + * Checks whether the given token is an access token. * The AccessToken interface is not exported, so we have to access it like this. */ private isAccessToken(token: unknown): token is KoaContextWithOIDC['oidc']['accessToken'] { diff --git a/src/identity/interaction/YupUtil.ts b/src/identity/interaction/YupUtil.ts index 242818658..a32da5fdc 100644 --- a/src/identity/interaction/YupUtil.ts +++ b/src/identity/interaction/YupUtil.ts @@ -9,8 +9,8 @@ import Dict = NodeJS.Dict; type BaseObjectSchema = ObjectSchema>; // The builtin `url` validator of `yup` does not support localhost URLs, so we create a custom one here. -// The reason for having a URL validator on the WebID is to prevent us from generating invalid ACL, -// which would break the pod creation causing us to have an incomplete pod. +// We validate the WebID URL to prevent generation of invalid ACL, +// which would break the pod creation, causing us to have an incomplete pod. export const URL_SCHEMA = string().trim().optional().test({ name: 'url', message: (value: { value: string }): string => `"${value.value}" is not a valid URL`, diff --git a/src/identity/interaction/login/ResolveLoginHandler.ts b/src/identity/interaction/login/ResolveLoginHandler.ts index 6968379c1..792877e16 100644 --- a/src/identity/interaction/login/ResolveLoginHandler.ts +++ b/src/identity/interaction/login/ResolveLoginHandler.ts @@ -81,7 +81,7 @@ export abstract class ResolveLoginHandler extends JsonInteractionHandler { } /** - * Updates the account setting that determines if the login status needs to be remembered. + * Updates the account setting that determines whether the login status needs to be remembered. * * @param accountId - ID of the account. * @param remember - If the account should be remembered or not. The setting will not be updated if this is undefined. diff --git a/src/init/AppRunner.ts b/src/init/AppRunner.ts index ed5bca6ba..8f09efbd7 100644 --- a/src/init/AppRunner.ts +++ b/src/init/AppRunner.ts @@ -226,7 +226,7 @@ export class AppRunner { return import(cssConfigPathJs) as Promise>; } - // Finally try and read from the config.community-solid-server + // Finally try to read from the config.community-solid-server // field in the root package.json const pkg = await readJSON(packageJsonPath) as { config?: Record }; if (typeof pkg.config?.['community-solid-server'] === 'object') { diff --git a/src/pods/generate/ComponentsJsFactory.ts b/src/pods/generate/ComponentsJsFactory.ts index 978217e8f..224bf793d 100644 --- a/src/pods/generate/ComponentsJsFactory.ts +++ b/src/pods/generate/ComponentsJsFactory.ts @@ -6,7 +6,7 @@ export interface ComponentsJsFactory { * Instantiates a new object using Components.js. * * @param configPath - Location of the config to instantiate. - * @param componentIri - Iri of the object in the config that will be the result. + * @param componentIri - IRI of the object in the config that will be the result. * @param variables - Variables to send to Components.js * * @returns The resulting object, corresponding to the given component IRI. diff --git a/src/storage/DataAccessorBasedStore.ts b/src/storage/DataAccessorBasedStore.ts index d0d232122..111e7ea15 100644 --- a/src/storage/DataAccessorBasedStore.ts +++ b/src/storage/DataAccessorBasedStore.ts @@ -374,7 +374,7 @@ export class DataAccessorBasedStore implements ResourceStore { * then the other URI MUST NOT correspond to another resource." * https://solid.github.io/specification/protocol#uri-slash-semantics * - * First the identifier gets requested and if no result is found + * First the identifier gets requested. If no result is found, * the identifier with differing trailing slash is requested. * * @param identifier - Identifier that needs to be checked. @@ -452,7 +452,7 @@ export class DataAccessorBasedStore implements ResourceStore { /** * Write the given resource to the DataAccessor. Metadata will be updated with necessary triples. - * In case of containers `handleContainerData` will be used to verify the data. + * For containers, `handleContainerData` will be used to verify the data. * * @param identifier - Identifier of the resource. * @param representation - Corresponding Representation. @@ -590,8 +590,8 @@ export class DataAccessorBasedStore implements ResourceStore { } /** - * Clean http Slug to be compatible with the server. Makes sure there are no unwanted characters - * e.g.: cleanslug('&%26') returns '%26%26' + * Clean http Slug to be compatible with the server. Makes sure there are no unwanted characters, + * e.g., cleanslug('&%26') returns '%26%26' * * @param slug - the slug to clean */ @@ -636,7 +636,7 @@ export class DataAccessorBasedStore implements ResourceStore { } /** - * Checks if the given metadata represents a (potential) container, + * Checks whether the given metadata represents a (potential) container, * based on the metadata. * * @param metadata - Metadata of the (new) resource. diff --git a/src/storage/ResourceSet.ts b/src/storage/ResourceSet.ts index c093000bc..12e20e1e9 100644 --- a/src/storage/ResourceSet.ts +++ b/src/storage/ResourceSet.ts @@ -5,7 +5,7 @@ import type { ResourceIdentifier } from '../http/representation/ResourceIdentifi */ export interface ResourceSet { /** - * Check if a resource exists in this ResourceSet. + * Checks whether a resource exists in this ResourceSet. * * @param identifier - Identifier of resource to check. * diff --git a/src/storage/conversion/ConversionUtil.ts b/src/storage/conversion/ConversionUtil.ts index 8d5eba862..b02125f95 100644 --- a/src/storage/conversion/ConversionUtil.ts +++ b/src/storage/conversion/ConversionUtil.ts @@ -162,7 +162,7 @@ export function matchesMediaPreferences(type: string, preferred?: ValuePreferenc } /** - * Checks if the given two media types/ranges match each other. + * Checks whether the given two media types/ranges match each other. * Takes wildcards into account. * * @param mediaA - Media type to match. diff --git a/src/storage/keyvalue/KeyValueStorage.ts b/src/storage/keyvalue/KeyValueStorage.ts index e98889865..9f037960c 100644 --- a/src/storage/keyvalue/KeyValueStorage.ts +++ b/src/storage/keyvalue/KeyValueStorage.ts @@ -12,7 +12,7 @@ export interface KeyValueStorage { get: (key: TKey) => Promise; /** - * Checks if there is a value stored for the given key. + * Checks whether there is a value stored for the given key. * * @param identifier - Identifier to check. */ diff --git a/src/storage/mapping/BaseFileIdentifierMapper.ts b/src/storage/mapping/BaseFileIdentifierMapper.ts index c4c0540c9..001befaf0 100644 --- a/src/storage/mapping/BaseFileIdentifierMapper.ts +++ b/src/storage/mapping/BaseFileIdentifierMapper.ts @@ -201,7 +201,7 @@ export class BaseFileIdentifierMapper implements FileIdentifierMapper { } /** - * Check if the given relative path is valid. + * Check whether the given relative path is valid. * * @param path - A relative path, as generated by {@link getRelativePath}. * @param identifier - A resource identifier. diff --git a/src/storage/mapping/FileIdentifierMapper.ts b/src/storage/mapping/FileIdentifierMapper.ts index 4c4bf1556..0bcd1604b 100644 --- a/src/storage/mapping/FileIdentifierMapper.ts +++ b/src/storage/mapping/FileIdentifierMapper.ts @@ -34,9 +34,9 @@ export interface FileIdentifierMapper { mapFilePathToUrl: (filePath: string, isContainer: boolean) => Promise; /** * Maps the given resource identifier / URL to a file path. - * Determines the content-type if no content-type was provided by finding the corresponding file. - * If there is no corresponding file a file path will be generated. - * For containers the content-type input gets ignored. + * Determines the content-type, if no content-type was provided, by finding the corresponding file. + * If there is no corresponding file, a file path will be generated. + * For containers, the content-type input gets ignored. * * @param identifier - The input identifier. * @param isMetadata - If we are mapping the metadata of the resource instead of its data. diff --git a/src/util/HeaderUtil.ts b/src/util/HeaderUtil.ts index 00cf20f84..443a4709a 100644 --- a/src/util/HeaderUtil.ts +++ b/src/util/HeaderUtil.ts @@ -503,7 +503,7 @@ export function matchesAuthorizationScheme(scheme: string, authorization?: strin * Checks if the scheme part of the specified url matches at least one of the provided options. * * @param url - A string representing the URL. - * @param schemes - Scheme value options (the function will check if at least one matches the URL scheme). + * @param schemes - Scheme value options (the function will check whether at least one matches the URL scheme). * * @returns True if the URL scheme matches at least one of the provided options, false otherwise. */ diff --git a/src/util/PathUtil.ts b/src/util/PathUtil.ts index d6ede69b9..393b39a16 100644 --- a/src/util/PathUtil.ts +++ b/src/util/PathUtil.ts @@ -203,7 +203,7 @@ export function encodeUriPathComponents(path: string): string { } /** - * Checks if the path corresponds to a container path (ending in a /). + * Checks whether the path corresponds to a container path (ending in a /). * * @param path - Path to check. */ @@ -214,7 +214,7 @@ export function isContainerPath(path: string): boolean { } /** - * Checks if the identifier corresponds to a container identifier. + * Checks whether the identifier corresponds to a container identifier. * * @param identifier - Identifier to check. */ diff --git a/src/util/StreamUtil.ts b/src/util/StreamUtil.ts index 3bfa47aab..5bb7830fc 100644 --- a/src/util/StreamUtil.ts +++ b/src/util/StreamUtil.ts @@ -80,7 +80,7 @@ const safeErrors = new Set([ /** * Pipes one stream into another and emits errors of the first stream with the second. - * In case of an error in the first stream the second one will be destroyed with the given error. + * If the first stream errors, the second one will be destroyed with the given error. * This will also make the stream {@link Guarded}. * * @param readable - Initial readable stream. diff --git a/src/util/StringUtil.ts b/src/util/StringUtil.ts index fdfcaab52..54dbb3272 100644 --- a/src/util/StringUtil.ts +++ b/src/util/StringUtil.ts @@ -32,7 +32,7 @@ export function isValidFileName(name: string): boolean { } /** - * Checks if the given string is a valid URL. + * Checks whether the given string is a valid URL. * * @param url - String to check. * diff --git a/src/util/errors/HttpError.ts b/src/util/errors/HttpError.ts index e1c97e502..e63da2d16 100644 --- a/src/util/errors/HttpError.ts +++ b/src/util/errors/HttpError.ts @@ -76,7 +76,7 @@ export interface HttpErrorClass { */ readonly uri: NamedNode; /** - * Checks if the given error is an instance of this class. + * Checks whether the given error is an instance of this class. */ readonly isInstance: (error: unknown) => error is HttpError; } diff --git a/src/util/handlers/AsyncHandler.ts b/src/util/handlers/AsyncHandler.ts index b8110563c..da4ffc6ef 100644 --- a/src/util/handlers/AsyncHandler.ts +++ b/src/util/handlers/AsyncHandler.ts @@ -7,7 +7,7 @@ export type AsyncHandlerOutput> = Await */ export abstract class AsyncHandler { /** - * Checks if the input can be handled by this class. + * Checks whether the input can be handled by this class. * If it cannot handle the input, rejects with an error explaining why. * * @param input - Input that could potentially be handled. diff --git a/src/util/handlers/WaterfallHandler.ts b/src/util/handlers/WaterfallHandler.ts index e0973c468..229951aee 100644 --- a/src/util/handlers/WaterfallHandler.ts +++ b/src/util/handlers/WaterfallHandler.ts @@ -24,7 +24,7 @@ export class WaterfallHandler implements AsyncHandler { } /** - * Checks if any of the stored handlers can handle the given input. + * Checks whether any of the stored handlers can handle the given input. * * @param input - The data that would need to be handled. * diff --git a/src/util/locking/ResourceLocker.ts b/src/util/locking/ResourceLocker.ts index 575200ab7..a2028e815 100644 --- a/src/util/locking/ResourceLocker.ts +++ b/src/util/locking/ResourceLocker.ts @@ -17,7 +17,7 @@ export interface ResourceLocker { /** * Releases a lock on the requested identifier. * The promise will resolve when the lock has been released. - * In case there is no lock on the resource an error should be thrown. + * If there is no lock on the resource, an error should be thrown. * * @param identifier - Resource to release the lock on. */ From 419312ee5f4790881a5d101afea7ab6ca88f5e61 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Wed, 3 Apr 2024 15:46:01 +0200 Subject: [PATCH 34/71] feat: Store original target in error metadata --- .../ldp/handler/components/error-handler.json | 34 ++++++++------ .../error/TargetExtractorErrorHandler.ts | 30 ++++++++++++ src/index.ts | 1 + src/util/Vocabularies.ts | 1 + .../error/TargetExtractorErrorHandler.test.ts | 47 +++++++++++++++++++ 5 files changed, 99 insertions(+), 14 deletions(-) create mode 100644 src/http/output/error/TargetExtractorErrorHandler.ts create mode 100644 test/unit/http/output/error/TargetExtractorErrorHandler.test.ts diff --git a/config/ldp/handler/components/error-handler.json b/config/ldp/handler/components/error-handler.json index d3d1acc77..e0c498983 100644 --- a/config/ldp/handler/components/error-handler.json +++ b/config/ldp/handler/components/error-handler.json @@ -7,20 +7,26 @@ "@type": "SafeErrorHandler", "showStackTrace": { "@id": "urn:solid-server:default:variable:showStackTrace" }, "errorHandler": { - "@type": "WaterfallHandler", - "handlers": [ - { - "comment": "Internally redirects are created by throwing a specific error, this handler converts them to the correct response.", - "@type": "RedirectingErrorHandler" - }, - { - "comment": "Converts an Error object into a representation for an HTTP response.", - "@type": "ConvertingErrorHandler", - "converter": { "@id": "urn:solid-server:default:UiEnabledConverter" }, - "preferenceParser": { "@id": "urn:solid-server:default:PreferenceParser" }, - "showStackTrace": { "@id": "urn:solid-server:default:variable:showStackTrace" } - } - ] + "@id": "urn:solid-server:default:TargetExtractorErrorHandler", + "@type": "TargetExtractorErrorHandler", + "targetExtractor": { "@id": "urn:solid-server:default:TargetExtractor" }, + "errorHandler": { + "@id": "urn:solid-server:default:WaterfallErrorHandler", + "@type": "WaterfallHandler", + "handlers": [ + { + "comment": "Internally redirects are created by throwing a specific error, this handler converts them to the correct response.", + "@type": "RedirectingErrorHandler" + }, + { + "comment": "Converts an Error object into a representation for an HTTP response.", + "@type": "ConvertingErrorHandler", + "converter": { "@id": "urn:solid-server:default:UiEnabledConverter" }, + "preferenceParser": { "@id": "urn:solid-server:default:PreferenceParser" }, + "showStackTrace": { "@id": "urn:solid-server:default:variable:showStackTrace" } + } + ] + } } } ] diff --git a/src/http/output/error/TargetExtractorErrorHandler.ts b/src/http/output/error/TargetExtractorErrorHandler.ts new file mode 100644 index 000000000..089e0a69a --- /dev/null +++ b/src/http/output/error/TargetExtractorErrorHandler.ts @@ -0,0 +1,30 @@ +import { DataFactory } from 'n3'; +import { SOLID_ERROR } from '../../../util/Vocabularies'; +import type { TargetExtractor } from '../../input/identifier/TargetExtractor'; +import type { ResponseDescription } from '../response/ResponseDescription'; +import type { ErrorHandlerArgs } from './ErrorHandler'; +import { ErrorHandler } from './ErrorHandler'; + +/** + * Adds metadata to an error to indicate what the identifier was of the resource originally being targeted. + */ +export class TargetExtractorErrorHandler extends ErrorHandler { + protected readonly errorHandler: ErrorHandler; + protected readonly targetExtractor: TargetExtractor; + + public constructor(errorHandler: ErrorHandler, targetExtractor: TargetExtractor) { + super(); + this.errorHandler = errorHandler; + this.targetExtractor = targetExtractor; + } + + public async canHandle(input: ErrorHandlerArgs): Promise { + return this.errorHandler.canHandle(input); + } + + public async handle(input: ErrorHandlerArgs): Promise { + const target = await this.targetExtractor.handleSafe(input); + input.error.metadata.add(SOLID_ERROR.terms.target, DataFactory.namedNode(target.path)); + return this.errorHandler.handle(input); + } +} diff --git a/src/index.ts b/src/index.ts index 3e4c844d4..58af187ff 100644 --- a/src/index.ts +++ b/src/index.ts @@ -100,6 +100,7 @@ export * from './http/output/error/ConvertingErrorHandler'; export * from './http/output/error/ErrorHandler'; export * from './http/output/error/RedirectingErrorHandler'; export * from './http/output/error/SafeErrorHandler'; +export * from './http/output/error/TargetExtractorErrorHandler'; // HTTP/Output/Metadata export * from './http/output/metadata/AllowAcceptHeaderWriter'; diff --git a/src/util/Vocabularies.ts b/src/util/Vocabularies.ts index 4ab5b2737..5e546d3ee 100644 --- a/src/util/Vocabularies.ts +++ b/src/util/Vocabularies.ts @@ -283,6 +283,7 @@ export const SOLID_ERROR = createVocabulary( 'errorCode', 'errorResponse', 'stack', + 'target', ); // Used to pass parameters to error templates diff --git a/test/unit/http/output/error/TargetExtractorErrorHandler.test.ts b/test/unit/http/output/error/TargetExtractorErrorHandler.test.ts new file mode 100644 index 000000000..03664572c --- /dev/null +++ b/test/unit/http/output/error/TargetExtractorErrorHandler.test.ts @@ -0,0 +1,47 @@ +import type { TargetExtractor } from '../../../../../src/http/input/identifier/TargetExtractor'; +import type { ErrorHandler, ErrorHandlerArgs } from '../../../../../src/http/output/error/ErrorHandler'; +import { TargetExtractorErrorHandler } from '../../../../../src/http/output/error/TargetExtractorErrorHandler'; +import type { ResourceIdentifier } from '../../../../../src/http/representation/ResourceIdentifier'; +import { NotFoundHttpError } from '../../../../../src/util/errors/NotFoundHttpError'; +import { SOLID_ERROR } from '../../../../../src/util/Vocabularies'; + +describe('A TargetExtractorErrorHandler', (): void => { + const identifier: ResourceIdentifier = { path: 'http://example.com/foo' }; + let input: ErrorHandlerArgs; + let source: jest.Mocked; + let targetExtractor: jest.Mocked; + let handler: TargetExtractorErrorHandler; + + beforeEach(async(): Promise => { + input = { + request: 'request' as any, + error: new NotFoundHttpError(), + }; + + source = { + canHandle: jest.fn(), + handle: jest.fn().mockResolvedValue('response'), + } satisfies Partial as any; + + targetExtractor = { + handleSafe: jest.fn().mockResolvedValue(identifier), + } satisfies Partial as any; + + handler = new TargetExtractorErrorHandler(source, targetExtractor); + }); + + it('can handle input its source can handle.', async(): Promise => { + await expect(handler.canHandle(input)).resolves.toBeUndefined(); + expect(source.canHandle).toHaveBeenLastCalledWith(input); + + const error = new Error('bad data'); + source.canHandle.mockRejectedValueOnce(error); + await expect(handler.canHandle(input)).rejects.toThrow(error); + }); + + it('adds the identifier as metadata.', async(): Promise => { + await expect(handler.handle(input)).resolves.toBe('response'); + expect(input.error.metadata.get(SOLID_ERROR.terms.target)?.value).toEqual(identifier.path); + expect(targetExtractor.handleSafe).toHaveBeenLastCalledWith(input); + }); +}); From d7078ad69261566c44e38d1bb19142fb8bd4dd0f Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Thu, 4 Apr 2024 10:11:26 +0200 Subject: [PATCH 35/71] fix: Expose auxiliary links on errors --- .../metadata/AuxiliaryLinkMetadataWriter.ts | 15 ++++++++++++--- .../metadata/AuxiliaryLinkMetadataWriter.test.ts | 14 +++++++++++++- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/http/output/metadata/AuxiliaryLinkMetadataWriter.ts b/src/http/output/metadata/AuxiliaryLinkMetadataWriter.ts index 6f3cde88f..dd612bd2b 100644 --- a/src/http/output/metadata/AuxiliaryLinkMetadataWriter.ts +++ b/src/http/output/metadata/AuxiliaryLinkMetadataWriter.ts @@ -1,9 +1,10 @@ -import { Util } from 'n3'; import { getLoggerFor } from '../../../logging/LogUtil'; import type { HttpResponse } from '../../../server/HttpResponse'; import { addHeader } from '../../../util/HeaderUtil'; +import { LDP, RDF, SOLID_ERROR } from '../../../util/Vocabularies'; import type { AuxiliaryStrategy } from '../../auxiliary/AuxiliaryStrategy'; import type { RepresentationMetadata } from '../../representation/RepresentationMetadata'; +import type { ResourceIdentifier } from '../../representation/ResourceIdentifier'; import { MetadataWriter } from './MetadataWriter'; /** @@ -30,9 +31,17 @@ export class AuxiliaryLinkMetadataWriter extends MetadataWriter { } public async handle(input: { response: HttpResponse; metadata: RepresentationMetadata }): Promise { - const identifier = { path: input.metadata.identifier.value }; + let identifier: ResourceIdentifier | undefined; + if (input.metadata.has(RDF.terms.type, LDP.terms.Resource)) { + identifier = { path: input.metadata.identifier.value }; + } else { + const target = input.metadata.get(SOLID_ERROR.terms.target); + if (target) { + identifier = { path: target.value }; + } + } // The metadata identifier will be a blank node in case an error was thrown. - if (!this.auxiliaryStrategy.isAuxiliaryIdentifier(identifier) && !Util.isBlankNode(input.metadata.identifier)) { + if (identifier && !this.auxiliaryStrategy.isAuxiliaryIdentifier(identifier)) { const auxiliaryIdentifier = this.specificStrategy.getAuxiliaryIdentifier(identifier); addHeader(input.response, 'Link', `<${auxiliaryIdentifier.path}>; rel="${this.relationType}"`); } diff --git a/test/unit/http/output/metadata/AuxiliaryLinkMetadataWriter.test.ts b/test/unit/http/output/metadata/AuxiliaryLinkMetadataWriter.test.ts index d93d16e0d..a3767790d 100644 --- a/test/unit/http/output/metadata/AuxiliaryLinkMetadataWriter.test.ts +++ b/test/unit/http/output/metadata/AuxiliaryLinkMetadataWriter.test.ts @@ -3,6 +3,7 @@ import { AuxiliaryLinkMetadataWriter } from '../../../../../src/http/output/meta import { RepresentationMetadata } from '../../../../../src/http/representation/RepresentationMetadata'; import type { ResourceIdentifier } from '../../../../../src/http/representation/ResourceIdentifier'; import type { HttpResponse } from '../../../../../src/server/HttpResponse'; +import { LDP, RDF, SOLID_ERROR } from '../../../../../src/util/Vocabularies'; import { SimpleSuffixStrategy } from '../../../../util/SimpleSuffixStrategy'; describe('A LinkRelMetadataWriter', (): void => { @@ -18,6 +19,7 @@ describe('A LinkRelMetadataWriter', (): void => { it('adds the correct link headers.', async(): Promise => { const response = createResponse() as HttpResponse; const metadata = new RepresentationMetadata(identifier); + metadata.add(RDF.terms.type, LDP.terms.Resource); await expect(writer.handle({ response, metadata })).resolves.toBeUndefined(); expect(response.getHeaders()).toEqual({ link: @@ -28,12 +30,22 @@ describe('A LinkRelMetadataWriter', (): void => { const response = createResponse() as HttpResponse; identifier.path += '.dummy'; const metadata = new RepresentationMetadata(identifier); + metadata.add(RDF.terms.type, LDP.terms.Resource); await expect(writer.handle({ response, metadata })).resolves.toBeUndefined(); expect(response.getHeaders()).toEqual({}); }); - it('does not add link headers for blank node identifiers.', async(): Promise => { + it('adds link headers for errors.', async(): Promise => { + const response = createResponse() as HttpResponse; + const metadata = new RepresentationMetadata(); + metadata.add(SOLID_ERROR.terms.target, identifier.path); + await expect(writer.handle({ response, metadata })).resolves.toBeUndefined(); + expect(response.getHeaders()).toEqual({ link: + `<${identifier.path}.meta>; rel="test"` }); + }); + + it('does not add link headers for errors without a target.', async(): Promise => { const response = createResponse() as HttpResponse; const metadata = new RepresentationMetadata(); await expect(writer.handle({ response, metadata })).resolves.toBeUndefined(); From 5e600006819ae1cf1f8edf804218aee700c59bae Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Thu, 4 Apr 2024 13:52:29 +0200 Subject: [PATCH 36/71] fix: Make allow headers more accurate --- .../metadata/AllowAcceptHeaderWriter.ts | 61 +++++++++++++------ .../metadata/AllowAcceptHeaderWriter.test.ts | 51 +++++++++++++--- test/util/FetchUtil.ts | 3 +- 3 files changed, 87 insertions(+), 28 deletions(-) diff --git a/src/http/output/metadata/AllowAcceptHeaderWriter.ts b/src/http/output/metadata/AllowAcceptHeaderWriter.ts index 53bacdde3..ce479df32 100644 --- a/src/http/output/metadata/AllowAcceptHeaderWriter.ts +++ b/src/http/output/metadata/AllowAcceptHeaderWriter.ts @@ -8,8 +8,11 @@ import { LDP, PIM, RDF, SOLID_ERROR } from '../../../util/Vocabularies'; import type { RepresentationMetadata } from '../../representation/RepresentationMetadata'; import { MetadataWriter } from './MetadataWriter'; -// Only PUT and PATCH can be used to create a new resource -const NEW_RESOURCE_ALLOWED_METHODS = new Set([ 'PUT', 'PATCH' ]); +enum ResourceType { + document, + container, + unknown, +} /** * Generates Allow, Accept-Patch, Accept-Post, and Accept-Put headers. @@ -30,8 +33,20 @@ export class AllowAcceptHeaderWriter extends MetadataWriter { public async handle(input: { response: HttpResponse; metadata: RepresentationMetadata }): Promise { const { response, metadata } = input; + let resourceType: ResourceType; + if (metadata.has(RDF.terms.type, LDP.terms.Resource)) { + resourceType = isContainerPath(metadata.identifier.value) ? ResourceType.container : ResourceType.document; + } else { + const target = metadata.get(SOLID_ERROR.terms.target)?.value; + if (target) { + resourceType = isContainerPath(target) ? ResourceType.container : ResourceType.document; + } else { + resourceType = ResourceType.unknown; + } + } + // Filter out methods which are not allowed - const allowedMethods = this.filterAllowedMethods(metadata); + const allowedMethods = this.filterAllowedMethods(metadata, resourceType); // Generate the Allow headers (if required) const generateAllow = this.generateAllow(allowedMethods, response, metadata); @@ -43,29 +58,34 @@ export class AllowAcceptHeaderWriter extends MetadataWriter { /** * Starts from the stored set of methods and removes all those that are not allowed based on the metadata. */ - private filterAllowedMethods(metadata: RepresentationMetadata): Set { + private filterAllowedMethods(metadata: RepresentationMetadata, resourceType: ResourceType): Set { const disallowedMethods = new Set(metadata.getAll(SOLID_ERROR.terms.disallowedMethod) .map((term): string => term.value)); const allowedMethods = new Set(this.supportedMethods.filter((method): boolean => !disallowedMethods.has(method))); // POST is only allowed on containers. // Metadata only has the resource URI in case it has resource metadata. - if (!this.isPostAllowed(metadata)) { + if (!this.isPostAllowed(resourceType)) { allowedMethods.delete('POST'); } - if (!this.isPutAllowed(metadata)) { + if (!this.isPutAllowed(metadata, resourceType)) { allowedMethods.delete('PUT'); } - if (!this.isDeleteAllowed(metadata)) { + if (!this.isPatchAllowed(resourceType)) { + allowedMethods.delete('PATCH'); + } + + if (!this.isDeleteAllowed(metadata, resourceType)) { allowedMethods.delete('DELETE'); } // If we are sure the resource does not exist: only keep methods that can create a new resource. if (metadata.has(SOLID_ERROR.terms.errorResponse, NotFoundHttpError.uri)) { for (const method of allowedMethods) { - if (!NEW_RESOURCE_ALLOWED_METHODS.has(method)) { + // Containers can only be created by PUT, documents also by PATCH + if (method !== 'PUT' && (method !== 'PATCH' || resourceType === ResourceType.container)) { allowedMethods.delete(method); } } @@ -76,18 +96,23 @@ export class AllowAcceptHeaderWriter extends MetadataWriter { /** * POST is only allowed on containers. - * The metadata URI is only valid in case there is resource metadata, - * otherwise it is just a blank node. */ - private isPostAllowed(metadata: RepresentationMetadata): boolean { - return !metadata.has(RDF.terms.type, LDP.terms.Resource) || isContainerPath(metadata.identifier.value); + private isPostAllowed(resourceType: ResourceType): boolean { + return resourceType !== ResourceType.document; } /** * PUT is not allowed on existing containers. */ - private isPutAllowed(metadata: RepresentationMetadata): boolean { - return !metadata.has(RDF.terms.type, LDP.terms.Resource) || !isContainerPath(metadata.identifier.value); + private isPutAllowed(metadata: RepresentationMetadata, resourceType: ResourceType): boolean { + return resourceType !== ResourceType.container || !metadata.has(RDF.terms.type, LDP.terms.Resource); + } + + /** + * PATCH is not allowed on containers. + */ + private isPatchAllowed(resourceType: ResourceType): boolean { + return resourceType !== ResourceType.container; } /** @@ -97,14 +122,14 @@ export class AllowAcceptHeaderWriter extends MetadataWriter { * * Note that the identifier value check only works if the metadata is not about an error. */ - private isDeleteAllowed(metadata: RepresentationMetadata): boolean { - if (!isContainerPath(metadata.identifier.value)) { + private isDeleteAllowed(metadata: RepresentationMetadata, resourceType: ResourceType): boolean { + if (resourceType !== ResourceType.container) { return true; } const isStorage = metadata.has(RDF.terms.type, PIM.terms.Storage); - const isEmpty = metadata.has(LDP.terms.contains); - return !isStorage && !isEmpty; + const isEmpty = !metadata.has(LDP.terms.contains); + return !isStorage && isEmpty; } /** diff --git a/test/unit/http/output/metadata/AllowAcceptHeaderWriter.test.ts b/test/unit/http/output/metadata/AllowAcceptHeaderWriter.test.ts index 738173056..9b18ef45e 100644 --- a/test/unit/http/output/metadata/AllowAcceptHeaderWriter.test.ts +++ b/test/unit/http/output/metadata/AllowAcceptHeaderWriter.test.ts @@ -30,6 +30,14 @@ describe('An AllowAcceptHeaderWriter', (): void => { { [RDF.type]: [ LDP.terms.Resource, LDP.terms.Container, PIM.terms.Storage ]}, ); const error404 = new RepresentationMetadata({ [SOLID_ERROR.errorResponse]: NotFoundHttpError.uri }); + const error404Container = new RepresentationMetadata({ + [SOLID_ERROR.errorResponse]: NotFoundHttpError.uri, + [SOLID_ERROR.target]: 'http://example.com/foo/', + }); + const error404Document = new RepresentationMetadata({ + [SOLID_ERROR.errorResponse]: NotFoundHttpError.uri, + [SOLID_ERROR.target]: 'http://example.com/foo/bar', + }); const error405 = new RepresentationMetadata( { [SOLID_ERROR.errorResponse]: MethodNotAllowedHttpError.uri, [SOLID_ERROR.disallowedMethod]: 'PUT' }, ); @@ -57,33 +65,36 @@ describe('An AllowAcceptHeaderWriter', (): void => { expect(headers['accept-post']).toBeUndefined(); }); - it('returns all methods except PUT for an empty container.', async(): Promise => { + it('returns all methods except PUT/PATCH for an empty container.', async(): Promise => { await expect(writer.handleSafe({ response, metadata: emptyContainer })).resolves.toBeUndefined(); const headers = response.getHeaders(); expect(typeof headers.allow).toBe('string'); expect(new Set(headers.allow!.split(', '))) - .toEqual(new Set([ 'OPTIONS', 'GET', 'HEAD', 'POST', 'PATCH', 'DELETE' ])); - expect(headers['accept-patch']).toBe('text/n3, application/sparql-update'); + .toEqual(new Set([ 'OPTIONS', 'GET', 'HEAD', 'POST', 'DELETE' ])); + expect(headers['accept-patch']).toBeUndefined(); + expect(headers['accept-put']).toBeUndefined(); expect(headers['accept-post']).toBe('*/*'); }); - it('returns all methods except PUT/DELETE for a non-empty container.', async(): Promise => { + it('returns all methods except PUT/PATCH/DELETE for a non-empty container.', async(): Promise => { await expect(writer.handleSafe({ response, metadata: fullContainer })).resolves.toBeUndefined(); const headers = response.getHeaders(); expect(typeof headers.allow).toBe('string'); expect(new Set(headers.allow!.split(', '))) - .toEqual(new Set([ 'OPTIONS', 'GET', 'HEAD', 'POST', 'PATCH' ])); - expect(headers['accept-patch']).toBe('text/n3, application/sparql-update'); + .toEqual(new Set([ 'OPTIONS', 'GET', 'HEAD', 'POST' ])); + expect(headers['accept-patch']).toBeUndefined(); + expect(headers['accept-put']).toBeUndefined(); expect(headers['accept-post']).toBe('*/*'); }); - it('returns all methods except PUT/DELETE for a storage container.', async(): Promise => { + it('returns all methods except PUT/PATCH/DELETE for a storage container.', async(): Promise => { await expect(writer.handleSafe({ response, metadata: storageContainer })).resolves.toBeUndefined(); const headers = response.getHeaders(); expect(typeof headers.allow).toBe('string'); expect(new Set(headers.allow!.split(', '))) - .toEqual(new Set([ 'OPTIONS', 'GET', 'HEAD', 'POST', 'PATCH' ])); - expect(headers['accept-patch']).toBe('text/n3, application/sparql-update'); + .toEqual(new Set([ 'OPTIONS', 'GET', 'HEAD', 'POST' ])); + expect(headers['accept-patch']).toBeUndefined(); + expect(headers['accept-put']).toBeUndefined(); expect(headers['accept-post']).toBe('*/*'); }); @@ -98,6 +109,28 @@ describe('An AllowAcceptHeaderWriter', (): void => { expect(headers['accept-post']).toBeUndefined(); }); + it('returns PUT if the target does not exist and is a document.', async(): Promise => { + await expect(writer.handleSafe({ response, metadata: error404Document })).resolves.toBeUndefined(); + const headers = response.getHeaders(); + expect(typeof headers.allow).toBe('string'); + expect(new Set(headers.allow!.split(', '))) + .toEqual(new Set([ 'PUT', 'PATCH' ])); + expect(headers['accept-patch']).toBe('text/n3, application/sparql-update'); + expect(headers['accept-put']).toBe('*/*'); + expect(headers['accept-post']).toBeUndefined(); + }); + + it('returns PUT if the target does not exist and is a container.', async(): Promise => { + await expect(writer.handleSafe({ response, metadata: error404Container })).resolves.toBeUndefined(); + const headers = response.getHeaders(); + expect(typeof headers.allow).toBe('string'); + expect(new Set(headers.allow!.split(', '))) + .toEqual(new Set([ 'PUT' ])); + expect(headers['accept-patch']).toBeUndefined(); + expect(headers['accept-put']).toBe('*/*'); + expect(headers['accept-post']).toBeUndefined(); + }); + it('removes methods that are not allowed by a 405 error.', async(): Promise => { await expect(writer.handleSafe({ response, metadata: error405 })).resolves.toBeUndefined(); const headers = response.getHeaders(); diff --git a/test/util/FetchUtil.ts b/test/util/FetchUtil.ts index fd9fb1da9..2e37eac4a 100644 --- a/test/util/FetchUtil.ts +++ b/test/util/FetchUtil.ts @@ -19,11 +19,12 @@ export async function getResource( expect(response.status).toBe(200); expect(response.headers.get('link')).toContain(`<${LDP.Resource}>; rel="type"`); expect(response.headers.get('link')).toContain(`<${url}.acl>; rel="acl"`); - expect(response.headers.get('accept-patch')).toBe('text/n3, application/sparql-update'); if (isContainer) { expect(response.headers.get('link')).toContain(`<${LDP.Container}>; rel="type"`); expect(response.headers.get('link')).toContain(`<${LDP.BasicContainer}>; rel="type"`); + } else { + expect(response.headers.get('accept-patch')).toBe('text/n3, application/sparql-update'); } if (expected?.contentType) { expect(response.headers.get('content-type')).toBe(expected.contentType); From 2846c711ab06311a4956b4ad0a21bde1213e993d Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Fri, 5 Apr 2024 10:03:58 +0200 Subject: [PATCH 37/71] docs: Fix language Co-authored-by: Ted Thibodeau Jr --- config/ldp/handler/components/error-handler.json | 2 +- src/http/output/error/TargetExtractorErrorHandler.ts | 2 +- src/http/output/metadata/AllowAcceptHeaderWriter.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/ldp/handler/components/error-handler.json b/config/ldp/handler/components/error-handler.json index e0c498983..12d41558e 100644 --- a/config/ldp/handler/components/error-handler.json +++ b/config/ldp/handler/components/error-handler.json @@ -15,7 +15,7 @@ "@type": "WaterfallHandler", "handlers": [ { - "comment": "Internally redirects are created by throwing a specific error, this handler converts them to the correct response.", + "comment": "Redirects are created internally by throwing a specific error; this handler converts them to the correct response.", "@type": "RedirectingErrorHandler" }, { diff --git a/src/http/output/error/TargetExtractorErrorHandler.ts b/src/http/output/error/TargetExtractorErrorHandler.ts index 089e0a69a..9a65e1443 100644 --- a/src/http/output/error/TargetExtractorErrorHandler.ts +++ b/src/http/output/error/TargetExtractorErrorHandler.ts @@ -6,7 +6,7 @@ import type { ErrorHandlerArgs } from './ErrorHandler'; import { ErrorHandler } from './ErrorHandler'; /** - * Adds metadata to an error to indicate what the identifier was of the resource originally being targeted. + * Adds metadata to an error to indicate the identifier of the originally targeted resource. */ export class TargetExtractorErrorHandler extends ErrorHandler { protected readonly errorHandler: ErrorHandler; diff --git a/src/http/output/metadata/AllowAcceptHeaderWriter.ts b/src/http/output/metadata/AllowAcceptHeaderWriter.ts index ce479df32..112d2029c 100644 --- a/src/http/output/metadata/AllowAcceptHeaderWriter.ts +++ b/src/http/output/metadata/AllowAcceptHeaderWriter.ts @@ -84,7 +84,7 @@ export class AllowAcceptHeaderWriter extends MetadataWriter { // If we are sure the resource does not exist: only keep methods that can create a new resource. if (metadata.has(SOLID_ERROR.terms.errorResponse, NotFoundHttpError.uri)) { for (const method of allowedMethods) { - // Containers can only be created by PUT, documents also by PATCH + // Containers can only be created by PUT; documents by PUT or PATCH if (method !== 'PUT' && (method !== 'PATCH' || resourceType === ResourceType.container)) { allowedMethods.delete(method); } From f73dfb31c0fe132524323acf6c4f4636bcd8bc80 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Fri, 5 Apr 2024 10:25:52 +0200 Subject: [PATCH 38/71] fix: Do not reuse the same error in StaticThrowHandler --- src/util/handlers/StaticThrowHandler.ts | 10 +++++---- .../integration/LdpHandlerWithoutAuth.test.ts | 6 ++++- .../util/handlers/StaticThrowHandler.test.ts | 22 ++++++++++++++++++- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/util/handlers/StaticThrowHandler.ts b/src/util/handlers/StaticThrowHandler.ts index 1928f61d8..d33da9129 100644 --- a/src/util/handlers/StaticThrowHandler.ts +++ b/src/util/handlers/StaticThrowHandler.ts @@ -1,11 +1,11 @@ -import type { HttpError } from '../errors/HttpError'; +import type { HttpError, HttpErrorClass } from '../errors/HttpError'; import { AsyncHandler } from './AsyncHandler'; /** - * Utility handler that can handle all input and always throws the given error. + * Utility handler that can handle all input and always throws an instance of the given error. */ export class StaticThrowHandler extends AsyncHandler { - private readonly error: HttpError; + protected readonly error: HttpError; public constructor(error: HttpError) { super(); @@ -13,6 +13,8 @@ export class StaticThrowHandler extends AsyncHandler { } public async handle(): Promise { - throw this.error; + // We are creating a new instance of the error instead of rethrowing the error, + // as reusing the same error can cause problem as the metadata is then also reused. + throw new (this.error.constructor as HttpErrorClass)(); } } diff --git a/test/integration/LdpHandlerWithoutAuth.test.ts b/test/integration/LdpHandlerWithoutAuth.test.ts index b47492030..d27c4ec09 100644 --- a/test/integration/LdpHandlerWithoutAuth.test.ts +++ b/test/integration/LdpHandlerWithoutAuth.test.ts @@ -506,7 +506,11 @@ describe.each(stores)('An LDP handler allowing all requests %s', (name, { storeC }); it('returns 405 for unsupported methods.', async(): Promise => { - const response = await fetch(baseUrl, { method: 'TRACE' }); + let response = await fetch(baseUrl, { method: 'TRACE' }); + expect(response.status).toBe(405); + + // Testing two different URLs as there used to be a problem with this + response = await fetch(joinUrl(baseUrl, 'foo'), { method: 'TRACE' }); expect(response.status).toBe(405); }); diff --git a/test/unit/util/handlers/StaticThrowHandler.test.ts b/test/unit/util/handlers/StaticThrowHandler.test.ts index 3fc561558..803ca26a7 100644 --- a/test/unit/util/handlers/StaticThrowHandler.test.ts +++ b/test/unit/util/handlers/StaticThrowHandler.test.ts @@ -1,5 +1,6 @@ import { BadRequestHttpError } from '../../../../src/util/errors/BadRequestHttpError'; import { StaticThrowHandler } from '../../../../src/util/handlers/StaticThrowHandler'; +import { SOLID_ERROR } from '../../../../src/util/Vocabularies'; describe('A StaticThrowHandler', (): void => { const error = new BadRequestHttpError(); @@ -9,7 +10,26 @@ describe('A StaticThrowHandler', (): void => { await expect(handler.canHandle({})).resolves.toBeUndefined(); }); - it('always throws the given error.', async(): Promise => { + it('always throws an instance of the given error.', async(): Promise => { await expect(handler.handle()).rejects.toThrow(error); }); + + it('creates a new instance every time.', async(): Promise => { + /* eslint-disable jest/no-conditional-expect */ + try { + await handler.handle(); + } catch (error: unknown) { + expect(BadRequestHttpError.isInstance(error)).toBe(true); + // Change the metadata + (error as BadRequestHttpError).metadata.add(SOLID_ERROR.terms.target, 'http://example.com/foo'); + } + try { + await handler.handle(); + } catch (error: unknown) { + expect(BadRequestHttpError.isInstance(error)).toBe(true); + // Metadata should not have the change + expect((error as BadRequestHttpError).metadata.has(SOLID_ERROR.terms.target)).toBe(false); + } + /* eslint-enable jest/no-conditional-expect */ + }); }); From 099897013c4ea014212495965d4972e5078ed406 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Thu, 18 Apr 2024 11:18:03 +0200 Subject: [PATCH 39/71] fix: Make `getParentContainer` work with query parameters --- .../identifiers/BaseIdentifierStrategy.ts | 21 +++++++++++++------ .../BaseIdentifierStrategy.test.ts | 2 ++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/util/identifiers/BaseIdentifierStrategy.ts b/src/util/identifiers/BaseIdentifierStrategy.ts index b466198a8..db752ccbe 100644 --- a/src/util/identifiers/BaseIdentifierStrategy.ts +++ b/src/util/identifiers/BaseIdentifierStrategy.ts @@ -1,9 +1,19 @@ import type { ResourceIdentifier } from '../../http/representation/ResourceIdentifier'; import { errorTermsToMetadata } from '../errors/HttpErrorUtil'; import { InternalServerError } from '../errors/InternalServerError'; -import { ensureTrailingSlash, isContainerIdentifier } from '../PathUtil'; +import { isContainerIdentifier } from '../PathUtil'; import type { IdentifierStrategy } from './IdentifierStrategy'; +/** + * Regular expression used to determine the parent container of a resource. + */ +const parentRegex = /^(.+\/)[^/]+\/*$/u; + +/** + * Used during containment check to determine if an identifier is a direct child or not. + */ +const tailRegex = /\/./u; + /** * Provides a default implementation for `getParentContainer` * which checks if the identifier is supported and not a root container. @@ -26,10 +36,9 @@ export abstract class BaseIdentifierStrategy implements IdentifierStrategy { throw new InternalServerError(`Cannot obtain the parent of ${identifier.path} because it is a root container.`); } - // Trailing slash is necessary for URL library - const parentPath = new URL('..', ensureTrailingSlash(identifier.path)).href; - - return { path: parentPath }; + // Due to the checks above we know this will always succeed + const match = parentRegex.exec(identifier.path); + return { path: match![1] }; } public abstract isRootContainer(identifier: ResourceIdentifier): boolean; @@ -49,6 +58,6 @@ export abstract class BaseIdentifierStrategy implements IdentifierStrategy { const tail = identifier.path.slice(container.path.length); // If there is at least one `/` followed by a char this is not a direct parent container - return !/\/./u.test(tail); + return !tailRegex.test(tail); } } diff --git a/test/unit/util/identifiers/BaseIdentifierStrategy.test.ts b/test/unit/util/identifiers/BaseIdentifierStrategy.test.ts index 3717522c4..a521c9976 100644 --- a/test/unit/util/identifiers/BaseIdentifierStrategy.test.ts +++ b/test/unit/util/identifiers/BaseIdentifierStrategy.test.ts @@ -19,7 +19,9 @@ describe('A BaseIdentifierStrategy', (): void => { describe('getParentContainer', (): void => { it('returns the parent identifier.', async(): Promise => { expect(strategy.getParentContainer({ path: 'http://example.com/foo/bar' })).toEqual({ path: 'http://example.com/foo/' }); + expect(strategy.getParentContainer({ path: 'http://example.com/foo//' })).toEqual({ path: 'http://example.com/' }); expect(strategy.getParentContainer({ path: 'http://example.com/foo/bar/' })).toEqual({ path: 'http://example.com/foo/' }); + expect(strategy.getParentContainer({ path: 'http://example.com/foo/bar?q=5' })).toEqual({ path: 'http://example.com/foo/' }); }); it('errors when attempting to get the parent of an unsupported identifier.', async(): Promise => { From e20efac3eaa79b2ed8b09cd72a7f8f0d85655894 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Fri, 19 Apr 2024 11:40:39 +0200 Subject: [PATCH 40/71] fix: Combine metadata with data when generating resources --- src/pods/generate/BaseResourcesGenerator.ts | 31 ++++++++++++------- .../generate/BaseResourcesGenerator.test.ts | 24 +++++++------- 2 files changed, 31 insertions(+), 24 deletions(-) diff --git a/src/pods/generate/BaseResourcesGenerator.ts b/src/pods/generate/BaseResourcesGenerator.ts index 2b89cb616..a86ef3bfd 100644 --- a/src/pods/generate/BaseResourcesGenerator.ts +++ b/src/pods/generate/BaseResourcesGenerator.ts @@ -185,8 +185,20 @@ export class BaseResourcesGenerator implements TemplatedResourcesGenerator { data = await this.processFile(link, options); metadata.contentType = link.contentType; } - // Do not yield a container resource if it already exists - if (!isContainerIdentifier(link.identifier) || !await this.store.hasResource(link.identifier)) { + + // Add metadata from .meta file if there is one + if (metaLink) { + const rawMetadata = await this.generateMetadata(metaLink, options); + if (rawMetadata.contentType) { + // Prevent having 2 content types + metadata.contentType = undefined; + } + metadata.setMetadata(rawMetadata); + this.logger.debug(`Adding metadata for ${metaLink.identifier.path}`); + } + + const shouldYield = !isContainerIdentifier(link.identifier) || !await this.store.hasResource(link.identifier); + if (shouldYield) { this.logger.debug(`Generating resource ${link.identifier.path}`); yield { identifier: link.identifier, @@ -194,20 +206,15 @@ export class BaseResourcesGenerator implements TemplatedResourcesGenerator { }; } - // Add metadata from .meta file if there is one - if (metaLink) { - const rawMetadata = await this.generateMetadata(metaLink, options); - if (!rawMetadata.contentType) { - // Make sure this does not remove the content-type if none is explicitly defined - rawMetadata.contentType = metadata.contentType; - } + // Still need to yield metadata in case the actual resource is not being yielded. + // We also do this for containers as existing containers can't be edited in the same way. + if (metaLink && (!shouldYield || isContainerIdentifier(link.identifier))) { const metaIdentifier = this.metadataStrategy.getAuxiliaryIdentifier(link.identifier); - const descriptionMeta = new RepresentationMetadata(metaIdentifier); - addResourceMetadata(rawMetadata, isContainerIdentifier(link.identifier)); + addResourceMetadata(metadata, isContainerIdentifier(link.identifier)); this.logger.debug(`Generating resource ${metaIdentifier.path}`); yield { identifier: metaIdentifier, - representation: new BasicRepresentation(rawMetadata.quads(), descriptionMeta, INTERNAL_QUADS), + representation: new BasicRepresentation(metadata.quads(), metaIdentifier, INTERNAL_QUADS), }; } } diff --git a/test/unit/pods/generate/BaseResourcesGenerator.test.ts b/test/unit/pods/generate/BaseResourcesGenerator.test.ts index 371f8ad76..31b1fb081 100644 --- a/test/unit/pods/generate/BaseResourcesGenerator.test.ts +++ b/test/unit/pods/generate/BaseResourcesGenerator.test.ts @@ -1,3 +1,4 @@ +import { DataFactory } from 'n3'; import type { ResourceIdentifier } from '../../../../src/http/representation/ResourceIdentifier'; import { BaseResourcesGenerator } from '../../../../src/pods/generate/BaseResourcesGenerator'; import type { @@ -10,7 +11,6 @@ import { asyncToArray } from '../../../../src/util/IterableUtil'; import { ensureTrailingSlash, joinFilePath, trimTrailingSlashes } from '../../../../src/util/PathUtil'; import { readableToQuads, readableToString } from '../../../../src/util/StreamUtil'; import { HandlebarsTemplateEngine } from '../../../../src/util/templates/HandlebarsTemplateEngine'; -import { CONTENT_TYPE_TERM } from '../../../../src/util/Vocabularies'; import { SimpleSuffixStrategy } from '../../../util/SimpleSuffixStrategy'; import { mockFileSystem } from '../../../util/Util'; @@ -110,7 +110,8 @@ describe('A BaseResourcesGenerator', (): void => { it('adds metadata from .meta files.', async(): Promise => { const meta = '<> "metadata".'; - cache.data = { '.meta': meta, container: { 'template.meta': meta, template }}; + const metaType = '<> "text/plain".'; + cache.data = { '.meta': meta, container: { 'template.meta': meta, template, type: 'dummy', 'type.meta': metaType }}; // Not using options since our dummy template generator generates invalid turtle const result = await asyncToArray(generator.generate(rootFilePath, location, { webId })); @@ -120,7 +121,7 @@ describe('A BaseResourcesGenerator', (): void => { { path: `${location.path}.meta` }, { path: `${location.path}container/` }, { path: `${location.path}container/template` }, - { path: `${location.path}container/template.meta` }, + { path: `${location.path}container/type` }, ]); // Root has the 1 raw metadata triple (with <> changed to its identifier) and content-type @@ -137,18 +138,17 @@ describe('A BaseResourcesGenerator', (): void => { expect(contMetadata.identifier.value).toBe(`${location.path}container/`); expect(contMetadata.quads()).toHaveLength(0); - // Document has the 1 raw metadata triple (with <> changed to its identifier) and content-type + // Document has the new metadata const docMetadata = result[3].representation.metadata; expect(docMetadata.identifier.value).toBe(`${location.path}container/template`); - expect(docMetadata.contentType).toBe('text/turtle'); - const docMetadataQuads = await readableToQuads(result[4].representation.data); - const expDocMetadataQuads = docMetadataQuads.getQuads(docMetadata.identifier, 'pre:has', null, null); - expect(expDocMetadataQuads).toHaveLength(1); - expect(expDocMetadataQuads[0].object.value).toBe('metadata'); // Metadata will replace existing metadata so need to make sure content-type is still there - const contentDocMetadataQuads = docMetadataQuads.getQuads(docMetadata.identifier, CONTENT_TYPE_TERM, null, null); - expect(contentDocMetadataQuads).toHaveLength(1); - expect(contentDocMetadataQuads[0].object.value).toBe('text/turtle'); + expect(docMetadata.contentType).toBe('text/turtle'); + expect(docMetadata.get(DataFactory.namedNode('pre:has'))?.value).toBe('metadata'); + + // Type document has new content type + const typeMetadata = result[4].representation.metadata; + expect(typeMetadata.identifier.value).toBe(`${location.path}container/type`); + expect(typeMetadata.contentType).toBe('text/plain'); }); it('does not create container when it already exists.', async(): Promise => { From 07499631b44154fd24d3fd8fd704df34dfca0d0a Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Tue, 23 Apr 2024 08:03:14 +0200 Subject: [PATCH 41/71] fix: Fix .nvmrc version --- .nvmrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.nvmrc b/.nvmrc index b6a7d89c6..3c032078a 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -16 +18 From f59b2c29704f48c02bcae13787588322524b2511 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Apr 2024 00:42:40 +0000 Subject: [PATCH 42/71] chore(deps): bump peaceiris/actions-gh-pages from 3 to 4 Bumps [peaceiris/actions-gh-pages](https://github.com/peaceiris/actions-gh-pages) from 3 to 4. - [Release notes](https://github.com/peaceiris/actions-gh-pages/releases) - [Changelog](https://github.com/peaceiris/actions-gh-pages/blob/main/CHANGELOG.md) - [Commits](https://github.com/peaceiris/actions-gh-pages/compare/v3...v4) --- updated-dependencies: - dependency-name: peaceiris/actions-gh-pages dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/mkdocs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/mkdocs.yml b/.github/workflows/mkdocs.yml index 6e8fbdf9f..129282924 100644 --- a/.github/workflows/mkdocs.yml +++ b/.github/workflows/mkdocs.yml @@ -70,7 +70,7 @@ jobs: - name: Generate typedocs run: npm run typedocs - name: Deploy typedocs - uses: peaceiris/actions-gh-pages@v3 + uses: peaceiris/actions-gh-pages@v4 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./docs From 386babff42d0e1f9cc4d60e2bbf791db22196a43 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 May 2024 10:14:46 +0000 Subject: [PATCH 43/71] chore(deps): bump ejs from 3.1.9 to 3.1.10 Bumps [ejs](https://github.com/mde/ejs) from 3.1.9 to 3.1.10. - [Release notes](https://github.com/mde/ejs/releases) - [Commits](https://github.com/mde/ejs/compare/v3.1.9...v3.1.10) --- updated-dependencies: - dependency-name: ejs dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index c4c23023d..ad2a2b725 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8862,9 +8862,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/ejs": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", - "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", "dependencies": { "jake": "^10.8.5" }, @@ -23972,9 +23972,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "ejs": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", - "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", "requires": { "jake": "^10.8.5" } From f244b288bd2d1f082c6d0855044153020c52bbe5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 May 2024 00:32:46 +0000 Subject: [PATCH 44/71] chore(deps): bump actions/checkout from 4.1.1 to 4.1.5 Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.1 to 4.1.5. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4.1.1...v4.1.5) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/cth-test.yml | 2 +- .github/workflows/docker.yml | 4 ++-- .github/workflows/mkdocs.yml | 6 +++--- .github/workflows/npm-test.yml | 10 +++++----- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/cth-test.yml b/.github/workflows/cth-test.yml index a68bc0aa1..fa48bcacb 100644 --- a/.github/workflows/cth-test.yml +++ b/.github/workflows/cth-test.yml @@ -42,7 +42,7 @@ jobs: with: node-version: 16.x - name: Check out the project - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4.1.5 with: ref: ${{ inputs.branch || github.ref }} - name: Install dependencies and run build scripts diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index e2ca27f4e..cb2d9a6c5 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -21,7 +21,7 @@ jobs: tags: ${{ steps.meta-main.outputs.tags || steps.meta-version.outputs.tags }} steps: - name: Checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4.1.5 - if: startsWith(github.ref, 'refs/tags/v') || (github.ref == 'refs/heads/main') name: Docker meta edge and version tag id: meta-main @@ -55,7 +55,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4.1.5 - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx diff --git a/.github/workflows/mkdocs.yml b/.github/workflows/mkdocs.yml index 129282924..6dfd40b65 100644 --- a/.github/workflows/mkdocs.yml +++ b/.github/workflows/mkdocs.yml @@ -21,7 +21,7 @@ jobs: outputs: major: ${{ steps.tagged_version.outputs.major || steps.current_version.outputs.major }} steps: - - uses: actions/checkout@v4.1.1 + - uses: actions/checkout@v4.1.5 - uses: actions/setup-node@v4 with: node-version: 16.x @@ -43,7 +43,7 @@ jobs: runs-on: ubuntu-latest needs: mkdocs-prep steps: - - uses: actions/checkout@v4.1.1 + - uses: actions/checkout@v4.1.5 - uses: actions/setup-python@v5 with: python-version: 3.x @@ -62,7 +62,7 @@ jobs: needs: [mkdocs-prep, mkdocs] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.1.1 + - uses: actions/checkout@v4.1.5 - uses: actions/setup-node@v4 with: node-version: 16.x diff --git a/.github/workflows/npm-test.yml b/.github/workflows/npm-test.yml index bfab61a3a..d1cbf83a9 100644 --- a/.github/workflows/npm-test.yml +++ b/.github/workflows/npm-test.yml @@ -7,7 +7,7 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.1.1 + - uses: actions/checkout@v4.1.5 - uses: actions/setup-node@v4 with: node-version: 16.x @@ -37,7 +37,7 @@ jobs: - name: Ensure line endings are consistent run: git config --global core.autocrlf input - name: Check out repository - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4.1.5 - name: Install dependencies and run build scripts run: npm ci - name: Type-check tests @@ -80,7 +80,7 @@ jobs: with: node-version: ${{ matrix.node-version }} - name: Check out repository - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4.1.5 - name: Install dependencies and run build scripts run: npm ci - name: Run integration tests @@ -104,7 +104,7 @@ jobs: - name: Ensure line endings are consistent run: git config --global core.autocrlf input - name: Check out repository - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4.1.5 - name: Install dependencies and run build scripts run: npm ci - name: Run integration tests @@ -126,7 +126,7 @@ jobs: with: node-version: 16.x - name: Check out repository - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4.1.5 - name: Install dependencies and run build scripts run: npm ci - name: Run deploy tests From 203f80020cfd9854f173267afbe97c7951ebac03 Mon Sep 17 00:00:00 2001 From: elf Pavlik Date: Wed, 15 May 2024 06:20:58 -0600 Subject: [PATCH 45/71] chore: update CI node versions * test: update CI node versions * Update npm-test.yml * revert changes to quotes * 22.0 broken on windows https://github.com/nodejs/node/issues/52682 --- .github/workflows/npm-test.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/npm-test.yml b/.github/workflows/npm-test.yml index d1cbf83a9..154b9a6a0 100644 --- a/.github/workflows/npm-test.yml +++ b/.github/workflows/npm-test.yml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v4.1.5 - uses: actions/setup-node@v4 with: - node-version: 16.x + node-version: 20.x - run: npm ci --ignore-scripts - run: npm run lint @@ -27,7 +27,8 @@ jobs: - 18.x - '20.0' - 20.x - - 21.x + - '22.1' + - 22.x timeout-minutes: 15 steps: - name: Use Node.js ${{ matrix.node-version }} @@ -59,7 +60,7 @@ jobs: node-version: - 18.x - 20.x - - 21.x + - 22.x env: TEST_DOCKER: true services: @@ -94,7 +95,7 @@ jobs: node-version: - 18.x - 20.x - - 21.x + - 22.x timeout-minutes: 20 steps: - name: Use Node.js ${{ matrix.node-version }} @@ -124,7 +125,7 @@ jobs: - name: Use Node.js uses: actions/setup-node@v4 with: - node-version: 16.x + node-version: 20.x - name: Check out repository uses: actions/checkout@v4.1.5 - name: Install dependencies and run build scripts From cb38613b4cea7f4e808b30a69f1d9aecbb9506e2 Mon Sep 17 00:00:00 2001 From: elf Pavlik Date: Wed, 22 May 2024 00:58:26 -0600 Subject: [PATCH 46/71] feat: Add support for StreamingHTTPChannel2023 notifications * feat: initial StremingHTTPChannel2023 notifications Co-authored-by: Maciej Samoraj * test: unit for StremingHTTPChannel2023 notifications Co-authored-by: Maciej Samoraj * test: integration for StremingHTTPChannel2023 notifications Co-authored-by: Maciej Samoraj * emit initial notification on streaming http channel * fix linting erros * ensure canceling fetch body in integration tests * extract defaultChannel for topic into util * add documentation * Apply suggestions from code review Co-authored-by: Ted Thibodeau Jr * only generate notifications when needed Co-authored-by: Maciej Samoraj * test: set body timeout to pass on node >21 Co-authored-by: Maciej Samoraj * address review feedback * remove node 21 workaround * add architecture documentation * Apply suggestions from code review Co-authored-by: Joachim Van Herwegen --------- Co-authored-by: Maciej Samoraj Co-authored-by: Ted Thibodeau Jr Co-authored-by: Joachim Van Herwegen --- config/http/notifications/all.json | 1 + config/http/notifications/streaming-http.json | 14 + .../notifications/streaming-http/http.json | 87 +++++ .../architecture/features/notifications.md | 42 +++ documentation/markdown/usage/notifications.md | 25 ++ src/index.ts | 8 + .../StreamingHttp2023Emitter.ts | 37 ++ .../StreamingHttp2023Util.ts | 17 + .../StreamingHttpListeningActivityHandler.ts | 49 +++ .../StreamingHttpMap.ts | 10 + .../StreamingHttpMetadataWriter.ts | 28 ++ .../StreamingHttpRequestHandler.ts | 79 +++++ src/util/Vocabularies.ts | 2 + .../StreamingHttpChannel2023.test.ts | 329 ++++++++++++++++++ .../config/streaming-http-notifications.json | 52 +++ .../StreamingHttp2023Emitter.test.ts | 78 +++++ .../StreamingHttp2023Util.test.ts | 19 + ...eamingHttpListeningActivityHandler.test.ts | 73 ++++ .../StreamingHttpMetadataWriter.test.ts | 20 ++ .../StreamingHttpRequestHandler.test.ts | 150 ++++++++ .../WebSocket2023Emitter.test.ts | 1 - test/util/Util.ts | 1 + 22 files changed, 1121 insertions(+), 1 deletion(-) create mode 100644 config/http/notifications/streaming-http.json create mode 100644 config/http/notifications/streaming-http/http.json create mode 100644 src/server/notifications/StreamingHttpChannel2023/StreamingHttp2023Emitter.ts create mode 100644 src/server/notifications/StreamingHttpChannel2023/StreamingHttp2023Util.ts create mode 100644 src/server/notifications/StreamingHttpChannel2023/StreamingHttpListeningActivityHandler.ts create mode 100644 src/server/notifications/StreamingHttpChannel2023/StreamingHttpMap.ts create mode 100644 src/server/notifications/StreamingHttpChannel2023/StreamingHttpMetadataWriter.ts create mode 100644 src/server/notifications/StreamingHttpChannel2023/StreamingHttpRequestHandler.ts create mode 100644 test/integration/StreamingHttpChannel2023.test.ts create mode 100644 test/integration/config/streaming-http-notifications.json create mode 100644 test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttp2023Emitter.test.ts create mode 100644 test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttp2023Util.test.ts create mode 100644 test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttpListeningActivityHandler.test.ts create mode 100644 test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttpMetadataWriter.test.ts create mode 100644 test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttpRequestHandler.test.ts diff --git a/config/http/notifications/all.json b/config/http/notifications/all.json index 85a0e4667..25a11dd9c 100644 --- a/config/http/notifications/all.json +++ b/config/http/notifications/all.json @@ -6,6 +6,7 @@ "css:config/http/notifications/base/http.json", "css:config/http/notifications/base/listener.json", "css:config/http/notifications/base/storage.json", + "css:config/http/notifications/streaming-http/http.json", "css:config/http/notifications/websockets/handler.json", "css:config/http/notifications/websockets/http.json", "css:config/http/notifications/websockets/subscription.json", diff --git a/config/http/notifications/streaming-http.json b/config/http/notifications/streaming-http.json new file mode 100644 index 000000000..f9336ed34 --- /dev/null +++ b/config/http/notifications/streaming-http.json @@ -0,0 +1,14 @@ +{ + "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "import": [ + "css:config/http/notifications/base/handler.json", + "css:config/http/notifications/base/http.json", + "css:config/http/notifications/base/storage.json", + "css:config/http/notifications/streaming-http/http.json" + ], + "@graph": [ + { + "comment": "All the relevant components are made in the specific imports seen above." + } + ] +} diff --git a/config/http/notifications/streaming-http/http.json b/config/http/notifications/streaming-http/http.json new file mode 100644 index 000000000..264d5f042 --- /dev/null +++ b/config/http/notifications/streaming-http/http.json @@ -0,0 +1,87 @@ +{ + "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "@graph": [ + { + "comment": "Path prefix used by streaming HTTP receiveFrom endpoints", + "@id": "urn:solid-server:default:variable:streamingHTTPReceiveFromPrefix", + "valueRaw": ".notifications/StreamingHTTPChannel2023/" + }, + { + "comment": "Creates updatesViaStreamingHttp2023 Link relations", + "@id": "urn:solid-server:default:StreamingHttpMetadataWriter", + "@type": "StreamingHttpMetadataWriter", + "baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" }, + "pathPrefix": { "@id": "urn:solid-server:default:variable:streamingHTTPReceiveFromPrefix" } + }, + { + "comment": "Allows discovery of the corresponding streaming HTTP channel", + "@id": "urn:solid-server:default:MetadataWriter", + "@type": "ParallelHandler", + "handlers": [ + { "@id": "urn:solid-server:default:StreamingHttpMetadataWriter" } + ] + }, + { + "comment": "Handles the request targeting a StreamingHTTPChannel2023 receiveFrom endpoint.", + "@id": "urn:solid-server:default:StreamingHttp2023Router", + "@type": "OperationRouterHandler", + "baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" }, + "allowedMethods": [ "GET" ], + "allowedPathNames": [ "/StreamingHTTPChannel2023/" ], + "handler": { + "@id": "urn:solid-server:default:StreamingHttp2023RequestHandler", + "@type": "StreamingHttpRequestHandler", + "streamMap": { "@id": "urn:solid-server:default:StreamingHttpMap" }, + "pathPrefix": { "@id": "urn:solid-server:default:variable:streamingHTTPReceiveFromPrefix" }, + "generator": { "@id": "urn:solid-server:default:BaseNotificationGenerator" }, + "serializer": { "@id": "urn:solid-server:default:BaseNotificationSerializer" }, + "credentialsExtractor": { "@id": "urn:solid-server:default:CredentialsExtractor" }, + "permissionReader": { "@id": "urn:solid-server:default:PermissionReader" }, + "authorizer": { "@id": "urn:solid-server:default:Authorizer" } + } + }, + { + "comment": "Add the router to notification type handler", + "@id": "urn:solid-server:default:NotificationTypeHandler", + "@type": "WaterfallHandler", + "handlers": [ + { "@id": "urn:solid-server:default:StreamingHttp2023Router" } + ] + }, + { + "comment": "Opened response streams will be stored in this Map.", + "@id": "urn:solid-server:default:StreamingHttpMap", + "@type": "StreamingHttpMap" + }, + { + "comment": "Emits serialized notifications through Streaming HTTP.", + "@id": "urn:solid-server:default:StreamingHttp2023Emitter", + "@type": "StreamingHttp2023Emitter", + "streamMap": { "@id": "urn:solid-server:default:StreamingHttpMap" } + }, + { + "comment": "Listens to the activities emitted by the MonitoringStore.", + "@id": "urn:solid-server:default:StreamingHttpListeningActivityHandler", + "@type": "StreamingHttpListeningActivityHandler", + "emitter": { "@id": "urn:solid-server:default:ResourceStore" }, + "streamMap": { "@id": "urn:solid-server:default:StreamingHttpMap" }, + "source": { + "comment": "Handles the generation and serialization of notifications for StreamingHTTPChannel2023", + "@id": "urn:solid-server:default:StreamingHttpNotificationHandler", + "@type": "ComposedNotificationHandler", + "generator": { "@id": "urn:solid-server:default:BaseNotificationGenerator" }, + "serializer": { "@id": "urn:solid-server:default:BaseNotificationSerializer" }, + "emitter": { "@id": "urn:solid-server:default:StreamingHttp2023Emitter" }, + "eTagHandler": { "@id": "urn:solid-server:default:ETagHandler" } + } + }, + { + "comment": "Add the activity handler to the primary initializer", + "@id": "urn:solid-server:default:PrimaryParallelInitializer", + "@type": "ParallelHandler", + "handlers": [ + { "@id": "urn:solid-server:default:StreamingHttpListeningActivityHandler" } + ] + } + ] +} diff --git a/documentation/markdown/architecture/features/notifications.md b/documentation/markdown/architecture/features/notifications.md index 1e20d0695..3c3a6a8a2 100644 --- a/documentation/markdown/architecture/features/notifications.md +++ b/documentation/markdown/architecture/features/notifications.md @@ -184,3 +184,45 @@ are quite similar to those needed for WebSocketChannel2023: * The `WebhookChannel2023Type` class contains all the necessary typing information. * `WebhookEmitter` is the `NotificationEmitter` that sends the request. * `WebhookUnsubscriber` and `WebhookWebId` are additional utility classes to support the spec requirements. + +## StreamingHTTPChannel2023 + +Currently, support for [StreamingHTTPChannel2023](https://solid.github.io/notifications/streaming-http-channel-2023) +only covers default, pre-established channels made available for every resource. Those channels output `text/turtle`. + +Support for custom, subscription-based channels can be added in the future. + +* For discovery, there is a `StreamingHttpMetadataWriter`, which adds `Link` to every `HTTP` response header +using `rel="http://www.w3.org/ns/solid/terms#updatesViaStreamingHttp2023"`. It links directly to the `receiveFrom` +endpoint of the default, pre-established channel for that topic resource. +* Requests to `receiveFrom` endpoints are handled by a `StreamingHttpRequestHandler`. + * It performs an authorization check. + * It creates a new response stream and adds it to the `StreamingHttpMap`, indexed by the topic resource. + * It sends an initial notification, similar to notification channels using a `state` feature. +* `StreamingHttp2023Emitter` is the `NotificationEmitter` that writes notifications to matching response streams. +* `StreamingHttpListeningActivityHandler` is responsible for observing the `MonitoringStore` + and emitting notifications when needed. + It doesn't use a `NotificationChannelStorage` since the default, pre-established channels are not + subscription-based. Instead, it uses a `StreamingHttpMap` to check for active receivers. + +```mermaid +flowchart TB + StreamingHttpListeningActivityHandler("StreamingHttpListeningActivityHandler
StreamingHttpListeningActivityHandler") + StreamingHttpListeningActivityHandler --> StreamingHttpListeningActivityHandlerArgs + + subgraph StreamingHttpListeningActivityHandlerArgs[" "] + StreamingHttpMap("StreamingHttpMap
StreamingHttpMap") + ResourceStore("ResourceStore
ActivityEmitter") + StreamingHttpNotificationHandler("StreamingHttpNotificationHandler
ComposedNotificationHandler") + end + + StreamingHttpNotificationHandler --> StreamingHttpNotificationHandlerArgs + subgraph StreamingHttpNotificationHandlerArgs[" "] + direction TB + Generator("BaseNotificationGenerator") + Serializer("BaseNotificationSerializer") + Emitter("StreamingHttp2023Emitter
StreamingHttp2023Emitter") + ETagHandler("ETagHandler") + + end +``` diff --git a/documentation/markdown/usage/notifications.md b/documentation/markdown/usage/notifications.md index 6a51e7196..a5ae41a0a 100644 --- a/documentation/markdown/usage/notifications.md +++ b/documentation/markdown/usage/notifications.md @@ -127,6 +127,31 @@ The response would then be something like this: } ``` +### Streaming HTTP + +Currently, Streaming HTTP channels are only available as pre-established channels on each resource. +This means that subscribing and unsubscribing are not supported, and no subscription services are advertised. +Instead, each resource advertises the `receiveFrom` of its pre-established notification channel using HTTP Link header, +using `rel="http://www.w3.org/ns/solid/terms#updatesViaStreamingHttp2023"`. + +For example, this — + +```shell +curl --head 'http://localhost:3000/foo/' +``` + +```http +HTTP/1.1 200 OK +Link: ; rel="http://www.w3.org/ns/solid/terms#updatesViaStreamingHttp2023" +``` + +It is essential to remember that any HTTP request to that `receiveFrom` endpoint requires the same authorization +as a `GET` request on the resource which advertises it. + +Currently, all pre-established Streaming HTTP channels have `Content-Type: text/turtle`. + +Information on how to consume Streaming HTTP responses [is available on MDN](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Using_readable_streams#consuming_a_fetch_as_a_stream) + ## Unsubscribing from a notification channel !!! note diff --git a/src/index.ts b/src/index.ts index 58af187ff..7dce018ff 100644 --- a/src/index.ts +++ b/src/index.ts @@ -404,6 +404,14 @@ export * from './server/notifications/WebSocketChannel2023/WebSocket2023Util'; export * from './server/notifications/WebSocketChannel2023/WebSocketMap'; export * from './server/notifications/WebSocketChannel2023/WebSocketChannel2023Type'; +// Server/Notifications/StreamingHTTPChannel2023 +export * from './server/notifications/StreamingHttpChannel2023/StreamingHttp2023Emitter'; +export * from './server/notifications/StreamingHttpChannel2023/StreamingHttp2023Util'; +export * from './server/notifications/StreamingHttpChannel2023/StreamingHttpListeningActivityHandler'; +export * from './server/notifications/StreamingHttpChannel2023/StreamingHttpMap'; +export * from './server/notifications/StreamingHttpChannel2023/StreamingHttpMetadataWriter'; +export * from './server/notifications/StreamingHttpChannel2023/StreamingHttpRequestHandler'; + // Server/Notifications export * from './server/notifications/ActivityEmitter'; export * from './server/notifications/BaseChannelType'; diff --git a/src/server/notifications/StreamingHttpChannel2023/StreamingHttp2023Emitter.ts b/src/server/notifications/StreamingHttpChannel2023/StreamingHttp2023Emitter.ts new file mode 100644 index 000000000..873bd3e82 --- /dev/null +++ b/src/server/notifications/StreamingHttpChannel2023/StreamingHttp2023Emitter.ts @@ -0,0 +1,37 @@ +import { getLoggerFor } from '../../../logging/LogUtil'; +import type { Representation } from '../../../http/representation/Representation'; +import { AsyncHandler } from '../../../util/handlers/AsyncHandler'; +import type { NotificationChannel } from '../NotificationChannel'; +import type { StreamingHttpMap } from './StreamingHttpMap'; + +export interface StreamingHttpEmitterInput { + channel: NotificationChannel; + representation: Representation; +} + +/** + * Emits notifications on StreamingHTTPChannel2023 streams. + * Uses the response streams found in the provided map. + * The key should be the identifier of the topic resource. + */ +export class StreamingHttp2023Emitter extends AsyncHandler { + protected readonly logger = getLoggerFor(this); + + public constructor( + private readonly streamMap: StreamingHttpMap, + ) { + super(); + } + + public async handle({ channel, representation }: StreamingHttpEmitterInput): Promise { + // Called as a NotificationEmitter: emit the notification + const streams = this.streamMap.get(channel.topic); + if (streams) { + for (const stream of streams) { + representation.data.pipe(stream, { end: false }); + } + } else { + representation.data.destroy(); + } + } +} diff --git a/src/server/notifications/StreamingHttpChannel2023/StreamingHttp2023Util.ts b/src/server/notifications/StreamingHttpChannel2023/StreamingHttp2023Util.ts new file mode 100644 index 000000000..424e68237 --- /dev/null +++ b/src/server/notifications/StreamingHttpChannel2023/StreamingHttp2023Util.ts @@ -0,0 +1,17 @@ +import type { ResourceIdentifier } from '../../../http/representation/ResourceIdentifier'; +import { NOTIFY } from '../../../util/Vocabularies'; +import type { NotificationChannel } from '../NotificationChannel'; + +/** + * Default StreamingHTTPChanel2023 for a topic. + * Currently channel description is only used internally and never sent to the client. + * The default channel uses Turtle. + */ +export function generateChannel(topic: ResourceIdentifier): NotificationChannel { + return { + id: `${topic.path}.channel`, + type: NOTIFY.StreamingHTTPChannel2023, + topic: topic.path, + accept: 'text/turtle', + }; +} diff --git a/src/server/notifications/StreamingHttpChannel2023/StreamingHttpListeningActivityHandler.ts b/src/server/notifications/StreamingHttpChannel2023/StreamingHttpListeningActivityHandler.ts new file mode 100644 index 000000000..693b9dad4 --- /dev/null +++ b/src/server/notifications/StreamingHttpChannel2023/StreamingHttpListeningActivityHandler.ts @@ -0,0 +1,49 @@ +import type { RepresentationMetadata } from '../../../http/representation/RepresentationMetadata'; +import type { ResourceIdentifier } from '../../../http/representation/ResourceIdentifier'; +import { getLoggerFor } from '../../../logging/LogUtil'; +import { createErrorMessage } from '../../../util/errors/ErrorUtil'; +import { StaticHandler } from '../../../util/handlers/StaticHandler'; +import type { AS, VocabularyTerm } from '../../../util/Vocabularies'; +import type { ActivityEmitter } from '../ActivityEmitter'; +import type { NotificationHandler } from '../NotificationHandler'; +import { generateChannel } from './StreamingHttp2023Util'; +import type { StreamingHttpMap } from './StreamingHttpMap'; + +/** + * Listens to an {@link ActivityEmitter} and calls the stored {@link NotificationHandler}s in case of an event + * for every matching notification channel found. + * + * Extends {@link StaticHandler} so it can be more easily injected into a Components.js configuration. + * No class takes this one as input, so to make sure Components.js instantiates it, + * it needs to be added somewhere where its presence has no impact, such as the list of initializers. + */ +export class StreamingHttpListeningActivityHandler extends StaticHandler { + protected readonly logger = getLoggerFor(this); + + public constructor( + emitter: ActivityEmitter, + private readonly streamMap: StreamingHttpMap, + private readonly source: NotificationHandler, + ) { + super(); + + emitter.on('changed', (topic, activity, metadata): void => { + if (this.streamMap.has(topic.path)) { + this.emit(topic, activity, metadata).catch( + (error): void => { + this.logger.error(`Error trying to handle notification for ${topic.path}: ${createErrorMessage(error)}`); + }, + ); + } + }); + } + + private async emit( + topic: ResourceIdentifier, + activity: VocabularyTerm, + metadata: RepresentationMetadata, + ): Promise { + const channel = generateChannel(topic); + return this.source.handleSafe({ channel, activity, topic, metadata }); + } +} diff --git a/src/server/notifications/StreamingHttpChannel2023/StreamingHttpMap.ts b/src/server/notifications/StreamingHttpChannel2023/StreamingHttpMap.ts new file mode 100644 index 000000000..b8e250b29 --- /dev/null +++ b/src/server/notifications/StreamingHttpChannel2023/StreamingHttpMap.ts @@ -0,0 +1,10 @@ +import type { PassThrough } from 'node:stream'; +import type { SingleThreaded } from '../../../init/cluster/SingleThreaded'; +import { WrappedSetMultiMap } from '../../../util/map/WrappedSetMultiMap'; + +/** + * A {@link SetMultiMap} linking identifiers to a set of Streaming HTTP streams. + * An extension of {@link WrappedSetMultiMap} to make sure Components.js allows us to create this in the config, + * as {@link WrappedSetMultiMap} has a constructor not supported. + */ +export class StreamingHttpMap extends WrappedSetMultiMap implements SingleThreaded {} diff --git a/src/server/notifications/StreamingHttpChannel2023/StreamingHttpMetadataWriter.ts b/src/server/notifications/StreamingHttpChannel2023/StreamingHttpMetadataWriter.ts new file mode 100644 index 000000000..b345853dd --- /dev/null +++ b/src/server/notifications/StreamingHttpChannel2023/StreamingHttpMetadataWriter.ts @@ -0,0 +1,28 @@ +import { getLoggerFor } from '../../../logging/LogUtil'; +import type { HttpResponse } from '../../HttpResponse'; +import { addHeader } from '../../../util/HeaderUtil'; +import type { RepresentationMetadata } from '../../../http/representation/RepresentationMetadata'; +import { MetadataWriter } from '../../../http/output/metadata/MetadataWriter'; + +/** + * A {@link MetadataWriter} that adds a link to the receiveFrom endpoint + * of the corresponding Streaming HTTP notifications channel + */ +export class StreamingHttpMetadataWriter extends MetadataWriter { + protected readonly logger = getLoggerFor(this); + + public constructor( + private readonly baseUrl: string, + private readonly pathPrefix: string, + ) { + super(); + } + + public async handle(input: { response: HttpResponse; metadata: RepresentationMetadata }): Promise { + const resourcePath = input.metadata.identifier.value.replace(this.baseUrl, ''); + const receiveFrom = `${this.baseUrl}${this.pathPrefix}${resourcePath}`; + const link = `<${receiveFrom}>; rel="http://www.w3.org/ns/solid/terms#updatesViaStreamingHttp2023"`; + this.logger.debug('Adding updatesViaStreamingHttp2023 to the Link header'); + addHeader(input.response, 'Link', link); + } +} diff --git a/src/server/notifications/StreamingHttpChannel2023/StreamingHttpRequestHandler.ts b/src/server/notifications/StreamingHttpChannel2023/StreamingHttpRequestHandler.ts new file mode 100644 index 000000000..86fb985f2 --- /dev/null +++ b/src/server/notifications/StreamingHttpChannel2023/StreamingHttpRequestHandler.ts @@ -0,0 +1,79 @@ +import { PassThrough } from 'node:stream'; +import type { Credentials } from '../../../authentication/Credentials'; +import type { CredentialsExtractor } from '../../../authentication/CredentialsExtractor'; +import type { Authorizer } from '../../../authorization/Authorizer'; +import type { PermissionReader } from '../../../authorization/PermissionReader'; +import { AccessMode } from '../../../authorization/permissions/Permissions'; +import { OkResponseDescription } from '../../../http/output/response/OkResponseDescription'; +import type { ResponseDescription } from '../../../http/output/response/ResponseDescription'; +import { BasicRepresentation } from '../../../http/representation/BasicRepresentation'; +import { getLoggerFor } from '../../../logging/LogUtil'; +import type { OperationHttpHandlerInput } from '../../OperationHttpHandler'; +import { OperationHttpHandler } from '../../OperationHttpHandler'; +import { guardStream } from '../../../util/GuardedStream'; +import { IdentifierSetMultiMap } from '../../../util/map/IdentifierMap'; +import { createErrorMessage } from '../../../util/errors/ErrorUtil'; +import type { NotificationGenerator } from '../generate/NotificationGenerator'; +import type { NotificationSerializer } from '../serialize/NotificationSerializer'; +import type { StreamingHttpMap } from './StreamingHttpMap'; +import { generateChannel } from './StreamingHttp2023Util'; + +/** + * Handles request to Streaming HTTP receiveFrom endopints. + * All allowed requests are stored in the {@link StreamingHttpMap} + */ +export class StreamingHttpRequestHandler extends OperationHttpHandler { + protected logger = getLoggerFor(this); + + public constructor( + private readonly streamMap: StreamingHttpMap, + private readonly pathPrefix: string, + private readonly generator: NotificationGenerator, + private readonly serializer: NotificationSerializer, + private readonly credentialsExtractor: CredentialsExtractor, + private readonly permissionReader: PermissionReader, + private readonly authorizer: Authorizer, + ) { + super(); + } + + public async handle({ operation, request }: OperationHttpHandlerInput): Promise { + const topic = operation.target.path.replace(this.pathPrefix, ''); + + // Verify if the client is allowed to connect + const credentials = await this.credentialsExtractor.handleSafe(request); + await this.authorize(credentials, topic); + + const stream = guardStream(new PassThrough()); + this.streamMap.add(topic, stream); + stream.on('error', (): boolean => this.streamMap.deleteEntry(topic, stream)); + stream.on('close', (): boolean => this.streamMap.deleteEntry(topic, stream)); + + const channel = generateChannel({ path: topic }); + // Send initial notification + try { + const notification = await this.generator.handle({ channel, topic: { path: topic }}); + const representation = await this.serializer.handleSafe({ channel, notification }); + representation.data.pipe(stream, { end: false }); + } catch (error: unknown) { + this.logger.error(`Problem emitting initial notification: ${createErrorMessage(error)}`); + } + // Pre-established channels use Turtle + const representation = new BasicRepresentation(topic, operation.target, channel.accept); + return new OkResponseDescription( + representation.metadata, + stream, + ); + } + + private async authorize(credentials: Credentials, topic: string): Promise { + const requestedModes = new IdentifierSetMultiMap([[{ path: topic }, AccessMode.read ]]); + this.logger.debug(`Retrieved required modes: ${[ ...requestedModes.entrySets() ].join(',')}`); + + const availablePermissions = await this.permissionReader.handleSafe({ credentials, requestedModes }); + this.logger.debug(`Available permissions are ${[ ...availablePermissions.entries() ].join(',')}`); + + await this.authorizer.handleSafe({ credentials, requestedModes, availablePermissions }); + this.logger.debug(`Authorization succeeded, creating notification channel`); + } +} diff --git a/src/util/Vocabularies.ts b/src/util/Vocabularies.ts index 5e546d3ee..292947b41 100644 --- a/src/util/Vocabularies.ts +++ b/src/util/Vocabularies.ts @@ -153,6 +153,7 @@ export const ACP = createVocabulary( export const AS = createVocabulary( 'https://www.w3.org/ns/activitystreams#', 'object', + 'target', 'Add', 'Create', @@ -231,6 +232,7 @@ export const NOTIFY = createVocabulary( 'WebhookChannel2023', 'WebSocketChannel2023', + 'StreamingHTTPChannel2023', ); export const OIDC = createVocabulary( diff --git a/test/integration/StreamingHttpChannel2023.test.ts b/test/integration/StreamingHttpChannel2023.test.ts new file mode 100644 index 000000000..4368070b4 --- /dev/null +++ b/test/integration/StreamingHttpChannel2023.test.ts @@ -0,0 +1,329 @@ +import { DataFactory, Parser, Store } from 'n3'; +import { BasicRepresentation } from '../../src/http/representation/BasicRepresentation'; +import type { App } from '../../src/init/App'; +import type { ResourceStore } from '../../src/storage/ResourceStore'; +import { joinUrl } from '../../src/util/PathUtil'; +import { AS, RDF } from '../../src/util/Vocabularies'; +import { getPort } from '../util/Util'; +import { + getDefaultVariables, + getPresetConfigPath, + getTestConfigPath, + getTestFolder, + instantiateFromConfig, + removeFolder, +} from './Config'; +import namedNode = DataFactory.namedNode; + +const port = getPort('StreamingHTTPChannel2023'); +const baseUrl = `http://localhost:${port}/`; + +const rootFilePath = getTestFolder('StreamingHTTPChannel2023'); +const stores: [string, any][] = [ + [ 'in-memory storage', { + configs: [ 'storage/backend/memory.json', 'util/resource-locker/memory.json' ], + teardown: jest.fn(), + }], + [ 'on-disk storage', { + configs: [ 'storage/backend/file.json', 'util/resource-locker/file.json' ], + teardown: async(): Promise => removeFolder(rootFilePath), + }], +]; + +async function readChunk(reader: ReadableStreamDefaultReader): Promise { + const decoder = new TextDecoder(); + const parser = new Parser(); + const { value } = await reader.read(); + const notification = decoder.decode(value); + return new Store(parser.parse(notification)); +} + +describe.each(stores)('A server supporting StreamingHTTPChannel2023 using %s', (name, { configs, teardown }): void => { + let app: App; + let store: ResourceStore; + const webId = 'http://example.com/card/#me'; + const topic = joinUrl(baseUrl, '/foo'); + const pathPrefix = '.notifications/StreamingHTTPChannel2023'; + const receiveFrom = joinUrl(baseUrl, pathPrefix, '/foo'); + + beforeAll(async(): Promise => { + const variables = { + ...getDefaultVariables(port, baseUrl), + 'urn:solid-server:default:variable:rootFilePath': rootFilePath, + }; + + // Create and start the server + const instances = await instantiateFromConfig( + 'urn:solid-server:test:Instances', + [ + ...configs.map(getPresetConfigPath), + getTestConfigPath('streaming-http-notifications.json'), + ], + variables, + ) as Record; + ({ app, store } = instances); + + await app.start(); + }); + + afterAll(async(): Promise => { + await teardown(); + await app.stop(); + }); + + it('advertises streaming http endpoint in Link header.', async(): Promise => { + await store.setRepresentation({ path: topic }, new BasicRepresentation('new', 'text/plain')); + const response = await fetch(topic); + expect(response.status).toBe(200); + const linkHeader = response.headers.get('link'); + const match = /<([^>]+)>; rel="http:\/\/www\.w3\.org\/ns\/solid\/terms#updatesViaStreamingHttp2023"/u + .exec(linkHeader!); + expect(match![1]).toEqual(receiveFrom); + }); + + it('only allows GET on receiveFrom endpoint.', async(): Promise => { + const methods = [ 'HEAD', 'PUT', 'POST' ]; + for (const method of methods) { + const response = await fetch(receiveFrom, { + method, + }); + expect(response.status).toBe(405); + } + + // For some reason it differs + const del = await fetch(receiveFrom, { + method: 'DELETE', + }); + expect(del.status).toBe(404); + }); + + it('emits initial Update if topic exists.', async(): Promise => { + await store.setRepresentation({ path: topic }, new BasicRepresentation('new', 'text/plain')); + const streamingResponse = await fetch(receiveFrom); + const reader = streamingResponse.body!.getReader(); + + try { + const quads = await readChunk(reader); + expect(quads.getObjects(null, RDF.terms.type, null)).toEqual([ AS.terms.Update ]); + expect(quads.getObjects(null, AS.terms.object, null)).toEqual([ namedNode(topic) ]); + } finally { + reader.releaseLock(); + await streamingResponse.body!.cancel(); + } + }); + + it('emits initial Delete if topic does not exist.', async(): Promise => { + try { + await store.deleteResource({ path: topic }); + } catch {} + const streamingResponse = await fetch(receiveFrom); + const reader = streamingResponse.body!.getReader(); + + try { + const quads = await readChunk(reader); + expect(quads.getObjects(null, RDF.terms.type, null)).toEqual([ AS.terms.Delete ]); + expect(quads.getObjects(null, AS.terms.object, null)).toEqual([ namedNode(topic) ]); + } finally { + reader.releaseLock(); + await streamingResponse.body!.cancel(); + } + }); + + it('does not emit initial notification when other receivers connect.', async(): Promise => { + await store.setRepresentation({ path: topic }, new BasicRepresentation('new', 'text/plain')); + const streamingResponse = await fetch(receiveFrom); + const reader = streamingResponse.body!.getReader(); + + const otherResponse = await fetch(receiveFrom); + const otherReader = otherResponse.body!.getReader(); + + try { + // Expected initial notification + const updateQuads = await readChunk(reader); + expect(updateQuads.getObjects(null, RDF.terms.type, null)).toEqual([ AS.terms.Update ]); + expect(updateQuads.getObjects(null, AS.terms.object, null)).toEqual([ namedNode(topic) ]); + + // Expected initial notification on other receiver + const otherQuads = await readChunk(otherReader); + expect(otherQuads.getObjects(null, RDF.terms.type, null)).toEqual([ AS.terms.Update ]); + expect(otherQuads.getObjects(null, AS.terms.object, null)).toEqual([ namedNode(topic) ]); + + // Delete resource + const response = await fetch(topic, { + method: 'DELETE', + }); + expect(response.status).toBe(205); + + // If it was caused by the other receiver connecting, it would have been Update as well + const deleteQuads = await readChunk(reader); + expect(deleteQuads.getObjects(null, RDF.terms.type, null)).toEqual([ AS.terms.Delete ]); + expect(deleteQuads.getObjects(null, AS.terms.object, null)).toEqual([ namedNode(topic) ]); + } finally { + reader.releaseLock(); + await streamingResponse.body!.cancel(); + otherReader.releaseLock(); + await otherResponse.body!.cancel(); + } + }); + + it('emits Create events.', async(): Promise => { + try { + await store.deleteResource({ path: topic }); + } catch {} + const streamingResponse = await fetch(receiveFrom); + const reader = streamingResponse.body!.getReader(); + + try { + // Ignore initial notification + await readChunk(reader); + + // Create resource + const response = await fetch(topic, { + method: 'PUT', + headers: { 'content-type': 'text/plain' }, + body: 'abc', + }); + expect(response.status).toBe(201); + + const quads = await readChunk(reader); + expect(quads.getObjects(null, RDF.terms.type, null)).toEqual([ AS.terms.Create ]); + expect(quads.getObjects(null, AS.terms.object, null)).toEqual([ namedNode(topic) ]); + } finally { + reader.releaseLock(); + await streamingResponse.body!.cancel(); + } + }); + + it('emits Update events.', async(): Promise => { + await store.setRepresentation({ path: topic }, new BasicRepresentation('new', 'text/plain')); + const streamingResponse = await fetch(receiveFrom); + const reader = streamingResponse.body!.getReader(); + + try { + // Ignore initial notification + await readChunk(reader); + + // Update resource + const response = await fetch(topic, { + method: 'PUT', + headers: { 'content-type': 'text/plain' }, + body: 'abc', + }); + expect(response.status).toBe(205); + + const quads = await readChunk(reader); + expect(quads.getObjects(null, RDF.terms.type, null)).toEqual([ AS.terms.Update ]); + expect(quads.getObjects(null, AS.terms.object, null)).toEqual([ namedNode(topic) ]); + } finally { + reader.releaseLock(); + await streamingResponse.body!.cancel(); + } + }); + + it('emits Delete events.', async(): Promise => { + await store.setRepresentation({ path: topic }, new BasicRepresentation('new', 'text/plain')); + const streamingResponse = await fetch(receiveFrom); + const reader = streamingResponse.body!.getReader(); + + try { + // Ignore initial notification + await readChunk(reader); + + // Delete resource + const response = await fetch(topic, { + method: 'DELETE', + }); + expect(response.status).toBe(205); + + const quads = await readChunk(reader); + expect(quads.getObjects(null, RDF.terms.type, null)).toEqual([ AS.terms.Delete ]); + expect(quads.getObjects(null, AS.terms.object, null)).toEqual([ namedNode(topic) ]); + } finally { + reader.releaseLock(); + await streamingResponse.body!.cancel(); + } + }); + + it('prevents connecting to channels of restricted topics.', async(): Promise => { + const restricted = joinUrl(baseUrl, '/restricted'); + const restrictedReceiveFrom = joinUrl(baseUrl, pathPrefix, '/restricted'); + await store.setRepresentation({ path: restricted }, new BasicRepresentation('new', 'text/plain')); + + // Only allow our WebID to read + const restrictedAcl = ` + @prefix acl: . + @prefix foaf: . + + <#authorization> + a acl:Authorization; + acl:agent <${webId}>; + acl:mode acl:Read, acl:Write; + acl:accessTo <./restricted>.`; + + await store.setRepresentation({ path: `${restricted}.acl` }, new BasicRepresentation(restrictedAcl, 'text/turtle')); + + // Unauthenticated fetch fails + const unauthenticatedResponse = await fetch(restrictedReceiveFrom); + try { + expect(unauthenticatedResponse.status).toBe(401); + } finally { + await unauthenticatedResponse.body?.cancel(); + } + + // Authenticated fetch succeeds + const authenticatedResponse = await fetch(restrictedReceiveFrom, { + headers: { + authorization: `WebID ${webId}`, + }, + }); + try { + expect(authenticatedResponse.status).toBe(200); + } finally { + await authenticatedResponse.body!.cancel(); + } + }); + + it('emits container notifications if contents get added or removed.', async(): Promise => { + const resource = joinUrl(baseUrl, '/resource'); + const baseReceiveFrom = joinUrl(baseUrl, pathPrefix, '/'); + + // Connecting to the base URL, which is the parent container + const streamingResponse = await fetch(baseReceiveFrom); + const reader = streamingResponse.body!.getReader(); + + try { + // Ignore initial notification + await readChunk(reader); + + // Create contained resource + const createResponse = await fetch(resource, { + method: 'PUT', + headers: { 'content-type': 'text/plain' }, + body: 'abc', + }); + expect(createResponse.status).toBe(201); + + // Will receive the Add notification + const addQuads = await readChunk(reader); + + expect(addQuads.getObjects(null, RDF.terms.type, null)).toEqual([ AS.terms.Add ]); + expect(addQuads.getObjects(null, AS.terms.object, null)).toEqual([ namedNode(resource) ]); + expect(addQuads.getObjects(null, AS.terms.target, null)).toEqual([ namedNode(baseUrl) ]); + + // Remove contained resource + const removeResponse = await fetch(resource, { + method: 'DELETE', + }); + expect(removeResponse.status).toBe(205); + + // Will receive the Remove notification + const removeQuads = await readChunk(reader); + expect(removeQuads.getObjects(null, RDF.terms.type, null)).toEqual([ AS.terms.Remove ]); + expect(removeQuads.getObjects(null, AS.terms.object, null)).toEqual([ namedNode(resource) ]); + expect(removeQuads.getObjects(null, AS.terms.target, null)).toEqual([ namedNode(baseUrl) ]); + } finally { + reader.releaseLock(); + await streamingResponse.body!.cancel(); + } + }); +}); diff --git a/test/integration/config/streaming-http-notifications.json b/test/integration/config/streaming-http-notifications.json new file mode 100644 index 000000000..a79bff185 --- /dev/null +++ b/test/integration/config/streaming-http-notifications.json @@ -0,0 +1,52 @@ +{ + "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", + "import": [ + "css:config/app/init/initialize-root.json", + "css:config/app/main/default.json", + "css:config/http/handler/default.json", + "css:config/http/middleware/default.json", + "css:config/http/notifications/streaming-http.json", + "css:config/http/server-factory/http.json", + "css:config/http/static/default.json", + "css:config/identity/access/public.json", + "css:config/identity/email/default.json", + "css:config/identity/handler/no-accounts.json", + "css:config/identity/oidc/default.json", + "css:config/identity/ownership/token.json", + "css:config/identity/pod/static.json", + "css:config/ldp/authentication/debug-auth-header.json", + "css:config/ldp/authorization/webacl.json", + "css:config/ldp/handler/default.json", + "css:config/ldp/metadata-parser/default.json", + "css:config/ldp/metadata-writer/default.json", + "css:config/ldp/modes/default.json", + + "css:config/storage/key-value/resource-store.json", + "css:config/storage/location/root.json", + "css:config/storage/middleware/default.json", + "css:config/util/auxiliary/acl.json", + "css:config/util/identifiers/suffix.json", + "css:config/util/index/default.json", + "css:config/util/logging/winston.json", + "css:config/util/representation-conversion/default.json", + + "css:config/util/variables/default.json" + ], + "@graph": [ + { + "comment": "Streaming HTTP notifications with debug authentication.", + "@id": "urn:solid-server:test:Instances", + "@type": "RecordObject", + "record": [ + { + "RecordObject:_record_key": "app", + "RecordObject:_record_value": { "@id": "urn:solid-server:default:App" } + }, + { + "RecordObject:_record_key": "store", + "RecordObject:_record_value": { "@id": "urn:solid-server:default:ResourceStore" } + } + ] + } + ] +} diff --git a/test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttp2023Emitter.test.ts b/test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttp2023Emitter.test.ts new file mode 100644 index 000000000..5ea91d0c8 --- /dev/null +++ b/test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttp2023Emitter.test.ts @@ -0,0 +1,78 @@ +import { PassThrough } from 'node:stream'; +import { BasicRepresentation } from '../../../../../src/http/representation/BasicRepresentation'; +import type { NotificationChannel } from '../../../../../src/server/notifications/NotificationChannel'; +import { + StreamingHttp2023Emitter, +} from '../../../../../src/server/notifications/StreamingHttpChannel2023/StreamingHttp2023Emitter'; +import { WrappedSetMultiMap } from '../../../../../src/util/map/WrappedSetMultiMap'; +import type { StreamingHttpMap } from '../../../../../src'; + +describe('A StreamingHttp2023Emitter', (): void => { + const channel: NotificationChannel = { + id: 'id', + topic: 'http://example.com/foo', + type: 'type', + }; + + let stream: jest.Mocked; + let streamMap: StreamingHttpMap; + let emitter: StreamingHttp2023Emitter; + + beforeEach(async(): Promise => { + stream = jest.mocked(new PassThrough()); + + streamMap = new WrappedSetMultiMap(); + + emitter = new StreamingHttp2023Emitter(streamMap); + }); + + it('emits notifications to the stored Streams.', async(): Promise => { + streamMap.add(channel.topic, stream); + + const representation = new BasicRepresentation('notification', 'text/plain'); + const spy = jest.spyOn(representation.data, 'pipe'); + await expect(emitter.handle({ channel, representation })).resolves.toBeUndefined(); + expect(spy).toHaveBeenCalledTimes(1); + expect(spy).toHaveBeenLastCalledWith(stream, { end: false }); + }); + + it('destroys the representation if there is no matching Stream.', async(): Promise => { + const representation = new BasicRepresentation('notification', 'text/plain'); + const spy = jest.spyOn(representation.data, 'pipe'); + await expect(emitter.handle({ channel, representation })).resolves.toBeUndefined(); + expect(spy).toHaveBeenCalledTimes(0); + expect(representation.data.destroyed).toBe(true); + }); + + it('can write to multiple matching Streams.', async(): Promise => { + const stream2 = jest.mocked(new PassThrough()); + + streamMap.add(channel.topic, stream); + streamMap.add(channel.topic, stream2); + + const representation = new BasicRepresentation('notification', 'text/plain'); + const spy = jest.spyOn(representation.data, 'pipe'); + await expect(emitter.handle({ channel, representation })).resolves.toBeUndefined(); + expect(spy).toHaveBeenCalledTimes(2); + expect(spy).toHaveBeenCalledWith(stream, { end: false }); + expect(spy).toHaveBeenLastCalledWith(stream2, { end: false }); + }); + + it('only writes to the matching topic Streams.', async(): Promise => { + const stream2 = jest.mocked(new PassThrough()); + const channel2: NotificationChannel = { + ...channel, + id: 'other id', + topic: 'other topic', + }; + + streamMap.add(channel.topic, stream); + streamMap.add(channel2.topic, stream2); + + const representation = new BasicRepresentation('notification', 'text/plain'); + const spy = jest.spyOn(representation.data, 'pipe'); + await expect(emitter.handle({ channel, representation })).resolves.toBeUndefined(); + expect(spy).toHaveBeenCalledTimes(1); + expect(spy).toHaveBeenLastCalledWith(stream, { end: false }); + }); +}); diff --git a/test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttp2023Util.test.ts b/test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttp2023Util.test.ts new file mode 100644 index 000000000..aff22baa3 --- /dev/null +++ b/test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttp2023Util.test.ts @@ -0,0 +1,19 @@ +import { + generateChannel, +} from '../../../../../src/server/notifications/StreamingHttpChannel2023/StreamingHttp2023Util'; +import { NOTIFY } from '../../../../../src/util/Vocabularies'; + +describe('StreamingHttp2023Util', (): void => { + describe('#generateChannel', (): void => { + it('returns description given topic.', (): void => { + const topic = { path: 'http://example.com/foo' }; + const channel = generateChannel(topic); + expect(channel).toEqual({ + id: `${topic.path}.channel`, + type: NOTIFY.StreamingHTTPChannel2023, + topic: topic.path, + accept: 'text/turtle', + }); + }); + }); +}); diff --git a/test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttpListeningActivityHandler.test.ts b/test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttpListeningActivityHandler.test.ts new file mode 100644 index 000000000..7554b3917 --- /dev/null +++ b/test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttpListeningActivityHandler.test.ts @@ -0,0 +1,73 @@ +import { EventEmitter } from 'node:events'; +import { PassThrough } from 'node:stream'; +import { RepresentationMetadata } from '../../../../../src/http/representation/RepresentationMetadata'; +import type { ResourceIdentifier } from '../../../../../src/http/representation/ResourceIdentifier'; +import type { Logger } from '../../../../../src/logging/Logger'; +import { getLoggerFor } from '../../../../../src/logging/LogUtil'; +import type { ActivityEmitter } from '../../../../../src/server/notifications/ActivityEmitter'; +import type { NotificationHandler } from '../../../../../src/server/notifications/NotificationHandler'; +import { AS } from '../../../../../src/util/Vocabularies'; +import { flushPromises } from '../../../../util/Util'; +import { StreamingHttpListeningActivityHandler, StreamingHttpMap } from '../../../../../src'; + +jest.mock('../../../../../src/logging/LogUtil', (): any => { + const logger: Logger = { error: jest.fn() } as any; + return { getLoggerFor: (): Logger => logger }; +}); + +describe('A StreamingHttpListeningActivityHandler', (): void => { + const logger: jest.Mocked = getLoggerFor('mock') as any; + const topic: ResourceIdentifier = { path: 'http://example.com/foo' }; + const activity = AS.terms.Update; + const metadata = new RepresentationMetadata(); + let emitter: ActivityEmitter; + let streamMap: StreamingHttpMap; + let notificationHandler: jest.Mocked; + + beforeEach(async(): Promise => { + jest.clearAllMocks(); + emitter = new EventEmitter() as any; + streamMap = new StreamingHttpMap(); + + notificationHandler = { + handleSafe: jest.fn().mockResolvedValue(undefined), + } as any; + + // eslint-disable-next-line no-new + new StreamingHttpListeningActivityHandler(emitter, streamMap, notificationHandler); + }); + + it('calls the NotificationHandler if there is an event and a stream.', async(): Promise => { + streamMap.add(topic.path, new PassThrough()); + emitter.emit('changed', topic, activity, metadata); + + await flushPromises(); + + expect(notificationHandler.handleSafe).toHaveBeenCalledTimes(1); + expect(notificationHandler.handleSafe).toHaveBeenLastCalledWith( + expect.objectContaining({ activity, topic, metadata }), + ); + expect(logger.error).toHaveBeenCalledTimes(0); + }); + + it('does not call the NotificationHandler if there is an event but no stream.', async(): Promise => { + emitter.emit('changed', topic, activity, metadata); + + await flushPromises(); + + expect(notificationHandler.handleSafe).toHaveBeenCalledTimes(0); + expect(logger.error).toHaveBeenCalledTimes(0); + }); + + it('logs error from notification handler.', async(): Promise => { + streamMap.add(topic.path, new PassThrough()); + notificationHandler.handleSafe.mockRejectedValueOnce(new Error('bad input')); + + emitter.emit('changed', topic, activity, metadata); + + await flushPromises(); + + expect(logger.error).toHaveBeenCalledTimes(1); + expect(logger.error).toHaveBeenLastCalledWith(`Error trying to handle notification for ${topic.path}: bad input`); + }); +}); diff --git a/test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttpMetadataWriter.test.ts b/test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttpMetadataWriter.test.ts new file mode 100644 index 000000000..7b2110895 --- /dev/null +++ b/test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttpMetadataWriter.test.ts @@ -0,0 +1,20 @@ +import { createResponse } from 'node-mocks-http'; +import { + StreamingHttpMetadataWriter, +} from '../../../../../src/server/notifications/StreamingHttpChannel2023/StreamingHttpMetadataWriter'; +import { RepresentationMetadata } from '../../../../../src/http/representation/RepresentationMetadata'; +import type { HttpResponse } from '../../../../../src/server/HttpResponse'; + +describe('A StreamingHttpMetadataWriter', (): void => { + const baseUrl = 'http://example.org/'; + const pathPrefix = '.notifications/StreamingHTTPChannel2023/'; + const writer = new StreamingHttpMetadataWriter(baseUrl, pathPrefix); + const rel = 'http://www.w3.org/ns/solid/terms#updatesViaStreamingHttp2023'; + + it('adds the correct link header.', async(): Promise => { + const response = createResponse() as HttpResponse; + const metadata = new RepresentationMetadata({ path: 'http://example.org/foo/bar/baz' }); + await expect(writer.handle({ response, metadata })).resolves.toBeUndefined(); + expect(response.getHeaders()).toEqual({ link: `; rel="${rel}"` }); + }); +}); diff --git a/test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttpRequestHandler.test.ts b/test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttpRequestHandler.test.ts new file mode 100644 index 000000000..246cb6970 --- /dev/null +++ b/test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttpRequestHandler.test.ts @@ -0,0 +1,150 @@ +import type { CredentialsExtractor } from '../../../../../src/authentication/CredentialsExtractor'; +import type { Authorizer } from '../../../../../src/authorization/Authorizer'; +import type { PermissionReader } from '../../../../../src/authorization/PermissionReader'; +import { IdentifierMap } from '../../../../../src/util/map/IdentifierMap'; +import { AccessMode } from '../../../../../src/authorization/permissions/Permissions'; +import type { ResourceIdentifier } from '../../../../../src/http/representation/ResourceIdentifier'; +import type { Operation } from '../../../../../src/http/Operation'; +import type { NotificationChannel } from '../../../../../src/server/notifications/NotificationChannel'; +import type { HttpRequest } from '../../../../../src/server/HttpRequest'; +import type { HttpResponse } from '../../../../../src/server/HttpResponse'; +import { BasicRepresentation } from '../../../../../src/http/representation/BasicRepresentation'; +import type { Logger } from '../../../../../src/logging/Logger'; +import { getLoggerFor } from '../../../../../src/logging/LogUtil'; + +import { + StreamingHttpRequestHandler, +} from '../../../../../src/server/notifications/StreamingHttpChannel2023/StreamingHttpRequestHandler'; +import type { NotificationGenerator, NotificationSerializer } from '../../../../../src'; +import { StreamingHttpMap } from '../../../../../src'; +import type { Notification } from '../../../../../src/server/notifications/Notification'; +import { flushPromises } from '../../../../util/Util'; + +jest.mock('../../../../../src/logging/LogUtil', (): any => { + const logger: Logger = { error: jest.fn(), debug: jest.fn() } as any; + return { getLoggerFor: (): Logger => logger }; +}); + +describe('A StreamingHttpRequestHandler', (): void => { + const logger: jest.Mocked = getLoggerFor('mock') as any; + const topic: ResourceIdentifier = { path: 'http://example.com/foo' }; + const pathPrefix = '.notifications/StreamingHTTPChannel2023/'; + const channel: NotificationChannel = { + id: 'id', + topic: topic.path, + type: 'type', + }; + const notification: Notification = { + '@context': [ + 'https://www.w3.org/ns/activitystreams', + 'https://www.w3.org/ns/solid/notification/v1', + ], + id: `urn:123:http://example.com/foo`, + type: 'Update', + object: 'http://example.com/foo', + published: '123', + state: '"123456-text/turtle"', + }; + const representation = new BasicRepresentation(); + const request: HttpRequest = {} as any; + const response: HttpResponse = {} as any; + let streamMap: StreamingHttpMap; + let operation: Operation; + let generator: jest.Mocked; + let serializer: jest.Mocked; + let credentialsExtractor: jest.Mocked; + let permissionReader: jest.Mocked; + let authorizer: jest.Mocked; + let handler: StreamingHttpRequestHandler; + + beforeEach(async(): Promise => { + operation = { + method: 'GET', + target: { path: 'http://example.com/.notifications/StreamingHTTPChannel2023/foo' }, + body: new BasicRepresentation(), + preferences: {}, + }; + + streamMap = new StreamingHttpMap(); + + generator = { + canHandle: jest.fn(), + handle: jest.fn().mockResolvedValue(notification), + } as any; + + serializer = { + handleSafe: jest.fn().mockResolvedValue(representation), + } as any; + + credentialsExtractor = { + handleSafe: jest.fn().mockResolvedValue({ public: {}}), + } as any; + + permissionReader = { + handleSafe: jest.fn().mockResolvedValue(new IdentifierMap([[ topic, AccessMode.read ]])), + } as any; + + authorizer = { + handleSafe: jest.fn(), + } as any; + + handler = new StreamingHttpRequestHandler( + streamMap, + pathPrefix, + generator, + serializer, + credentialsExtractor, + permissionReader, + authorizer, + ); + }); + + it('stores streams.', async(): Promise => { + await handler.handle({ operation, request, response }); + expect([ ...streamMap.keys() ]).toHaveLength(1); + expect(streamMap.has(channel.topic)).toBe(true); + }); + + it('removes closed streams.', async(): Promise => { + const description = await handler.handle({ operation, request, response }); + expect(streamMap.has(channel.topic)).toBe(true); + description.data!.emit('close'); + expect(streamMap.has(channel.topic)).toBe(false); + }); + + it('removes erroring streams.', async(): Promise => { + const description = await handler.handle({ operation, request, response }); + expect(streamMap.has(channel.topic)).toBe(true); + description.data!.emit('error'); + expect(streamMap.has(channel.topic)).toBe(false); + }); + + it('sets content type to turtle.', async(): Promise => { + const description = await handler.handle({ operation, request, response }); + expect(description.metadata?.contentType).toBe('text/turtle'); + }); + + it('responds with the stream.', async(): Promise => { + const description = await handler.handle({ operation, request, response }); + expect(description.data).toBeDefined(); + }); + + it('sends initial notification.', async(): Promise => { + const spy = jest.spyOn(representation.data, 'pipe'); + await handler.handle({ operation, request, response }); + expect(spy).toHaveBeenCalledTimes(1); + }); + + it('logs an error if sending initial notification fails.', async(): Promise => { + serializer.handleSafe.mockRejectedValueOnce(new Error('failed')); + await handler.handle({ operation, request, response }); + await flushPromises(); + expect(logger.error).toHaveBeenCalledTimes(1); + expect(logger.error).toHaveBeenLastCalledWith(`Problem emitting initial notification: failed`); + }); + + it('errors on requests the Authorizer rejects.', async(): Promise => { + authorizer.handleSafe.mockRejectedValue(new Error('not allowed')); + await expect(handler.handle({ operation, request, response })).rejects.toThrow('not allowed'); + }); +}); diff --git a/test/unit/server/notifications/WebSocketChannel2023/WebSocket2023Emitter.test.ts b/test/unit/server/notifications/WebSocketChannel2023/WebSocket2023Emitter.test.ts index 236f3f7a7..ab98639e3 100644 --- a/test/unit/server/notifications/WebSocketChannel2023/WebSocket2023Emitter.test.ts +++ b/test/unit/server/notifications/WebSocketChannel2023/WebSocket2023Emitter.test.ts @@ -21,7 +21,6 @@ describe('A WebSocket2023Emitter', (): void => { beforeEach(async(): Promise => { webSocket = { send: jest.fn(), - close: jest.fn(), } as any; socketMap = new WrappedSetMultiMap(); diff --git a/test/util/Util.ts b/test/util/Util.ts index 3c7c86f98..22f669e5a 100644 --- a/test/util/Util.ts +++ b/test/util/Util.ts @@ -29,6 +29,7 @@ const portNames = [ 'ServerFetch', 'SetupMemory', 'SparqlStorage', + 'StreamingHTTPChannel2023', 'Subdomains', 'WebhookChannel2023', 'WebhookChannel2023-client', From 2f10d22c18268e91a4b008f6f9f3f0b11c7bffca Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Fri, 24 May 2024 08:34:31 +0200 Subject: [PATCH 47/71] chore(release): Release version 7.1.0 of the npm package --- CHANGELOG.md | 20 ++++++++++++++++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d83164e7..c5be9d752 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,26 @@ All notable changes to this project will be documented in this file. +## [7.1.0](https://github.com/CommunitySolidServer/CommunitySolidServer/compare/v7.0.5...v7.1.0) (2024-05-24) + +### Features + +* Add support for StreamingHTTPChannel2023 notifications ([cb38613](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/cb38613b4cea7f4e808b30a69f1d9aecbb9506e2)) +* Store original target in error metadata ([419312e](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/419312ee5f4790881a5d101afea7ab6ca88f5e61)) + +### Fixes + +* Fix .nvmrc version ([0749963](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/07499631b44154fd24d3fd8fd704df34dfca0d0a)) +* Combine metadata with data when generating resources ([e20efac](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/e20efac3eaa79b2ed8b09cd72a7f8f0d85655894)) +* Make `getParentContainer` work with query parameters ([0998970](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/099897013c4ea014212495965d4972e5078ed406)) +* Do not reuse the same error in StaticThrowHandler ([f73dfb3](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/f73dfb31c0fe132524323acf6c4f4636bcd8bc80)) +* Make allow headers more accurate ([5e60000](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/5e600006819ae1cf1f8edf804218aee700c59bae)) +* Expose auxiliary links on errors ([d7078ad](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/d7078ad69261566c44e38d1bb19142fb8bd4dd0f)) + +### Refactors + +* Simplify eslint configs ([cac70b1](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/cac70b1f88dcbbb3ebbe0b8e0b082ead4ab27b33)) + ## [7.0.5](https://github.com/CommunitySolidServer/CommunitySolidServer/compare/v7.0.4...v7.0.5) (2024-03-25) ### Fixes diff --git a/package-lock.json b/package-lock.json index ad2a2b725..e4ed06be7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@solid/community-server", - "version": "7.0.5", + "version": "7.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@solid/community-server", - "version": "7.0.5", + "version": "7.1.0", "license": "MIT", "dependencies": { "@comunica/context-entries": "^2.8.2", diff --git a/package.json b/package.json index 9ccd97000..d58a2616f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@solid/community-server", - "version": "7.0.5", + "version": "7.1.0", "description": "Community Solid Server: an open and modular implementation of the Solid specifications", "license": "MIT", "homepage": "https://github.com/CommunitySolidServer/CommunitySolidServer#readme", From 556899dbdbf3bb285de71225d156c4891dce23a9 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Fri, 24 May 2024 13:10:20 +0200 Subject: [PATCH 48/71] docs: Add HTTP streaming notification option to docs --- config/http/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/config/http/README.md b/config/http/README.md index caeffc035..be0d7d119 100644 --- a/config/http/README.md +++ b/config/http/README.md @@ -22,12 +22,14 @@ Determines how notifications should be sent out from the server when resources c * *all*: Supports all available notification types of the Solid Notifications protocol [specification](https://solidproject.org/TR/notifications-protocol). - Currently, this includes WebhookChannel2023 and WebSocketChannel2023. + Currently, this includes WebhookChannel2023, WebSocketChannel2023 and StreamingHTTPChannel2023. * *disabled*: No notifications are sent out. * *legacy-websocket*: Follows the legacy Solid WebSocket [specification](https://github.com/solid/solid-spec/blob/master/api-websockets.md). Will be removed in future versions. * *new-old-websockets.json*: Support for both the legacy Solid Websockets and the new WebSocketChannel2023. +* *streaming-http*: Follows the StreamingHTTPChannel2023 + [specification](https://solid.github.io/notifications/streaming-http-channel-2023) draft. * *webhooks*: Follows the WebhookChannel2023 [specification](https://solid.github.io/notifications/webhook-channel-2023) draft. * *websockets*: Follows the WebSocketChannel2023 From d350c140fd184d33cbaf6880b9d4b1476d1ffb7c Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Tue, 11 Jun 2024 08:58:00 +0200 Subject: [PATCH 49/71] docs: Add missing index for starting the server --- documentation/mkdocs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/documentation/mkdocs.yml b/documentation/mkdocs.yml index 797dcf788..70019bb1f 100644 --- a/documentation/mkdocs.yml +++ b/documentation/mkdocs.yml @@ -80,6 +80,7 @@ nav: - Features: - features.md - Usage: + - Starting the server: usage/starting-server.md - Example request: usage/example-requests.md - Metadata: usage/metadata.md - Identity provider: From a402aa63821c7dea571e7aed927205c13796bfaa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Jun 2024 00:43:33 +0000 Subject: [PATCH 50/71] chore(deps): bump actions/checkout from 4.1.5 to 4.1.7 Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.5 to 4.1.7. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4.1.5...v4.1.7) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/cth-test.yml | 2 +- .github/workflows/docker.yml | 4 ++-- .github/workflows/mkdocs.yml | 6 +++--- .github/workflows/npm-test.yml | 10 +++++----- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/cth-test.yml b/.github/workflows/cth-test.yml index fa48bcacb..a6d5b3a49 100644 --- a/.github/workflows/cth-test.yml +++ b/.github/workflows/cth-test.yml @@ -42,7 +42,7 @@ jobs: with: node-version: 16.x - name: Check out the project - uses: actions/checkout@v4.1.5 + uses: actions/checkout@v4.1.7 with: ref: ${{ inputs.branch || github.ref }} - name: Install dependencies and run build scripts diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index cb2d9a6c5..46be79a1b 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -21,7 +21,7 @@ jobs: tags: ${{ steps.meta-main.outputs.tags || steps.meta-version.outputs.tags }} steps: - name: Checkout - uses: actions/checkout@v4.1.5 + uses: actions/checkout@v4.1.7 - if: startsWith(github.ref, 'refs/tags/v') || (github.ref == 'refs/heads/main') name: Docker meta edge and version tag id: meta-main @@ -55,7 +55,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4.1.5 + uses: actions/checkout@v4.1.7 - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx diff --git a/.github/workflows/mkdocs.yml b/.github/workflows/mkdocs.yml index 6dfd40b65..2b27d313c 100644 --- a/.github/workflows/mkdocs.yml +++ b/.github/workflows/mkdocs.yml @@ -21,7 +21,7 @@ jobs: outputs: major: ${{ steps.tagged_version.outputs.major || steps.current_version.outputs.major }} steps: - - uses: actions/checkout@v4.1.5 + - uses: actions/checkout@v4.1.7 - uses: actions/setup-node@v4 with: node-version: 16.x @@ -43,7 +43,7 @@ jobs: runs-on: ubuntu-latest needs: mkdocs-prep steps: - - uses: actions/checkout@v4.1.5 + - uses: actions/checkout@v4.1.7 - uses: actions/setup-python@v5 with: python-version: 3.x @@ -62,7 +62,7 @@ jobs: needs: [mkdocs-prep, mkdocs] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.1.5 + - uses: actions/checkout@v4.1.7 - uses: actions/setup-node@v4 with: node-version: 16.x diff --git a/.github/workflows/npm-test.yml b/.github/workflows/npm-test.yml index 154b9a6a0..04a368c72 100644 --- a/.github/workflows/npm-test.yml +++ b/.github/workflows/npm-test.yml @@ -7,7 +7,7 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.1.5 + - uses: actions/checkout@v4.1.7 - uses: actions/setup-node@v4 with: node-version: 20.x @@ -38,7 +38,7 @@ jobs: - name: Ensure line endings are consistent run: git config --global core.autocrlf input - name: Check out repository - uses: actions/checkout@v4.1.5 + uses: actions/checkout@v4.1.7 - name: Install dependencies and run build scripts run: npm ci - name: Type-check tests @@ -81,7 +81,7 @@ jobs: with: node-version: ${{ matrix.node-version }} - name: Check out repository - uses: actions/checkout@v4.1.5 + uses: actions/checkout@v4.1.7 - name: Install dependencies and run build scripts run: npm ci - name: Run integration tests @@ -105,7 +105,7 @@ jobs: - name: Ensure line endings are consistent run: git config --global core.autocrlf input - name: Check out repository - uses: actions/checkout@v4.1.5 + uses: actions/checkout@v4.1.7 - name: Install dependencies and run build scripts run: npm ci - name: Run integration tests @@ -127,7 +127,7 @@ jobs: with: node-version: 20.x - name: Check out repository - uses: actions/checkout@v4.1.5 + uses: actions/checkout@v4.1.7 - name: Install dependencies and run build scripts run: npm ci - name: Run deploy tests From a0ea743449c8b43a6c87d04ad24577a793a4f2d7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Jun 2024 05:36:40 +0000 Subject: [PATCH 51/71] chore(deps-dev): bump braces from 3.0.2 to 3.0.3 Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3. - [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md) - [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3) --- updated-dependencies: - dependency-name: braces dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index e4ed06be7..40da569f5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7054,12 +7054,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -10528,9 +10528,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" @@ -22641,12 +22641,12 @@ } }, "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "requires": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" } }, "browserslist": { @@ -25108,9 +25108,9 @@ } }, "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "requires": { "to-regex-range": "^5.0.1" From 1f474a3c8ee84df3676c21b6bdbbb84c9ec61074 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Jun 2024 00:26:52 +0000 Subject: [PATCH 52/71] chore(deps): bump docker/build-push-action from 5 to 6 Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 5 to 6. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v5...v6) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/docker.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 46be79a1b..1b7f2d197 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -66,7 +66,7 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and export to docker - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: context: . load: true @@ -85,7 +85,7 @@ jobs: done <<< "${{ needs.docker-meta.outputs.tags }}"; - name: Build and push - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: context: . push: true From 5936aceccddb970c5bba967426846d4270966694 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Jun 2024 17:46:14 +0000 Subject: [PATCH 53/71] chore(deps): bump ws from 8.14.2 to 8.17.1 Bumps [ws](https://github.com/websockets/ws) from 8.14.2 to 8.17.1. - [Release notes](https://github.com/websockets/ws/releases) - [Commits](https://github.com/websockets/ws/compare/8.14.2...8.17.1) --- updated-dependencies: - dependency-name: ws dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40da569f5..4114844df 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16653,9 +16653,9 @@ } }, "node_modules/ws": { - "version": "8.14.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", - "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "engines": { "node": ">=10.0.0" }, @@ -29752,9 +29752,9 @@ } }, "ws": { - "version": "8.14.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", - "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "requires": {} }, "xml-name-validator": { From 86e8c09e2da2a96e3b2227ba2d330d437616aa1a Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Thu, 18 Jul 2024 08:10:23 +0200 Subject: [PATCH 54/71] chore: Update markdownlint-cli2 dependency --- .markdownlint-cli2.cjs | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.markdownlint-cli2.cjs b/.markdownlint-cli2.cjs index b9355ada5..2e9fd2e40 100644 --- a/.markdownlint-cli2.cjs +++ b/.markdownlint-cli2.cjs @@ -22,7 +22,7 @@ module.exports = { // Allow multiple subheadings with the same content // across different section (#1 ##A ##B #2 ##A ##B) MD024: { - allow_different_nesting: true, + siblings_only: true, }, // Set Ordered list item prefix to "ordered" (use 1. 2. 3. not 1. 1. 1.) diff --git a/package.json b/package.json index d58a2616f..57ceb2b43 100644 --- a/package.json +++ b/package.json @@ -159,7 +159,7 @@ "jest": "^29.7.0", "jest-esm-transformer-2": "^1.0.0", "jest-rdf": "^1.8.0", - "markdownlint-cli2": "^0.10.0", + "markdownlint-cli2": "^0.13.0", "node-mocks-http": "^1.13.0", "nodemon": "^3.0.1", "set-cookie-parser": "^2.6.0", From d1282f6b1a220103baf819d2b1d3a7666b668e3d Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Thu, 18 Jul 2024 08:36:05 +0200 Subject: [PATCH 55/71] chore: Update eslint-plugin-jest dependency --- eslint/test.js | 1 + package-lock.json | 681 +++++++++++------- package.json | 4 +- .../error/ConvertingErrorHandler.test.ts | 16 +- .../IdentityProviderFactory.test.ts | 15 +- .../interaction/InteractionUtil.test.ts | 6 +- .../interaction/oidc/PickWebIdHandler.test.ts | 3 +- .../ownership/TokenOwnershipValidator.test.ts | 2 +- .../storage/ClientIdAdapterFactory.test.ts | 4 +- test/unit/init/AppRunner.test.ts | 6 +- .../unit/storage/LockingResourceStore.test.ts | 39 +- test/unit/storage/PatchingStore.test.ts | 6 +- .../conversion/ChainedConverter.test.ts | 8 +- test/unit/util/StreamUtil.test.ts | 6 +- .../WrappedExpiringReadWriteLocker.test.ts | 10 +- 15 files changed, 506 insertions(+), 301 deletions(-) diff --git a/eslint/test.js b/eslint/test.js index 4ea6939e9..a2487c422 100644 --- a/eslint/test.js +++ b/eslint/test.js @@ -25,6 +25,7 @@ module.exports = { 'jest/max-expects': 'off', 'jest/no-conditional-in-test': 'off', 'jest/prefer-expect-assertions': 'off', + 'jest/prefer-importing-jest-globals': 'off', 'jest/prefer-lowercase-title': 'off', 'jest/prefer-strict-equal': 'off', 'jest/require-hook': 'off', diff --git a/package-lock.json b/package-lock.json index 4114844df..809ac2068 100644 --- a/package-lock.json +++ b/package-lock.json @@ -88,17 +88,17 @@ "@inrupt/solid-client-authn-core": "^2.0.0", "@inrupt/solid-client-authn-node": "^2.0.0", "@tsconfig/node18": "^18.2.2", - "@types/jest": "^29.5.5", + "@types/jest": "^29.5.12", "@types/set-cookie-parser": "^2.4.4", "@types/supertest": "^2.0.14", "commit-and-tag-version": "^11.3.0", "componentsjs-generator": "^3.1.2", - "eslint-plugin-jest": "^27.4.3", + "eslint-plugin-jest": "^28.6.0", "husky": "^4.3.8", "jest": "^29.7.0", "jest-esm-transformer-2": "^1.0.0", "jest-rdf": "^1.8.0", - "markdownlint-cli2": "^0.10.0", + "markdownlint-cli2": "^0.13.0", "node-mocks-http": "^1.13.0", "nodemon": "^3.0.1", "set-cookie-parser": "^2.6.0", @@ -3152,17 +3152,6 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@comunica/actor-rdf-parse-html/node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, "node_modules/@comunica/actor-rdf-parse-html/node_modules/htmlparser2": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.0.0.tgz", @@ -5099,6 +5088,18 @@ "url": "https://github.com/sindresorhus/is?sponsor=1" } }, + "node_modules/@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@sinonjs/commons": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", @@ -5773,9 +5774,9 @@ } }, "node_modules/@types/jest": { - "version": "29.5.5", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.5.tgz", - "integrity": "sha512-ebylz2hnsWR9mYvmBFbXJXr+33UPc4+ZdxyDXh5w0FlPBTfCVN3wPL+kuOiQt3xvrK419v7XWeAs+AeOksafXg==", + "version": "29.5.12", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz", + "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", "dev": true, "dependencies": { "expect": "^29.0.0", @@ -6588,19 +6589,6 @@ "source-map-js": "^1.0.2" } }, - "node_modules/@vue/compiler-core/node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, "node_modules/@vue/compiler-dom": { "version": "3.4.21", "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.21.tgz", @@ -8736,17 +8724,6 @@ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, - "node_modules/dom-serializer/node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, "node_modules/domelementtype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", @@ -8920,10 +8897,9 @@ } }, "node_modules/entities": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", - "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", - "dev": true, + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "engines": { "node": ">=0.12" }, @@ -9304,19 +9280,19 @@ } }, "node_modules/eslint-plugin-jest": { - "version": "27.4.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.4.3.tgz", - "integrity": "sha512-7S6SmmsHsgIm06BAGCAxL+ABd9/IB3MWkz2pudj6Qqor2y1qQpWPfuFU4SG9pWj4xDjF0e+D7Llh5useuSzAZw==", + "version": "28.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.6.0.tgz", + "integrity": "sha512-YG28E1/MIKwnz+e2H7VwYPzHUYU4aMa19w0yGcwXnnmJH6EfgHahTJ2un3IyraUxNfnz/KUhJAFXNNwWPo12tg==", "dev": true, "dependencies": { - "@typescript-eslint/utils": "^5.10.0" + "@typescript-eslint/utils": "^6.0.0 || ^7.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^16.10.0 || ^18.12.0 || >=20.0.0" }, "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^5.0.0 || ^6.0.0", - "eslint": "^7.0.0 || ^8.0.0", + "@typescript-eslint/eslint-plugin": "^6.0.0 || ^7.0.0", + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0", "jest": "*" }, "peerDependenciesMeta": { @@ -9328,6 +9304,139 @@ } } }, + "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/scope-manager": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", + "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/types": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", + "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", + "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/utils": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.1.tgz", + "integrity": "sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/typescript-estree": "7.16.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", + "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.16.1", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-jest/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/eslint-plugin-jest/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/eslint-plugin-jest/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/eslint-plugin-jsdoc": { "version": "48.2.2", "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.2.tgz", @@ -10374,9 +10483,9 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-glob": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", - "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -11202,17 +11311,6 @@ "entities": "^4.4.0" } }, - "node_modules/htmlparser2/node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, "node_modules/http-assert": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/http-assert/-/http-assert-1.5.0.tgz", @@ -12627,9 +12725,9 @@ } }, "node_modules/jsonc-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", + "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", "dev": true }, "node_modules/jsonfile": { @@ -12910,12 +13008,12 @@ "dev": true }, "node_modules/linkify-it": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", - "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", "dev": true, "dependencies": { - "uc.micro": "^1.0.1" + "uc.micro": "^2.0.0" } }, "node_modules/load-json-file": { @@ -13176,19 +13274,20 @@ } }, "node_modules/markdown-it": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz", - "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", "dev": true, "dependencies": { "argparse": "^2.0.1", - "entities": "~3.0.1", - "linkify-it": "^4.0.1", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" }, "bin": { - "markdown-it": "bin/markdown-it.js" + "markdown-it": "bin/markdown-it.mjs" } }, "node_modules/markdown-it/node_modules/argparse": { @@ -13198,38 +13297,42 @@ "dev": true }, "node_modules/markdownlint": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.31.1.tgz", - "integrity": "sha512-CKMR2hgcIBrYlIUccDCOvi966PZ0kJExDrUi1R+oF9PvqQmCrTqjOsgIvf2403OmJ+CWomuzDoylr6KbuMyvHA==", + "version": "0.34.0", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.34.0.tgz", + "integrity": "sha512-qwGyuyKwjkEMOJ10XN6OTKNOVYvOIi35RNvDLNxTof5s8UmyGHlCdpngRHoRGNvQVGuxO3BJ7uNSgdeX166WXw==", "dev": true, "dependencies": { - "markdown-it": "13.0.1", - "markdownlint-micromark": "0.1.7" + "markdown-it": "14.1.0", + "markdownlint-micromark": "0.1.9" }, "engines": { - "node": ">=16" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" } }, "node_modules/markdownlint-cli2": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.10.0.tgz", - "integrity": "sha512-kVxjPyKFC+eW7iqcxiNI50RDzwugpXkEX5eQlDso/0IUs9M73jXYguLFHDzgi5KatcxU/57Fu8KoGtkFft9lfA==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.13.0.tgz", + "integrity": "sha512-Pg4nF7HlopU97ZXtrcVISWp3bdsuc5M0zXyLp2/sJv2zEMlInrau0ZKK482fQURzVezJzWBpNmu4u6vGAhij+g==", "dev": true, "dependencies": { - "globby": "13.2.2", - "markdownlint": "0.31.1", + "globby": "14.0.1", + "js-yaml": "4.1.0", + "jsonc-parser": "3.2.1", + "markdownlint": "0.34.0", "markdownlint-cli2-formatter-default": "0.0.4", - "micromatch": "4.0.5", - "strip-json-comments": "5.0.1", - "yaml": "2.3.2" + "micromatch": "4.0.5" }, "bin": { - "markdownlint-cli2": "markdownlint-cli2.js", - "markdownlint-cli2-config": "markdownlint-cli2-config.js", - "markdownlint-cli2-fix": "markdownlint-cli2-fix.js" + "markdownlint-cli2": "markdownlint-cli2.js" }, "engines": { - "node": ">=16" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" } }, "node_modules/markdownlint-cli2-formatter-default": { @@ -13241,29 +13344,48 @@ "markdownlint-cli2": ">=0.0.4" } }, + "node_modules/markdownlint-cli2/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "node_modules/markdownlint-cli2/node_modules/globby": { - "version": "13.2.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", - "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.1.tgz", + "integrity": "sha512-jOMLD2Z7MAhyG8aJpNOpmziMOP4rPLcc95oQPKXBazW82z+CEgPFBQvEpRUa1KeIMUJo4Wsm+q6uzO/Q/4BksQ==", "dev": true, "dependencies": { - "dir-glob": "^3.0.1", - "fast-glob": "^3.3.0", + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.2", "ignore": "^5.2.4", - "merge2": "^1.4.1", - "slash": "^4.0.0" + "path-type": "^5.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.1.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/markdownlint-cli2/node_modules/slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "node_modules/markdownlint-cli2/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/markdownlint-cli2/node_modules/path-type": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", "dev": true, "engines": { "node": ">=12" @@ -13272,10 +13394,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/markdownlint-cli2/node_modules/strip-json-comments": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.1.tgz", - "integrity": "sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw==", + "node_modules/markdownlint-cli2/node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", "dev": true, "engines": { "node": ">=14.16" @@ -13284,22 +13406,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/markdownlint-cli2/node_modules/yaml": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.2.tgz", - "integrity": "sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg==", - "dev": true, - "engines": { - "node": ">= 14" - } - }, "node_modules/markdownlint-micromark": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.7.tgz", - "integrity": "sha512-BbRPTC72fl5vlSKv37v/xIENSRDYL/7X/XoFzZ740FGEbs9vZerLrIkFRY0rv7slQKxDczToYuMmqQFN61fi4Q==", + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.9.tgz", + "integrity": "sha512-5hVs/DzAFa8XqYosbEAEg6ok6MF2smDj89ztn9pKkCtdKHVdPQuGMH7frFfYL9mLkvfFe4pTyAMffLbjf3/EyA==", "dev": true, "engines": { - "node": ">=16" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" } }, "node_modules/marked": { @@ -13341,9 +13457,9 @@ } }, "node_modules/mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", "dev": true }, "node_modules/media-typer": { @@ -14506,6 +14622,15 @@ "node": ">=6" } }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/pure-rand": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", @@ -16036,12 +16161,12 @@ "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" }, "node_modules/ts-api-utils": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", - "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, "engines": { - "node": ">=16.13.0" + "node": ">=16" }, "peerDependencies": { "typescript": ">=4.2.0" @@ -16296,9 +16421,9 @@ } }, "node_modules/uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", "dev": true }, "node_modules/ufo": { @@ -19330,11 +19455,6 @@ "readable-stream": "^4.2.0" }, "dependencies": { - "entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" - }, "htmlparser2": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.0.0.tgz", @@ -21116,6 +21236,12 @@ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.4.1.tgz", "integrity": "sha512-axlrvsHlHlFmKKMEg4VyvMzFr93JWJj4eIfXY1STVuO2fsImCa7ncaiG5gC8HKOX590AW5RtRsC41/B+OfrSqw==" }, + "@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "dev": true + }, "@sinonjs/commons": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", @@ -21658,9 +21784,9 @@ } }, "@types/jest": { - "version": "29.5.5", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.5.tgz", - "integrity": "sha512-ebylz2hnsWR9mYvmBFbXJXr+33UPc4+ZdxyDXh5w0FlPBTfCVN3wPL+kuOiQt3xvrK419v7XWeAs+AeOksafXg==", + "version": "29.5.12", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz", + "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", "dev": true, "requires": { "expect": "^29.0.0", @@ -22271,15 +22397,6 @@ "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.0.2" - }, - "dependencies": { - "entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true, - "peer": true - } } }, "@vue/compiler-dom": { @@ -23879,13 +23996,6 @@ "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" - }, - "dependencies": { - "entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" - } } }, "domelementtype": { @@ -24015,10 +24125,9 @@ } }, "entities": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", - "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", - "dev": true + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" }, "error-ex": { "version": "1.3.2", @@ -24396,12 +24505,92 @@ } }, "eslint-plugin-jest": { - "version": "27.4.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.4.3.tgz", - "integrity": "sha512-7S6SmmsHsgIm06BAGCAxL+ABd9/IB3MWkz2pudj6Qqor2y1qQpWPfuFU4SG9pWj4xDjF0e+D7Llh5useuSzAZw==", + "version": "28.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.6.0.tgz", + "integrity": "sha512-YG28E1/MIKwnz+e2H7VwYPzHUYU4aMa19w0yGcwXnnmJH6EfgHahTJ2un3IyraUxNfnz/KUhJAFXNNwWPo12tg==", "dev": true, "requires": { - "@typescript-eslint/utils": "^5.10.0" + "@typescript-eslint/utils": "^6.0.0 || ^7.0.0" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", + "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1" + } + }, + "@typescript-eslint/types": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", + "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", + "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + } + }, + "@typescript-eslint/utils": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.1.tgz", + "integrity": "sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/typescript-estree": "7.16.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", + "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "7.16.1", + "eslint-visitor-keys": "^3.4.3" + } + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true + } } }, "eslint-plugin-jsdoc": { @@ -24969,9 +25158,9 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "fast-glob": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", - "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -25603,13 +25792,6 @@ "domhandler": "^5.0.3", "domutils": "^3.0.1", "entities": "^4.4.0" - }, - "dependencies": { - "entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" - } } }, "http-assert": { @@ -26659,9 +26841,9 @@ } }, "jsonc-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", + "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", "dev": true }, "jsonfile": { @@ -26899,12 +27081,12 @@ "dev": true }, "linkify-it": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", - "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", "dev": true, "requires": { - "uc.micro": "^1.0.1" + "uc.micro": "^2.0.0" } }, "load-json-file": { @@ -27130,16 +27312,17 @@ "dev": true }, "markdown-it": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz", - "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", "dev": true, "requires": { "argparse": "^2.0.1", - "entities": "~3.0.1", - "linkify-it": "^4.0.1", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" }, "dependencies": { "argparse": { @@ -27151,58 +27334,68 @@ } }, "markdownlint": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.31.1.tgz", - "integrity": "sha512-CKMR2hgcIBrYlIUccDCOvi966PZ0kJExDrUi1R+oF9PvqQmCrTqjOsgIvf2403OmJ+CWomuzDoylr6KbuMyvHA==", + "version": "0.34.0", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.34.0.tgz", + "integrity": "sha512-qwGyuyKwjkEMOJ10XN6OTKNOVYvOIi35RNvDLNxTof5s8UmyGHlCdpngRHoRGNvQVGuxO3BJ7uNSgdeX166WXw==", "dev": true, "requires": { - "markdown-it": "13.0.1", - "markdownlint-micromark": "0.1.7" + "markdown-it": "14.1.0", + "markdownlint-micromark": "0.1.9" } }, "markdownlint-cli2": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.10.0.tgz", - "integrity": "sha512-kVxjPyKFC+eW7iqcxiNI50RDzwugpXkEX5eQlDso/0IUs9M73jXYguLFHDzgi5KatcxU/57Fu8KoGtkFft9lfA==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.13.0.tgz", + "integrity": "sha512-Pg4nF7HlopU97ZXtrcVISWp3bdsuc5M0zXyLp2/sJv2zEMlInrau0ZKK482fQURzVezJzWBpNmu4u6vGAhij+g==", "dev": true, "requires": { - "globby": "13.2.2", - "markdownlint": "0.31.1", + "globby": "14.0.1", + "js-yaml": "4.1.0", + "jsonc-parser": "3.2.1", + "markdownlint": "0.34.0", "markdownlint-cli2-formatter-default": "0.0.4", - "micromatch": "4.0.5", - "strip-json-comments": "5.0.1", - "yaml": "2.3.2" + "micromatch": "4.0.5" }, "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "globby": { - "version": "13.2.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", - "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.1.tgz", + "integrity": "sha512-jOMLD2Z7MAhyG8aJpNOpmziMOP4rPLcc95oQPKXBazW82z+CEgPFBQvEpRUa1KeIMUJo4Wsm+q6uzO/Q/4BksQ==", "dev": true, "requires": { - "dir-glob": "^3.0.1", - "fast-glob": "^3.3.0", + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.2", "ignore": "^5.2.4", - "merge2": "^1.4.1", - "slash": "^4.0.0" + "path-type": "^5.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.1.0" } }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "path-type": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", + "dev": true + }, "slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", - "dev": true - }, - "strip-json-comments": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.1.tgz", - "integrity": "sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw==", - "dev": true - }, - "yaml": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.2.tgz", - "integrity": "sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", "dev": true } } @@ -27215,9 +27408,9 @@ "requires": {} }, "markdownlint-micromark": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.7.tgz", - "integrity": "sha512-BbRPTC72fl5vlSKv37v/xIENSRDYL/7X/XoFzZ740FGEbs9vZerLrIkFRY0rv7slQKxDczToYuMmqQFN61fi4Q==", + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.9.tgz", + "integrity": "sha512-5hVs/DzAFa8XqYosbEAEg6ok6MF2smDj89ztn9pKkCtdKHVdPQuGMH7frFfYL9mLkvfFe4pTyAMffLbjf3/EyA==", "dev": true }, "marked": { @@ -27245,9 +27438,9 @@ "dev": true }, "mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", "dev": true }, "media-typer": { @@ -28106,6 +28299,12 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==" }, + "punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true + }, "pure-rand": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", @@ -29330,9 +29529,9 @@ "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" }, "ts-api-utils": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", - "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, "requires": {} }, @@ -29488,9 +29687,9 @@ "dev": true }, "uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", "dev": true }, "ufo": { diff --git a/package.json b/package.json index 57ceb2b43..4bbccd183 100644 --- a/package.json +++ b/package.json @@ -149,12 +149,12 @@ "@inrupt/solid-client-authn-core": "^2.0.0", "@inrupt/solid-client-authn-node": "^2.0.0", "@tsconfig/node18": "^18.2.2", - "@types/jest": "^29.5.5", + "@types/jest": "^29.5.12", "@types/set-cookie-parser": "^2.4.4", "@types/supertest": "^2.0.14", "commit-and-tag-version": "^11.3.0", "componentsjs-generator": "^3.1.2", - "eslint-plugin-jest": "^27.4.3", + "eslint-plugin-jest": "^28.6.0", "husky": "^4.3.8", "jest": "^29.7.0", "jest-esm-transformer-2": "^1.0.0", diff --git a/test/unit/http/output/error/ConvertingErrorHandler.test.ts b/test/unit/http/output/error/ConvertingErrorHandler.test.ts index 9630caf26..276d1fb0d 100644 --- a/test/unit/http/output/error/ConvertingErrorHandler.test.ts +++ b/test/unit/http/output/error/ConvertingErrorHandler.test.ts @@ -48,9 +48,11 @@ describe('A ConvertingErrorHandler', (): void => { ({ stack } = error); converter = { canHandle: jest.fn(), - handle: jest.fn((): Representation => new BasicRepresentation('serialization', 'text/turtle', true)), - handleSafe: jest.fn((): Representation => new BasicRepresentation('serialization', 'text/turtle', true)), - } as any; + handle: jest.fn(async(): Promise => + new BasicRepresentation('serialization', 'text/turtle', true)), + handleSafe: jest.fn(async(): Promise => + new BasicRepresentation('serialization', 'text/turtle', true)), + } satisfies Partial as any; preferenceParser = { canHandle: jest.fn(), @@ -80,7 +82,7 @@ describe('A ConvertingErrorHandler', (): void => { it('accepts input supported by the converter.', async(): Promise => { await expect(handler.canHandle({ error, request })).resolves.toBeUndefined(); expect(converter.canHandle).toHaveBeenCalledTimes(1); - const args = (converter.canHandle as jest.Mock).mock.calls[0][0] as RepresentationConverterArgs; + const args = converter.canHandle.mock.calls[0][0]; expect(args.preferences).toBe(preferences); expect(args.representation.metadata.contentType).toBe('internal/error'); }); @@ -90,7 +92,7 @@ describe('A ConvertingErrorHandler', (): void => { await expect(prom).resolves.toMatchObject({ statusCode: 404 }); expect((await prom).metadata?.contentType).toBe('text/turtle'); expect(converter.handle).toHaveBeenCalledTimes(1); - const args = (converter.handle as jest.Mock).mock.calls[0][0] as RepresentationConverterArgs; + const args = converter.handle.mock.calls[0][0]; await expectValidArgs(args, stack, cause); }); @@ -99,7 +101,7 @@ describe('A ConvertingErrorHandler', (): void => { await expect(prom).resolves.toMatchObject({ statusCode: 404 }); expect((await prom).metadata?.contentType).toBe('text/turtle'); expect(converter.handleSafe).toHaveBeenCalledTimes(1); - const args = (converter.handleSafe as jest.Mock).mock.calls[0][0] as RepresentationConverterArgs; + const args = converter.handleSafe.mock.calls[0][0]; await expectValidArgs(args, stack, cause); }); @@ -109,7 +111,7 @@ describe('A ConvertingErrorHandler', (): void => { await expect(prom).resolves.toMatchObject({ statusCode: 404 }); expect((await prom).metadata?.contentType).toBe('text/turtle'); expect(converter.handle).toHaveBeenCalledTimes(1); - const args = (converter.handle as jest.Mock).mock.calls[0][0] as RepresentationConverterArgs; + const args = converter.handle.mock.calls[0][0]; await expectValidArgs(args); }); }); diff --git a/test/unit/identity/configuration/IdentityProviderFactory.test.ts b/test/unit/identity/configuration/IdentityProviderFactory.test.ts index 5be2d5424..0146a47cf 100644 --- a/test/unit/identity/configuration/IdentityProviderFactory.test.ts +++ b/test/unit/identity/configuration/IdentityProviderFactory.test.ts @@ -1,6 +1,5 @@ import { Readable } from 'node:stream'; import { exportJWK, generateKeyPair } from 'jose'; -import type * as Koa from 'koa'; import type { ErrorHandler } from '../../../../src/http/output/error/ErrorHandler'; import type { ResponseWriter } from '../../../../src/http/output/ResponseWriter'; import { IdentityProviderFactory } from '../../../../src/identity/configuration/IdentityProviderFactory'; @@ -305,10 +304,9 @@ describe('An IdentityProviderFactory', (): void => { }); it('adds middleware to make the OIDC provider think the request wants HTML.', async(): Promise => { - const provider = await factory.getProvider() as any; - const use = provider.use as jest.Mock, Parameters>; - expect(use).toHaveBeenCalledTimes(1); - const middleware = use.mock.calls[0][0]; + const provider = await factory.getProvider(); + expect(provider.use).toHaveBeenCalledTimes(1); + const middleware = jest.mocked(provider.use).mock.calls[0][0]; // eslint-disable-next-line jest/unbound-method const oldAccept = ctx.accepts; @@ -321,10 +319,9 @@ describe('An IdentityProviderFactory', (): void => { }); it('does not modify the context accepts function in other cases.', async(): Promise => { - const provider = await factory.getProvider() as any; - const use = provider.use as jest.Mock, Parameters>; - expect(use).toHaveBeenCalledTimes(1); - const middleware = use.mock.calls[0][0]; + const provider = await factory.getProvider(); + expect(provider.use).toHaveBeenCalledTimes(1); + const middleware = jest.mocked(provider.use).mock.calls[0][0]; // eslint-disable-next-line jest/unbound-method const oldAccept = ctx.accepts; diff --git a/test/unit/identity/interaction/InteractionUtil.test.ts b/test/unit/identity/interaction/InteractionUtil.test.ts index 7c60676b1..92b766fca 100644 --- a/test/unit/identity/interaction/InteractionUtil.test.ts +++ b/test/unit/identity/interaction/InteractionUtil.test.ts @@ -97,7 +97,8 @@ describe('InteractionUtil', (): void => { await expect(forgetWebId(provider, oidcInteraction)).resolves.toBeUndefined(); expect(provider.Session.find).toHaveBeenCalledTimes(1); expect(provider.Session.find).toHaveBeenLastCalledWith('cookie'); - const session = await (provider.Session.find as jest.Mock).mock.results[0].value; + // eslint-disable-next-line jest/unbound-method + const session = await jest.mocked(provider.Session.find).mock.results[0].value; expect(session.accountId).toBeUndefined(); expect(session.persist).toHaveBeenCalledTimes(1); }); @@ -108,7 +109,8 @@ describe('InteractionUtil', (): void => { await expect(forgetWebId(provider, oidcInteraction)).resolves.toBeUndefined(); expect(provider.Grant.find).toHaveBeenCalledTimes(1); expect(provider.Grant.find).toHaveBeenLastCalledWith('grantId'); - const grant = await (provider.Grant.find as jest.Mock).mock.results[0].value; + // eslint-disable-next-line jest/unbound-method + const grant = await jest.mocked(provider.Grant.find).mock.results[0].value; expect(grant.destroy).toHaveBeenCalledTimes(1); }); }); diff --git a/test/unit/identity/interaction/oidc/PickWebIdHandler.test.ts b/test/unit/identity/interaction/oidc/PickWebIdHandler.test.ts index 2151e7196..a3f3de8b7 100644 --- a/test/unit/identity/interaction/oidc/PickWebIdHandler.test.ts +++ b/test/unit/identity/interaction/oidc/PickWebIdHandler.test.ts @@ -68,7 +68,8 @@ describe('A PickWebIdHandler', (): void => { expect(store.isLinked).toHaveBeenCalledTimes(1); expect(store.isLinked).toHaveBeenLastCalledWith(webId1, accountId); - expect((await (provider.Session.find as jest.Mock).mock.results[0].value).persist).toHaveBeenCalledTimes(1); + // eslint-disable-next-line jest/unbound-method + expect((await jest.mocked(provider.Session.find).mock.results[0].value).persist).toHaveBeenCalledTimes(1); expect(oidcInteraction.persist).toHaveBeenCalledTimes(1); expect(oidcInteraction.result).toEqual({ login: { diff --git a/test/unit/identity/ownership/TokenOwnershipValidator.test.ts b/test/unit/identity/ownership/TokenOwnershipValidator.test.ts index 8016f201d..4c71a9baa 100644 --- a/test/unit/identity/ownership/TokenOwnershipValidator.test.ts +++ b/test/unit/identity/ownership/TokenOwnershipValidator.test.ts @@ -43,7 +43,7 @@ describe('A TokenOwnershipValidator', (): void => { beforeEach(async(): Promise => { const now = Date.now(); jest.spyOn(Date, 'now').mockReturnValue(now); - (v4 as jest.Mock).mockReturnValue(token); + jest.mocked(v4).mockReturnValue(token); const map = new Map(); storage = { diff --git a/test/unit/identity/storage/ClientIdAdapterFactory.test.ts b/test/unit/identity/storage/ClientIdAdapterFactory.test.ts index 0b2c622a0..4a5bd7ff5 100644 --- a/test/unit/identity/storage/ClientIdAdapterFactory.test.ts +++ b/test/unit/identity/storage/ClientIdAdapterFactory.test.ts @@ -11,7 +11,7 @@ describe('A ClientIdAdapterFactory', (): void => { const id = 'https://app.example.com/card#me'; let json: any; let rdf: string; - let source: Adapter; + let source: jest.Mocked; let sourceFactory: AdapterFactory; let adapter: Adapter; const converter = new RdfToQuadConverter(); @@ -53,7 +53,7 @@ describe('A ClientIdAdapterFactory', (): void => { }); it('returns the source payload if there is one.', async(): Promise => { - (source.find as jest.Mock).mockResolvedValueOnce('payload!'); + source.find.mockResolvedValueOnce('payload!' as any); await expect(adapter.find(id)).resolves.toBe('payload!'); }); diff --git a/test/unit/init/AppRunner.test.ts b/test/unit/init/AppRunner.test.ts index 2013cd7d9..1e338fafa 100644 --- a/test/unit/init/AppRunner.test.ts +++ b/test/unit/init/AppRunner.test.ts @@ -489,7 +489,8 @@ describe('AppRunner', (): void => { }); it('throws an error if creating a ComponentsManager fails.', async(): Promise => { - (manager.configRegistry.register as jest.Mock).mockRejectedValueOnce(new Error('Fatal')); + // eslint-disable-next-line jest/unbound-method + jest.mocked(manager.configRegistry.register).mockRejectedValueOnce(new Error('Fatal')); let caughtError: Error = new Error('should disappear'); try { @@ -572,7 +573,8 @@ describe('AppRunner', (): void => { }); it('throws an error if non-error objects get thrown.', async(): Promise => { - (manager.configRegistry.register as jest.Mock).mockRejectedValueOnce('NotAnError'); + // eslint-disable-next-line jest/unbound-method + jest.mocked(manager.configRegistry.register).mockRejectedValueOnce('NotAnError'); let caughtError: Error = new Error('should disappear'); try { diff --git a/test/unit/storage/LockingResourceStore.test.ts b/test/unit/storage/LockingResourceStore.test.ts index 5fe7777bb..dbc8adc81 100644 --- a/test/unit/storage/LockingResourceStore.test.ts +++ b/test/unit/storage/LockingResourceStore.test.ts @@ -6,6 +6,7 @@ import type { ResourceIdentifier } from '../../../src/http/representation/Resour import { LockingResourceStore } from '../../../src/storage/LockingResourceStore'; import type { ResourceStore } from '../../../src/storage/ResourceStore'; import type { ExpiringReadWriteLocker } from '../../../src/util/locking/ExpiringReadWriteLocker'; +import type { ReadWriteLocker } from '../../../src/util/locking/ReadWriteLocker'; import type { PromiseOrValue } from '../../../src/util/PromiseUtil'; import { guardedStreamFrom } from '../../../src/util/StreamUtil'; import { flushPromises } from '../../util/Util'; @@ -19,7 +20,7 @@ describe('A LockingResourceStore', (): void => { const subjectId = { path: 'http://test.com/foo' }; const data = { data: 'data!' } as any; let store: LockingResourceStore; - let locker: ExpiringReadWriteLocker; + let locker: jest.Mocked; let source: ResourceStore; let auxiliaryStrategy: AuxiliaryIdentifierStrategy; let order: string[]; @@ -62,7 +63,7 @@ describe('A LockingResourceStore', (): void => { } finally { order.push('unlock read'); } - }), + }) satisfies ReadWriteLocker['withReadLock'] as any, withWriteLock: jest.fn(async ( identifier: ResourceIdentifier, whileLocked: (maintainLock: () => void) => PromiseOrValue, @@ -73,7 +74,7 @@ describe('A LockingResourceStore', (): void => { } finally { order.push('unlock write'); } - }), + }) satisfies ReadWriteLocker['withWriteLock'] as any, }; auxiliaryStrategy = { @@ -93,7 +94,7 @@ describe('A LockingResourceStore', (): void => { it('acquires a lock on the container when adding a representation.', async(): Promise => { await store.addResource(subjectId, data); expect(locker.withWriteLock).toHaveBeenCalledTimes(1); - expect((locker.withWriteLock as jest.Mock).mock.calls[0][0]).toEqual(subjectId); + expect(locker.withWriteLock.mock.calls[0][0]).toEqual(subjectId); expect(source.addResource).toHaveBeenCalledTimes(1); expect(source.addResource).toHaveBeenLastCalledWith(subjectId, data, undefined); expect(order).toEqual([ 'lock write', 'addResource', 'unlock write' ]); @@ -101,7 +102,7 @@ describe('A LockingResourceStore', (): void => { order = []; await expect(store.addResource(auxiliaryId, data)).resolves.toBeUndefined(); expect(locker.withWriteLock).toHaveBeenCalledTimes(2); - expect((locker.withWriteLock as jest.Mock).mock.calls[1][0]).toEqual(subjectId); + expect(locker.withWriteLock.mock.calls[1][0]).toEqual(subjectId); expect(source.addResource).toHaveBeenCalledTimes(2); expect(source.addResource).toHaveBeenLastCalledWith(auxiliaryId, data, undefined); expect(order).toEqual([ 'lock write', 'addResource', 'unlock write' ]); @@ -110,7 +111,7 @@ describe('A LockingResourceStore', (): void => { it('acquires a lock on the resource when setting its representation.', async(): Promise => { await store.setRepresentation(subjectId, data); expect(locker.withWriteLock).toHaveBeenCalledTimes(1); - expect((locker.withWriteLock as jest.Mock).mock.calls[0][0]).toEqual(subjectId); + expect(locker.withWriteLock.mock.calls[0][0]).toEqual(subjectId); expect(source.setRepresentation).toHaveBeenCalledTimes(1); expect(source.setRepresentation).toHaveBeenLastCalledWith(subjectId, data, undefined); expect(order).toEqual([ 'lock write', 'setRepresentation', 'unlock write' ]); @@ -118,7 +119,7 @@ describe('A LockingResourceStore', (): void => { order = []; await expect(store.setRepresentation(auxiliaryId, data)).resolves.toBeUndefined(); expect(locker.withWriteLock).toHaveBeenCalledTimes(2); - expect((locker.withWriteLock as jest.Mock).mock.calls[1][0]).toEqual(subjectId); + expect(locker.withWriteLock.mock.calls[1][0]).toEqual(subjectId); expect(source.setRepresentation).toHaveBeenCalledTimes(2); expect(source.setRepresentation).toHaveBeenLastCalledWith(auxiliaryId, data, undefined); expect(order).toEqual([ 'lock write', 'setRepresentation', 'unlock write' ]); @@ -127,7 +128,7 @@ describe('A LockingResourceStore', (): void => { it('acquires a lock on the resource when deleting it.', async(): Promise => { await store.deleteResource(subjectId); expect(locker.withWriteLock).toHaveBeenCalledTimes(1); - expect((locker.withWriteLock as jest.Mock).mock.calls[0][0]).toEqual(subjectId); + expect(locker.withWriteLock.mock.calls[0][0]).toEqual(subjectId); expect(source.deleteResource).toHaveBeenCalledTimes(1); expect(source.deleteResource).toHaveBeenLastCalledWith(subjectId, undefined); expect(order).toEqual([ 'lock write', 'deleteResource', 'unlock write' ]); @@ -135,7 +136,7 @@ describe('A LockingResourceStore', (): void => { order = []; await expect(store.deleteResource(auxiliaryId)).resolves.toBeUndefined(); expect(locker.withWriteLock).toHaveBeenCalledTimes(2); - expect((locker.withWriteLock as jest.Mock).mock.calls[1][0]).toEqual(subjectId); + expect(locker.withWriteLock.mock.calls[1][0]).toEqual(subjectId); expect(source.deleteResource).toHaveBeenCalledTimes(2); expect(source.deleteResource).toHaveBeenLastCalledWith(auxiliaryId, undefined); expect(order).toEqual([ 'lock write', 'deleteResource', 'unlock write' ]); @@ -144,7 +145,7 @@ describe('A LockingResourceStore', (): void => { it('acquires a lock on the resource when modifying its representation.', async(): Promise => { await store.modifyResource(subjectId, data as Patch); expect(locker.withWriteLock).toHaveBeenCalledTimes(1); - expect((locker.withWriteLock as jest.Mock).mock.calls[0][0]).toEqual(subjectId); + expect(locker.withWriteLock.mock.calls[0][0]).toEqual(subjectId); expect(source.modifyResource).toHaveBeenCalledTimes(1); expect(source.modifyResource).toHaveBeenLastCalledWith(subjectId, data, undefined); expect(order).toEqual([ 'lock write', 'modifyResource', 'unlock write' ]); @@ -152,7 +153,7 @@ describe('A LockingResourceStore', (): void => { order = []; await expect(store.modifyResource(auxiliaryId, data as Patch)).resolves.toBeUndefined(); expect(locker.withWriteLock).toHaveBeenCalledTimes(2); - expect((locker.withWriteLock as jest.Mock).mock.calls[1][0]).toEqual(subjectId); + expect(locker.withWriteLock.mock.calls[1][0]).toEqual(subjectId); expect(source.modifyResource).toHaveBeenCalledTimes(2); expect(source.modifyResource).toHaveBeenLastCalledWith(auxiliaryId, data, undefined); expect(order).toEqual([ 'lock write', 'modifyResource', 'unlock write' ]); @@ -165,7 +166,7 @@ describe('A LockingResourceStore', (): void => { }; await expect(store.getRepresentation(subjectId, {})).rejects.toThrow('dummy'); expect(locker.withReadLock).toHaveBeenCalledTimes(1); - expect((locker.withReadLock as jest.Mock).mock.calls[0][0]).toEqual(subjectId); + expect(locker.withReadLock.mock.calls[0][0]).toEqual(subjectId); expect(order).toEqual([ 'lock read', 'bad get', 'unlock read' ]); }); @@ -180,7 +181,7 @@ describe('A LockingResourceStore', (): void => { // Verify the lock was acquired and released at the right time expect(locker.withReadLock).toHaveBeenCalledTimes(1); - expect((locker.withReadLock as jest.Mock).mock.calls[0][0]).toEqual(subjectId); + expect(locker.withReadLock.mock.calls[0][0]).toEqual(subjectId); expect(source.getRepresentation).toHaveBeenCalledTimes(1); expect(source.getRepresentation).toHaveBeenLastCalledWith(subjectId, {}, undefined); expect(order).toEqual([ 'lock read', 'getRepresentation', 'end', 'unlock read' ]); @@ -197,7 +198,7 @@ describe('A LockingResourceStore', (): void => { // Verify the lock was acquired and released at the right time expect(locker.withReadLock).toHaveBeenCalledTimes(1); - expect((locker.withReadLock as jest.Mock).mock.calls[0][0]).toEqual(subjectId); + expect(locker.withReadLock.mock.calls[0][0]).toEqual(subjectId); expect(source.getRepresentation).toHaveBeenCalledTimes(1); expect(source.getRepresentation).toHaveBeenLastCalledWith(auxiliaryId, {}, undefined); expect(order).toEqual([ 'lock read', 'getRepresentation', 'end', 'unlock read' ]); @@ -215,7 +216,7 @@ describe('A LockingResourceStore', (): void => { // Verify the lock was acquired and released at the right time expect(locker.withReadLock).toHaveBeenCalledTimes(1); - expect((locker.withReadLock as jest.Mock).mock.calls[0][0]).toEqual(subjectId); + expect(locker.withReadLock.mock.calls[0][0]).toEqual(subjectId); expect(source.getRepresentation).toHaveBeenCalledTimes(1); expect(representation.data.destroy).toHaveBeenCalledTimes(1); expect(order).toEqual([ 'lock read', 'getRepresentation', 'error', 'unlock read', 'close' ]); @@ -232,7 +233,7 @@ describe('A LockingResourceStore', (): void => { // Verify the lock was acquired and released at the right time expect(locker.withReadLock).toHaveBeenCalledTimes(1); - expect((locker.withReadLock as jest.Mock).mock.calls[0][0]).toEqual(subjectId); + expect(locker.withReadLock.mock.calls[0][0]).toEqual(subjectId); expect(source.getRepresentation).toHaveBeenCalledTimes(1); expect(order).toEqual([ 'lock read', 'getRepresentation', 'close', 'unlock read' ]); }); @@ -251,7 +252,7 @@ describe('A LockingResourceStore', (): void => { // Verify the lock was acquired and released at the right time expect(locker.withReadLock).toHaveBeenCalledTimes(1); - expect((locker.withReadLock as jest.Mock).mock.calls[0][0]).toEqual(subjectId); + expect(locker.withReadLock.mock.calls[0][0]).toEqual(subjectId); expect(source.getRepresentation).toHaveBeenCalledTimes(1); expect(order).toEqual([ 'lock read', 'getRepresentation', 'end', 'unlock read' ]); }); @@ -268,7 +269,7 @@ describe('A LockingResourceStore', (): void => { // Verify the lock was acquired and released at the right time expect(locker.withReadLock).toHaveBeenCalledTimes(1); - expect((locker.withReadLock as jest.Mock).mock.calls[0][0]).toEqual(subjectId); + expect(locker.withReadLock.mock.calls[0][0]).toEqual(subjectId); expect(source.getRepresentation).toHaveBeenCalledTimes(1); expect(representation.data.destroy).toHaveBeenCalledTimes(1); expect(representation.data.destroy).toHaveBeenLastCalledWith(new Error('timeout')); @@ -288,7 +289,7 @@ describe('A LockingResourceStore', (): void => { await expect(prom).rejects.toThrow('timeout'); expect(locker.withReadLock).toHaveBeenCalledTimes(1); - expect((locker.withReadLock as jest.Mock).mock.calls[0][0]).toEqual(subjectId); + expect(locker.withReadLock.mock.calls[0][0]).toEqual(subjectId); expect(source.getRepresentation).toHaveBeenCalledTimes(1); expect(order).toEqual([ 'lock read', 'useless get', 'timeout', 'unlock read' ]); }); diff --git a/test/unit/storage/PatchingStore.test.ts b/test/unit/storage/PatchingStore.test.ts index 7c08840dc..04403f5a9 100644 --- a/test/unit/storage/PatchingStore.test.ts +++ b/test/unit/storage/PatchingStore.test.ts @@ -6,14 +6,14 @@ import { NotImplementedHttpError } from '../../../src/util/errors/NotImplemented describe('A PatchingStore', (): void => { let store: PatchingStore; - let source: ResourceStore; + let source: jest.Mocked; let patcher: PatchHandler; let handleSafeFn: jest.Mock, []>; beforeEach(async(): Promise => { source = { modifyResource: jest.fn(async(): Promise => 'modify'), - } as unknown as ResourceStore; + } satisfies Partial as any; handleSafeFn = jest.fn(async(): Promise => 'patcher'); patcher = { handleSafe: handleSafeFn } as unknown as PatchHandler; @@ -34,7 +34,7 @@ describe('A PatchingStore', (): void => { await expect(store.modifyResource({ path: 'modifyPath' }, {} as Patch)).resolves.toBe('patcher'); expect(source.modifyResource).toHaveBeenCalledTimes(1); expect(source.modifyResource).toHaveBeenLastCalledWith({ path: 'modifyPath' }, {}, undefined); - await expect((source.modifyResource as jest.Mock).mock.results[0].value).rejects.toThrow(NotImplementedHttpError); + await expect(source.modifyResource.mock.results[0].value).rejects.toThrow(NotImplementedHttpError); expect(handleSafeFn).toHaveBeenCalledTimes(1); expect(handleSafeFn).toHaveBeenLastCalledWith({ source, identifier: { path: 'modifyPath' }, patch: {}}); }); diff --git a/test/unit/storage/conversion/ChainedConverter.test.ts b/test/unit/storage/conversion/ChainedConverter.test.ts index cce8db779..d0a05d0d4 100644 --- a/test/unit/storage/conversion/ChainedConverter.test.ts +++ b/test/unit/storage/conversion/ChainedConverter.test.ts @@ -174,13 +174,13 @@ describe('A ChainedConverter', (): void => { ]; const converter = new ChainedConverter(converters); - jest.spyOn(converters[0], 'handle'); - jest.spyOn(converters[1], 'handle'); + const spy0 = jest.spyOn(converters[0], 'handle'); + const spy1 = jest.spyOn(converters[1], 'handle'); const result = await converter.handle(args); expect(result.metadata.contentType).toBe('x/x'); - let { metadata } = await (converters[0].handle as jest.Mock).mock.results[0].value; + let { metadata } = await spy0.mock.results[0].value; expect(metadata.contentType).toBe('c/c'); - ({ metadata } = await (converters[1].handle as jest.Mock).mock.results[0].value); + ({ metadata } = await spy1.mock.results[0].value); expect(metadata.contentType).toBe('d/d'); }); diff --git a/test/unit/util/StreamUtil.test.ts b/test/unit/util/StreamUtil.test.ts index 743ef4e2b..cd85e8e04 100644 --- a/test/unit/util/StreamUtil.test.ts +++ b/test/unit/util/StreamUtil.test.ts @@ -143,7 +143,7 @@ describe('StreamUtil', (): void => { }); it('does not destroy the source stream if it is an HttpRequest.', async(): Promise => { - (isHttpRequest as unknown as jest.Mock).mockReturnValueOnce(true); + jest.mocked(isHttpRequest).mockReturnValueOnce(true); const input = new PassThrough(); const output = new PassThrough(); const piped = pipeSafely(input, output); @@ -160,7 +160,7 @@ describe('StreamUtil', (): void => { }); it('still sends errors downstream if the input is an HttpRequest.', async(): Promise => { - (isHttpRequest as unknown as jest.Mock).mockReturnValueOnce(true); + jest.mocked(isHttpRequest).mockReturnValueOnce(true); const input = new PassThrough(); input.read = (): any => { input.emit('error', new Error('error')); @@ -172,7 +172,7 @@ describe('StreamUtil', (): void => { }); it('can map errors if the input is an HttpRequest.', async(): Promise => { - (isHttpRequest as unknown as jest.Mock).mockReturnValueOnce(true); + jest.mocked(isHttpRequest).mockReturnValueOnce(true); const input = Readable.from([ 'data' ]); input.read = (): any => { input.emit('error', new Error('error')); diff --git a/test/unit/util/locking/WrappedExpiringReadWriteLocker.test.ts b/test/unit/util/locking/WrappedExpiringReadWriteLocker.test.ts index 9f98bc447..cc6963987 100644 --- a/test/unit/util/locking/WrappedExpiringReadWriteLocker.test.ts +++ b/test/unit/util/locking/WrappedExpiringReadWriteLocker.test.ts @@ -9,16 +9,16 @@ describe('A WrappedExpiringReadWriteLocker', (): void => { const identifier = { path: 'path' }; let syncCb: () => string; let asyncCb: () => Promise; - let wrappedLocker: ReadWriteLocker; + let wrappedLocker: jest.Mocked; let locker: WrappedExpiringReadWriteLocker; const expiration = 1000; beforeEach(async(): Promise => { wrappedLocker = { withReadLock: jest.fn(async(id: ResourceIdentifier, whileLocked: () => PromiseOrValue): - Promise => whileLocked()), + Promise => whileLocked()) satisfies ReadWriteLocker['withReadLock'] as any, withWriteLock: jest.fn(async(id: ResourceIdentifier, whileLocked: () => PromiseOrValue): - Promise => whileLocked()), + Promise => whileLocked()) satisfies ReadWriteLocker['withWriteLock'] as any, }; syncCb = jest.fn((): string => 'sync'); @@ -33,12 +33,12 @@ describe('A WrappedExpiringReadWriteLocker', (): void => { let prom = locker.withReadLock(identifier, syncCb); await expect(prom).resolves.toBe('sync'); expect(wrappedLocker.withReadLock).toHaveBeenCalledTimes(1); - expect((wrappedLocker.withReadLock as jest.Mock).mock.calls[0][0]).toBe(identifier); + expect(wrappedLocker.withReadLock.mock.calls[0][0]).toBe(identifier); prom = locker.withWriteLock(identifier, syncCb); await expect(prom).resolves.toBe('sync'); expect(wrappedLocker.withWriteLock).toHaveBeenCalledTimes(1); - expect((wrappedLocker.withWriteLock as jest.Mock).mock.calls[0][0]).toBe(identifier); + expect(wrappedLocker.withWriteLock.mock.calls[0][0]).toBe(identifier); }); it('calls the functions that need to be locked through the wrapped locker.', async(): Promise => { From ecd031e69f7c317ae03411c680682a1dcdff542e Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Thu, 18 Jul 2024 11:03:30 +0200 Subject: [PATCH 56/71] chore: Update lint dependencies --- .../handler/base/provider-factory.json | 13 +- eslint.config.js | 8 +- eslint/file-names.js | 4 +- eslint/general.js | 4 +- eslint/test.js | 2 +- eslint/typed.js | 3 + eslint/unicorn.js | 2 +- package-lock.json | 5842 +++++++++-------- package.json | 10 +- scripts/formatChangelog.ts | 2 +- src/authentication/UnsecureWebIdExtractor.ts | 2 +- src/authorization/AcpReader.ts | 2 +- src/authorization/WebAclReader.ts | 4 +- .../access/AgentGroupAccessChecker.ts | 4 +- src/http/UnsecureWebSocketsProtocol.ts | 2 +- .../account/util/BaseCookieStore.ts | 2 +- .../account/util/BaseLoginAccountStorage.ts | 2 +- src/init/migration/V6MigrationInitializer.ts | 2 +- src/pods/generate/BaseComponentsJsFactory.ts | 2 +- src/server/util/RedirectingHttpHandler.ts | 2 +- src/storage/DataAccessorBasedStore.ts | 2 +- src/storage/accessors/FileDataAccessor.ts | 2 +- src/storage/accessors/SparqlDataAccessor.ts | 2 +- .../ContainerToTemplateConverter.ts | 2 +- src/storage/keyvalue/JsonResourceStorage.ts | 5 +- src/storage/mapping/ExtensionBasedMapper.ts | 2 +- src/util/Header.ts | 2 +- src/util/HeaderUtil.ts | 2 +- src/util/PathUtil.ts | 6 +- src/util/RecordObject.ts | 1 + src/util/errors/ErrorUtil.ts | 6 +- src/util/errors/MethodNotAllowedHttpError.ts | 2 + test/integration/Config.ts | 2 +- test/unit/init/AppRunner.test.ts | 10 +- .../storage/DataAccessorBasedStore.test.ts | 8 +- .../storage/keyvalue/JsonFileStorage.test.ts | 4 +- test/util/Util.ts | 8 +- 37 files changed, 3049 insertions(+), 2931 deletions(-) diff --git a/config/identity/handler/base/provider-factory.json b/config/identity/handler/base/provider-factory.json index 73d1cd6e6..da61981e0 100644 --- a/config/identity/handler/base/provider-factory.json +++ b/config/identity/handler/base/provider-factory.json @@ -39,9 +39,16 @@ }, "enabledJWA": { "dPoPSigningAlgValues": [ - "RS256", "RS384", "RS512", - "PS256", "PS384", "PS512", - "ES256", "ES256K", "ES384", "ES512", + "RS256", + "RS384", + "RS512", + "PS256", + "PS384", + "PS512", + "ES256", + "ES256K", + "ES384", + "ES512", "EdDSA" ] }, diff --git a/eslint.config.js b/eslint.config.js index cc1658728..3829d0be2 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -16,7 +16,7 @@ antfu.GLOB_EXCLUDE.splice(index, 1); module.exports = antfu.default( { // Don't want to lint test assets, or TS snippets in markdown files - ignores: [ 'test/assets/*', '**/*.md/**/*.ts' ], + ignores: [ 'test/assets/*', '**/*.md' ], typescript: { tsconfigPath: [ './tsconfig.json', './scripts/tsconfig.json', './test/tsconfig.json' ], }, @@ -26,12 +26,12 @@ module.exports = antfu.default( .append(unicornConfig) .append(fileNamesConfig) // Using an override here so all the type settings are also applied correctly - .override('antfu:typescript:rules-type-aware', typedConfig) + .override('antfu/typescript/rules-type-aware', typedConfig) .append({ ...testConfig, files: [ 'test/**/*.ts' ], }) - .override('antfu:jsonc:rules', { + .override('antfu/jsonc/rules', { rules: { // Consistent with how we do it in code 'jsonc/array-bracket-spacing': [ 'error', 'always', { @@ -48,7 +48,7 @@ module.exports = antfu.default( 'unicorn/filename-case': 'off', }, }) - .override('antfu:markdown:parser', { + .override('antfu/markdown/parser', { rules: { // We want to be able to use these in Markdown text 'no-irregular-whitespace': 'off', diff --git a/eslint/file-names.js b/eslint/file-names.js index e67704730..a394deb12 100644 --- a/eslint/file-names.js +++ b/eslint/file-names.js @@ -1,6 +1,6 @@ module.exports = [ { - name: 'opinionated:file-names:all', + name: 'opinionated/file-names/all', rules: { 'unicorn/filename-case': [ 'error', { cases: { @@ -17,7 +17,7 @@ module.exports = [ }, }, { - name: 'opinionated:file-names:ts', + name: 'opinionated/file-names/ts', files: [ '**/*.ts' ], rules: { 'unicorn/filename-case': [ 'error', { diff --git a/eslint/general.js b/eslint/general.js index 04fd2c106..7bc7ad31e 100644 --- a/eslint/general.js +++ b/eslint/general.js @@ -1,5 +1,5 @@ module.exports = { - name: 'opinionated:general', + name: 'opinionated/general', rules: { 'antfu/consistent-list-newline': 'error', @@ -126,6 +126,8 @@ module.exports = { 'ts/prefer-for-of': 'error', 'ts/prefer-function-type': 'error', + // Only need 1 unused vars rule + 'no-unused-vars': 'off', 'unused-imports/no-unused-vars': [ 'error', { args: 'after-used', vars: 'all', ignoreRestSiblings: true }, diff --git a/eslint/test.js b/eslint/test.js index a2487c422..5e0be0e57 100644 --- a/eslint/test.js +++ b/eslint/test.js @@ -2,7 +2,7 @@ const jest = require('eslint-plugin-jest'); // Specifically for tests module.exports = { - name: 'opinionated:test', + name: 'opinionated/test', // See https://github.com/jest-community/eslint-plugin-jest/issues/1408 plugins: { jest, diff --git a/eslint/typed.js b/eslint/typed.js index 47a3d0b74..092da2661 100644 --- a/eslint/typed.js +++ b/eslint/typed.js @@ -1,4 +1,5 @@ module.exports = { + name: 'opinionated/typed', rules: { 'ts/consistent-type-assertions': [ 'error', { assertionStyle: 'as', @@ -45,6 +46,8 @@ module.exports = { 'ts/prefer-readonly': 'error', 'ts/prefer-reduce-type-parameter': 'error', 'ts/prefer-regexp-exec': 'error', + // Not sure if this would make code better + 'ts/strict-boolean-expressions': 'off', 'ts/prefer-string-starts-ends-with': 'error', 'ts/require-array-sort-compare': 'error', diff --git a/eslint/unicorn.js b/eslint/unicorn.js index 5371b1a97..8cf054908 100644 --- a/eslint/unicorn.js +++ b/eslint/unicorn.js @@ -1,5 +1,5 @@ module.exports = { - name: 'opinionated:unicorn', + name: 'opinionated/unicorn', rules: { 'unicorn/better-regex': 'error', 'unicorn/empty-brace-spaces': 'error', diff --git a/package-lock.json b/package-lock.json index 809ac2068..6376bfa29 100644 --- a/package-lock.json +++ b/package-lock.json @@ -82,9 +82,9 @@ "community-solid-server": "bin/server.js" }, "devDependencies": { - "@antfu/eslint-config": "2.11.4", - "@commitlint/cli": "^17.7.2", - "@commitlint/config-conventional": "^17.7.0", + "@antfu/eslint-config": "2.21.3", + "@commitlint/cli": "^19.3.0", + "@commitlint/config-conventional": "^19.2.2", "@inrupt/solid-client-authn-core": "^2.0.0", "@inrupt/solid-client-authn-node": "^2.0.0", "@tsconfig/node18": "^18.2.2", @@ -106,8 +106,8 @@ "supertest": "^6.3.3", "ts-jest": "^29.1.1", "ts-node": "^10.9.1", - "typedoc": "^0.25.2", - "typescript": "^5.2.2" + "typedoc": "^0.26.4", + "typescript": "^5.5.3" }, "engines": { "node": ">=18.0" @@ -137,43 +137,45 @@ } }, "node_modules/@antfu/eslint-config": { - "version": "2.11.4", - "resolved": "https://registry.npmjs.org/@antfu/eslint-config/-/eslint-config-2.11.4.tgz", - "integrity": "sha512-kQC8XFKih5igRodfDBpXIi3KFsjYuCfX2F9VK4hk79+KkDETUF/14ymai4O+Y+vmSNdRFwjtDL5YhcRoaD0rAg==", + "version": "2.21.3", + "resolved": "https://registry.npmjs.org/@antfu/eslint-config/-/eslint-config-2.21.3.tgz", + "integrity": "sha512-nY2pYSJGo5utj8LSMHIkJVMv04PTX9Cpu78ciCgkO5R5DOHyilvXXAEe+iwXkvaaRTmtDqhnhbIPFxKCiaqFNA==", "dev": true, "dependencies": { - "@antfu/install-pkg": "^0.3.1", + "@antfu/install-pkg": "^0.3.3", "@clack/prompts": "^0.7.0", - "@stylistic/eslint-plugin": "^1.7.0", - "@typescript-eslint/eslint-plugin": "^7.4.0", - "@typescript-eslint/parser": "^7.4.0", - "eslint-config-flat-gitignore": "^0.1.3", - "eslint-flat-config-utils": "^0.1.1", + "@stylistic/eslint-plugin": "^2.3.0", + "@typescript-eslint/eslint-plugin": "^7.15.0", + "@typescript-eslint/parser": "^7.15.0", + "eslint-config-flat-gitignore": "^0.1.5", + "eslint-flat-config-utils": "^0.2.5", "eslint-merge-processors": "^0.1.0", - "eslint-plugin-antfu": "^2.1.2", + "eslint-plugin-antfu": "^2.3.4", + "eslint-plugin-command": "^0.2.3", "eslint-plugin-eslint-comments": "^3.2.0", - "eslint-plugin-import-x": "^0.4.4", - "eslint-plugin-jsdoc": "^48.2.1", - "eslint-plugin-jsonc": "^2.14.1", - "eslint-plugin-markdown": "^4.0.1", - "eslint-plugin-n": "^16.6.2", + "eslint-plugin-import-x": "^0.5.3", + "eslint-plugin-jsdoc": "^48.5.2", + "eslint-plugin-jsonc": "^2.16.0", + "eslint-plugin-markdown": "^5.0.0", + "eslint-plugin-n": "^17.9.0", "eslint-plugin-no-only-tests": "^3.1.0", - "eslint-plugin-perfectionist": "^2.7.0", - "eslint-plugin-toml": "^0.10.0", - "eslint-plugin-unicorn": "^51.0.1", - "eslint-plugin-unused-imports": "^3.1.0", - "eslint-plugin-vitest": "^0.4.0", - "eslint-plugin-vue": "^9.24.0", - "eslint-plugin-yml": "^1.13.2", - "eslint-processor-vue-blocks": "^0.1.1", - "globals": "^15.0.0", + "eslint-plugin-perfectionist": "^2.11.0", + "eslint-plugin-regexp": "^2.6.0", + "eslint-plugin-toml": "^0.11.1", + "eslint-plugin-unicorn": "^54.0.0", + "eslint-plugin-unused-imports": "^3.2.0", + "eslint-plugin-vitest": "^0.5.4", + "eslint-plugin-vue": "^9.27.0", + "eslint-plugin-yml": "^1.14.0", + "eslint-processor-vue-blocks": "^0.1.2", + "globals": "^15.8.0", "jsonc-eslint-parser": "^2.4.0", "local-pkg": "^0.5.0", "parse-gitignore": "^2.0.0", - "picocolors": "^1.0.0", - "toml-eslint-parser": "^0.9.3", - "vue-eslint-parser": "^9.4.2", - "yaml-eslint-parser": "^1.2.2", + "picocolors": "^1.0.1", + "toml-eslint-parser": "^0.10.0", + "vue-eslint-parser": "^9.4.3", + "yaml-eslint-parser": "^1.2.3", "yargs": "^17.7.2" }, "bin": { @@ -183,20 +185,28 @@ "url": "https://github.com/sponsors/antfu" }, "peerDependencies": { + "@eslint-react/eslint-plugin": "^1.5.8", + "@prettier/plugin-xml": "^3.4.1", "@unocss/eslint-plugin": ">=0.50.0", - "astro-eslint-parser": "^0.16.3", + "astro-eslint-parser": "^1.0.2", "eslint": ">=8.40.0", - "eslint-plugin-astro": "^0.31.4", + "eslint-plugin-astro": "^1.2.0", "eslint-plugin-format": ">=0.1.0", - "eslint-plugin-react": "^7.33.2", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.4", - "eslint-plugin-svelte": "^2.35.1", + "eslint-plugin-solid": "^0.13.2", + "eslint-plugin-svelte": ">=2.35.1", "prettier-plugin-astro": "^0.13.0", "prettier-plugin-slidev": "^1.0.5", - "svelte-eslint-parser": "^0.33.1" + "svelte-eslint-parser": ">=0.37.0" }, "peerDependenciesMeta": { + "@eslint-react/eslint-plugin": { + "optional": true + }, + "@prettier/plugin-xml": { + "optional": true + }, "@unocss/eslint-plugin": { "optional": true }, @@ -209,15 +219,15 @@ "eslint-plugin-format": { "optional": true }, - "eslint-plugin-react": { - "optional": true - }, "eslint-plugin-react-hooks": { "optional": true }, "eslint-plugin-react-refresh": { "optional": true }, + "eslint-plugin-solid": { + "optional": true + }, "eslint-plugin-svelte": { "optional": true }, @@ -233,22 +243,20 @@ } }, "node_modules/@antfu/eslint-config/node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.4.0.tgz", - "integrity": "sha512-yHMQ/oFaM7HZdVrVm/M2WHaNPgyuJH4WelkSVEWSSsir34kxW2kDJCxlXRhhGWEsMN0WAW/vLpKfKVcm8k+MPw==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz", + "integrity": "sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A==", "dev": true, "dependencies": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "7.4.0", - "@typescript-eslint/type-utils": "7.4.0", - "@typescript-eslint/utils": "7.4.0", - "@typescript-eslint/visitor-keys": "7.4.0", - "debug": "^4.3.4", + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/type-utils": "7.16.1", + "@typescript-eslint/utils": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", "graphemer": "^1.4.0", - "ignore": "^5.2.4", + "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "ts-api-utils": "^1.3.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -268,15 +276,15 @@ } }, "node_modules/@antfu/eslint-config/node_modules/@typescript-eslint/parser": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.4.0.tgz", - "integrity": "sha512-ZvKHxHLusweEUVwrGRXXUVzFgnWhigo4JurEj0dGF1tbcGh6buL+ejDdjxOQxv6ytcY1uhun1p2sm8iWStlgLQ==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.16.1.tgz", + "integrity": "sha512-u+1Qx86jfGQ5i4JjK33/FnawZRpsLxRnKzGE6EABZ40KxVT/vWsiZFEBBHjFOljmmV3MBYOHEKi0Jm9hbAOClA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.4.0", - "@typescript-eslint/types": "7.4.0", - "@typescript-eslint/typescript-estree": "7.4.0", - "@typescript-eslint/visitor-keys": "7.4.0", + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/typescript-estree": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", "debug": "^4.3.4" }, "engines": { @@ -295,33 +303,16 @@ } } }, - "node_modules/@antfu/eslint-config/node_modules/@typescript-eslint/scope-manager": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.4.0.tgz", - "integrity": "sha512-68VqENG5HK27ypafqLVs8qO+RkNc7TezCduYrx8YJpXq2QGZ30vmNZGJJJC48+MVn4G2dCV8m5ZTVnzRexTVtw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.4.0", - "@typescript-eslint/visitor-keys": "7.4.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@antfu/eslint-config/node_modules/@typescript-eslint/type-utils": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.4.0.tgz", - "integrity": "sha512-247ETeHgr9WTRMqHbbQdzwzhuyaJ8dPTuyuUEMANqzMRB1rj/9qFIuIXK7l0FX9i9FXbHeBQl/4uz6mYuCE7Aw==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.1.tgz", + "integrity": "sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.4.0", - "@typescript-eslint/utils": "7.4.0", + "@typescript-eslint/typescript-estree": "7.16.1", + "@typescript-eslint/utils": "7.16.1", "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" + "ts-api-utils": "^1.3.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -340,9 +331,9 @@ } }, "node_modules/@antfu/eslint-config/node_modules/@typescript-eslint/types": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.4.0.tgz", - "integrity": "sha512-mjQopsbffzJskos5B4HmbsadSJQWaRK0UxqQ7GuNA9Ga4bEKeiO6b2DnB6cM6bpc8lemaPseh0H9B/wyg+J7rw==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", + "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -353,19 +344,19 @@ } }, "node_modules/@antfu/eslint-config/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.4.0.tgz", - "integrity": "sha512-A99j5AYoME/UBQ1ucEbbMEmGkN7SE0BvZFreSnTd1luq7yulcHdyGamZKizU7canpGDWGJ+Q6ZA9SyQobipePg==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", + "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.4.0", - "@typescript-eslint/visitor-keys": "7.4.0", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -380,39 +371,14 @@ } } }, - "node_modules/@antfu/eslint-config/node_modules/@typescript-eslint/utils": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.4.0.tgz", - "integrity": "sha512-NQt9QLM4Tt8qrlBVY9lkMYzfYtNz8/6qwZg8pI3cMGlPnj6mOpRxxAm7BMJN9K0AiY+1BwJ5lVC650YJqYOuNg==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "7.4.0", - "@typescript-eslint/types": "7.4.0", - "@typescript-eslint/typescript-estree": "7.4.0", - "semver": "^7.5.4" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - } - }, "node_modules/@antfu/eslint-config/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.4.0.tgz", - "integrity": "sha512-0zkC7YM0iX5Y41homUUeW1CHtZR01K3ybjM1l6QczoMuay0XKtrb93kv95AxUGwdjGr64nNqnOCwmEl616N8CA==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", + "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.4.0", - "eslint-visitor-keys": "^3.4.1" + "@typescript-eslint/types": "7.16.1", + "eslint-visitor-keys": "^3.4.3" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -432,9 +398,9 @@ } }, "node_modules/@antfu/eslint-config/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -447,149 +413,24 @@ } }, "node_modules/@antfu/install-pkg": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-0.3.1.tgz", - "integrity": "sha512-A3zWY9VeTPnxlMiZtsGHw2lSd3ghwvL8s9RiGOtqvDxhhFfZ781ynsGBa/iUnDJ5zBrmTFQrJDud3TGgRISaxw==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-0.3.3.tgz", + "integrity": "sha512-nHHsk3NXQ6xkCfiRRC8Nfrg8pU5kkr3P3Y9s9dKqiuRmBD0Yap7fymNDjGFKeWhZQHqqbCS5CfeMy9wtExM24w==", "dev": true, "dependencies": { - "execa": "^8.0.1" + "@jsdevtools/ez-spawn": "^3.0.4" }, "funding": { "url": "https://github.com/sponsors/antfu" } }, - "node_modules/@antfu/install-pkg/node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "node_modules/@antfu/utils": { + "version": "0.7.10", + "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-0.7.10.tgz", + "integrity": "sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==", "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": ">=16.17" - }, "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/@antfu/install-pkg/node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "dev": true, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@antfu/install-pkg/node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "dev": true, - "engines": { - "node": ">=16.17.0" - } - }, - "node_modules/@antfu/install-pkg/node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@antfu/install-pkg/node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@antfu/install-pkg/node_modules/npm-run-path": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", - "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", - "dev": true, - "dependencies": { - "path-key": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@antfu/install-pkg/node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@antfu/install-pkg/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@antfu/install-pkg/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@antfu/install-pkg/node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/antfu" } }, "node_modules/@babel/code-frame": { @@ -872,9 +713,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", "dev": true, "engines": { "node": ">=6.9.0" @@ -974,9 +815,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.1.tgz", - "integrity": "sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.8.tgz", + "integrity": "sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -1300,73 +1141,208 @@ } }, "node_modules/@commitlint/cli": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-17.7.2.tgz", - "integrity": "sha512-t3N7TZq7lOeqTOyEgfGcaltHqEJf7YDlPg75MldeVPPyz14jZq/+mbGF9tueDLFX8R6RwdymrN6D+U5XwZ8Iwg==", + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-19.3.0.tgz", + "integrity": "sha512-LgYWOwuDR7BSTQ9OLZ12m7F/qhNY+NpAyPBgo4YNMkACE7lGuUnuQq1yi9hz1KA4+3VqpOYl8H1rY/LYK43v7g==", "dev": true, "dependencies": { - "@commitlint/format": "^17.4.4", - "@commitlint/lint": "^17.7.0", - "@commitlint/load": "^17.7.2", - "@commitlint/read": "^17.5.1", - "@commitlint/types": "^17.4.4", - "execa": "^5.0.0", - "lodash.isfunction": "^3.0.9", - "resolve-from": "5.0.0", - "resolve-global": "1.0.0", + "@commitlint/format": "^19.3.0", + "@commitlint/lint": "^19.2.2", + "@commitlint/load": "^19.2.0", + "@commitlint/read": "^19.2.1", + "@commitlint/types": "^19.0.3", + "execa": "^8.0.1", "yargs": "^17.0.0" }, "bin": { "commitlint": "cli.js" }, "engines": { - "node": ">=v14" + "node": ">=v18" } }, - "node_modules/@commitlint/cli/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "node_modules/@commitlint/cli/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/@commitlint/cli/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "dev": true, "engines": { - "node": ">=8" + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/cli/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/@commitlint/cli/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/cli/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/cli/node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/cli/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/cli/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/cli/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@commitlint/cli/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@commitlint/config-conventional": { - "version": "17.7.0", - "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-17.7.0.tgz", - "integrity": "sha512-iicqh2o6et+9kWaqsQiEYZzfLbtoWv9uZl8kbI8EGfnc0HeGafQBF7AJ0ylN9D/2kj6txltsdyQs8+2fTMwWEw==", + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-19.2.2.tgz", + "integrity": "sha512-mLXjsxUVLYEGgzbxbxicGPggDuyWNkf25Ht23owXIH+zV2pv1eJuzLK3t1gDY5Gp6pxdE60jZnWUY5cvgL3ufw==", "dev": true, "dependencies": { - "conventional-changelog-conventionalcommits": "^6.1.0" + "@commitlint/types": "^19.0.3", + "conventional-changelog-conventionalcommits": "^7.0.2" }, "engines": { - "node": ">=v14" + "node": ">=v18" + } + }, + "node_modules/@commitlint/config-conventional/node_modules/conventional-changelog-conventionalcommits": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-7.0.2.tgz", + "integrity": "sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==", + "dev": true, + "dependencies": { + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=16" } }, "node_modules/@commitlint/config-validator": { - "version": "17.6.7", - "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-17.6.7.tgz", - "integrity": "sha512-vJSncmnzwMvpr3lIcm0I8YVVDJTzyjy7NZAeXbTXy+MPUdAr9pKyyg7Tx/ebOQ9kqzE6O9WT6jg2164br5UdsQ==", + "version": "19.0.3", + "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-19.0.3.tgz", + "integrity": "sha512-2D3r4PKjoo59zBc2auodrSCaUnCSALCx54yveOFwwP/i2kfEAQrygwOleFWswLqK0UL/F9r07MFi5ev2ohyM4Q==", "dev": true, "dependencies": { - "@commitlint/types": "^17.4.4", + "@commitlint/types": "^19.0.3", "ajv": "^8.11.0" }, "engines": { - "node": ">=v14" + "node": ">=v18" } }, "node_modules/@commitlint/config-validator/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -1380,12 +1356,12 @@ "dev": true }, "node_modules/@commitlint/ensure": { - "version": "17.6.7", - "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-17.6.7.tgz", - "integrity": "sha512-mfDJOd1/O/eIb/h4qwXzUxkmskXDL9vNPnZ4AKYKiZALz4vHzwMxBSYtyL2mUIDeU9DRSpEUins8SeKtFkYHSw==", + "version": "19.0.3", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-19.0.3.tgz", + "integrity": "sha512-SZEpa/VvBLoT+EFZVb91YWbmaZ/9rPH3ESrINOl0HD2kMYsjvl0tF7nMHh0EpTcv4+gTtZBAe1y/SS6/OhfZzQ==", "dev": true, "dependencies": { - "@commitlint/types": "^17.4.4", + "@commitlint/types": "^19.0.3", "lodash.camelcase": "^4.3.0", "lodash.kebabcase": "^4.1.1", "lodash.snakecase": "^4.1.1", @@ -1393,106 +1369,120 @@ "lodash.upperfirst": "^4.3.1" }, "engines": { - "node": ">=v14" + "node": ">=v18" } }, "node_modules/@commitlint/execute-rule": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-17.4.0.tgz", - "integrity": "sha512-LIgYXuCSO5Gvtc0t9bebAMSwd68ewzmqLypqI2Kke1rqOqqDbMpYcYfoPfFlv9eyLIh4jocHWwCK5FS7z9icUA==", + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-19.0.0.tgz", + "integrity": "sha512-mtsdpY1qyWgAO/iOK0L6gSGeR7GFcdW7tIjcNFxcWkfLDF5qVbPHKuGATFqRMsxcO8OUKNj0+3WOHB7EHm4Jdw==", "dev": true, "engines": { - "node": ">=v14" + "node": ">=v18" } }, "node_modules/@commitlint/format": { - "version": "17.4.4", - "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-17.4.4.tgz", - "integrity": "sha512-+IS7vpC4Gd/x+uyQPTAt3hXs5NxnkqAZ3aqrHd5Bx/R9skyCAWusNlNbw3InDbAK6j166D9asQM8fnmYIa+CXQ==", + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-19.3.0.tgz", + "integrity": "sha512-luguk5/aF68HiF4H23ACAfk8qS8AHxl4LLN5oxPc24H+2+JRPsNr1OS3Gaea0CrH7PKhArBMKBz5RX9sA5NtTg==", "dev": true, "dependencies": { - "@commitlint/types": "^17.4.4", - "chalk": "^4.1.0" + "@commitlint/types": "^19.0.3", + "chalk": "^5.3.0" }, "engines": { - "node": ">=v14" + "node": ">=v18" + } + }, + "node_modules/@commitlint/format/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/@commitlint/is-ignored": { - "version": "17.7.0", - "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-17.7.0.tgz", - "integrity": "sha512-043rA7m45tyEfW7Zv2vZHF++176MLHH9h70fnPoYlB1slKBeKl8BwNIlnPg4xBdRBVNPaCqvXxWswx2GR4c9Hw==", + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-19.2.2.tgz", + "integrity": "sha512-eNX54oXMVxncORywF4ZPFtJoBm3Tvp111tg1xf4zWXGfhBPKpfKG6R+G3G4v5CPlRROXpAOpQ3HMhA9n1Tck1g==", "dev": true, "dependencies": { - "@commitlint/types": "^17.4.4", - "semver": "7.5.4" + "@commitlint/types": "^19.0.3", + "semver": "^7.6.0" }, "engines": { - "node": ">=v14" + "node": ">=v18" } }, "node_modules/@commitlint/lint": { - "version": "17.7.0", - "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-17.7.0.tgz", - "integrity": "sha512-TCQihm7/uszA5z1Ux1vw+Nf3yHTgicus/+9HiUQk+kRSQawByxZNESeQoX9ujfVd3r4Sa+3fn0JQAguG4xvvbA==", + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-19.2.2.tgz", + "integrity": "sha512-xrzMmz4JqwGyKQKTpFzlN0dx0TAiT7Ran1fqEBgEmEj+PU98crOFtysJgY+QdeSagx6EDRigQIXJVnfrI0ratA==", "dev": true, "dependencies": { - "@commitlint/is-ignored": "^17.7.0", - "@commitlint/parse": "^17.7.0", - "@commitlint/rules": "^17.7.0", - "@commitlint/types": "^17.4.4" + "@commitlint/is-ignored": "^19.2.2", + "@commitlint/parse": "^19.0.3", + "@commitlint/rules": "^19.0.3", + "@commitlint/types": "^19.0.3" }, "engines": { - "node": ">=v14" + "node": ">=v18" } }, "node_modules/@commitlint/load": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-17.7.2.tgz", - "integrity": "sha512-XA7WTnsjHZ4YH6ZYsrnxgLdXzriwMMq+utZUET6spbOEEIPBCDLdOQXS26P+v3TTO4hUHOEhzUquaBv3jbBixw==", + "version": "19.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-19.2.0.tgz", + "integrity": "sha512-XvxxLJTKqZojCxaBQ7u92qQLFMMZc4+p9qrIq/9kJDy8DOrEa7P1yx7Tjdc2u2JxIalqT4KOGraVgCE7eCYJyQ==", "dev": true, "dependencies": { - "@commitlint/config-validator": "^17.6.7", - "@commitlint/execute-rule": "^17.4.0", - "@commitlint/resolve-extends": "^17.6.7", - "@commitlint/types": "^17.4.4", - "@types/node": "20.5.1", - "chalk": "^4.1.0", - "cosmiconfig": "^8.0.0", - "cosmiconfig-typescript-loader": "^4.0.0", + "@commitlint/config-validator": "^19.0.3", + "@commitlint/execute-rule": "^19.0.0", + "@commitlint/resolve-extends": "^19.1.0", + "@commitlint/types": "^19.0.3", + "chalk": "^5.3.0", + "cosmiconfig": "^9.0.0", + "cosmiconfig-typescript-loader": "^5.0.0", "lodash.isplainobject": "^4.0.6", "lodash.merge": "^4.6.2", - "lodash.uniq": "^4.5.0", - "resolve-from": "^5.0.0", - "ts-node": "^10.8.1", - "typescript": "^4.6.4 || ^5.0.0" + "lodash.uniq": "^4.5.0" }, "engines": { - "node": ">=v14" + "node": ">=v18" } }, - "node_modules/@commitlint/load/node_modules/@types/node": { - "version": "20.5.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.1.tgz", - "integrity": "sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==", - "dev": true - }, "node_modules/@commitlint/load/node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "node_modules/@commitlint/load/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/@commitlint/load/node_modules/cosmiconfig": { - "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", "dev": true, "dependencies": { + "env-paths": "^2.2.1", "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", - "parse-json": "^5.2.0", - "path-type": "^4.0.0" + "parse-json": "^5.2.0" }, "engines": { "node": ">=14" @@ -1509,6 +1499,23 @@ } } }, + "node_modules/@commitlint/load/node_modules/cosmiconfig-typescript-loader": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-5.0.0.tgz", + "integrity": "sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==", + "dev": true, + "dependencies": { + "jiti": "^1.19.1" + }, + "engines": { + "node": ">=v16" + }, + "peerDependencies": { + "@types/node": "*", + "cosmiconfig": ">=8.2", + "typescript": ">=4" + } + }, "node_modules/@commitlint/load/node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -1521,99 +1528,319 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/@commitlint/load/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/@commitlint/message": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-17.4.2.tgz", - "integrity": "sha512-3XMNbzB+3bhKA1hSAWPCQA3lNxR4zaeQAQcHj0Hx5sVdO6ryXtgUBGGv+1ZCLMgAPRixuc6en+iNAzZ4NzAa8Q==", + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-19.0.0.tgz", + "integrity": "sha512-c9czf6lU+9oF9gVVa2lmKaOARJvt4soRsVmbR7Njwp9FpbBgste5i7l/2l5o8MmbwGh4yE1snfnsy2qyA2r/Fw==", "dev": true, "engines": { - "node": ">=v14" + "node": ">=v18" } }, "node_modules/@commitlint/parse": { - "version": "17.7.0", - "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-17.7.0.tgz", - "integrity": "sha512-dIvFNUMCUHqq5Abv80mIEjLVfw8QNuA4DS7OWip4pcK/3h5wggmjVnlwGCDvDChkw2TjK1K6O+tAEV78oxjxag==", + "version": "19.0.3", + "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-19.0.3.tgz", + "integrity": "sha512-Il+tNyOb8VDxN3P6XoBBwWJtKKGzHlitEuXA5BP6ir/3loWlsSqDr5aecl6hZcC/spjq4pHqNh0qPlfeWu38QA==", "dev": true, "dependencies": { - "@commitlint/types": "^17.4.4", - "conventional-changelog-angular": "^6.0.0", - "conventional-commits-parser": "^4.0.0" + "@commitlint/types": "^19.0.3", + "conventional-changelog-angular": "^7.0.0", + "conventional-commits-parser": "^5.0.0" }, "engines": { - "node": ">=v14" + "node": ">=v18" } }, "node_modules/@commitlint/parse/node_modules/conventional-changelog-angular": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz", - "integrity": "sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz", + "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==", "dev": true, "dependencies": { "compare-func": "^2.0.0" }, "engines": { - "node": ">=14" + "node": ">=16" } }, "node_modules/@commitlint/parse/node_modules/conventional-commits-parser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz", - "integrity": "sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz", + "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==", "dev": true, "dependencies": { - "is-text-path": "^1.0.1", + "is-text-path": "^2.0.0", "JSONStream": "^1.3.5", - "meow": "^8.1.2", - "split2": "^3.2.2" + "meow": "^12.0.1", + "split2": "^4.0.0" }, "bin": { - "conventional-commits-parser": "cli.js" + "conventional-commits-parser": "cli.mjs" }, "engines": { - "node": ">=14" + "node": ">=16" + } + }, + "node_modules/@commitlint/parse/node_modules/is-text-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz", + "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==", + "dev": true, + "dependencies": { + "text-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@commitlint/parse/node_modules/meow": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", + "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", + "dev": true, + "engines": { + "node": ">=16.10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/parse/node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true, + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/@commitlint/parse/node_modules/text-extensions": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz", + "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@commitlint/read": { - "version": "17.5.1", - "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-17.5.1.tgz", - "integrity": "sha512-7IhfvEvB//p9aYW09YVclHbdf1u7g7QhxeYW9ZHSO8Huzp8Rz7m05aCO1mFG7G8M+7yfFnXB5xOmG18brqQIBg==", + "version": "19.2.1", + "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-19.2.1.tgz", + "integrity": "sha512-qETc4+PL0EUv7Q36lJbPG+NJiBOGg7SSC7B5BsPWOmei+Dyif80ErfWQ0qXoW9oCh7GTpTNRoaVhiI8RbhuaNw==", "dev": true, "dependencies": { - "@commitlint/top-level": "^17.4.0", - "@commitlint/types": "^17.4.4", - "fs-extra": "^11.0.0", - "git-raw-commits": "^2.0.11", - "minimist": "^1.2.6" + "@commitlint/top-level": "^19.0.0", + "@commitlint/types": "^19.0.3", + "execa": "^8.0.1", + "git-raw-commits": "^4.0.0", + "minimist": "^1.2.8" }, "engines": { - "node": ">=v14" + "node": ">=v18" + } + }, + "node_modules/@commitlint/read/node_modules/dargs": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-8.1.0.tgz", + "integrity": "sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/read/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/@commitlint/read/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/read/node_modules/git-raw-commits": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-4.0.0.tgz", + "integrity": "sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==", + "dev": true, + "dependencies": { + "dargs": "^8.0.0", + "meow": "^12.0.1", + "split2": "^4.0.0" + }, + "bin": { + "git-raw-commits": "cli.mjs" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@commitlint/read/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/@commitlint/read/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/read/node_modules/meow": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", + "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", + "dev": true, + "engines": { + "node": ">=16.10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/read/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/read/node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/read/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/read/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/read/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@commitlint/read/node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true, + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/@commitlint/read/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@commitlint/resolve-extends": { - "version": "17.6.7", - "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-17.6.7.tgz", - "integrity": "sha512-PfeoAwLHtbOaC9bGn/FADN156CqkFz6ZKiVDMjuC2N5N0740Ke56rKU7Wxdwya8R8xzLK9vZzHgNbuGhaOVKIg==", + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-19.1.0.tgz", + "integrity": "sha512-z2riI+8G3CET5CPgXJPlzftH+RiWYLMYv4C9tSLdLXdr6pBNimSKukYP9MS27ejmscqCTVA4almdLh0ODD2KYg==", "dev": true, "dependencies": { - "@commitlint/config-validator": "^17.6.7", - "@commitlint/types": "^17.4.4", - "import-fresh": "^3.0.0", + "@commitlint/config-validator": "^19.0.3", + "@commitlint/types": "^19.0.3", + "global-directory": "^4.0.1", + "import-meta-resolve": "^4.0.0", "lodash.mergewith": "^4.6.2", - "resolve-from": "^5.0.0", - "resolve-global": "^1.0.0" + "resolve-from": "^5.0.0" }, "engines": { - "node": ">=v14" + "node": ">=v18" } }, "node_modules/@commitlint/resolve-extends/node_modules/resolve-from": { @@ -1626,113 +1853,282 @@ } }, "node_modules/@commitlint/rules": { - "version": "17.7.0", - "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-17.7.0.tgz", - "integrity": "sha512-J3qTh0+ilUE5folSaoK91ByOb8XeQjiGcdIdiB/8UT1/Rd1itKo0ju/eQVGyFzgTMYt8HrDJnGTmNWwcMR1rmA==", + "version": "19.0.3", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-19.0.3.tgz", + "integrity": "sha512-TspKb9VB6svklxNCKKwxhELn7qhtY1rFF8ls58DcFd0F97XoG07xugPjjbVnLqmMkRjZDbDIwBKt9bddOfLaPw==", "dev": true, "dependencies": { - "@commitlint/ensure": "^17.6.7", - "@commitlint/message": "^17.4.2", - "@commitlint/to-lines": "^17.4.0", - "@commitlint/types": "^17.4.4", - "execa": "^5.0.0" + "@commitlint/ensure": "^19.0.3", + "@commitlint/message": "^19.0.0", + "@commitlint/to-lines": "^19.0.0", + "@commitlint/types": "^19.0.3", + "execa": "^8.0.1" }, "engines": { - "node": ">=v14" + "node": ">=v18" + } + }, + "node_modules/@commitlint/rules/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/@commitlint/rules/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/rules/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/@commitlint/rules/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/rules/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/rules/node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/rules/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/rules/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/rules/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@commitlint/rules/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@commitlint/to-lines": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-17.4.0.tgz", - "integrity": "sha512-LcIy/6ZZolsfwDUWfN1mJ+co09soSuNASfKEU5sCmgFCvX5iHwRYLiIuoqXzOVDYOy7E7IcHilr/KS0e5T+0Hg==", + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-19.0.0.tgz", + "integrity": "sha512-vkxWo+VQU5wFhiP9Ub9Sre0FYe019JxFikrALVoD5UGa8/t3yOJEpEhxC5xKiENKKhUkTpEItMTRAjHw2SCpZw==", "dev": true, "engines": { - "node": ">=v14" + "node": ">=v18" } }, "node_modules/@commitlint/top-level": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-17.4.0.tgz", - "integrity": "sha512-/1loE/g+dTTQgHnjoCy0AexKAEFyHsR2zRB4NWrZ6lZSMIxAhBJnmCqwao7b4H8888PsfoTBCLBYIw8vGnej8g==", + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-19.0.0.tgz", + "integrity": "sha512-KKjShd6u1aMGNkCkaX4aG1jOGdn7f8ZI8TR1VEuNqUOjWTOdcDSsmglinglJ18JTjuBX5I1PtjrhQCRcixRVFQ==", "dev": true, "dependencies": { - "find-up": "^5.0.0" + "find-up": "^7.0.0" }, "engines": { - "node": ">=v14" + "node": ">=v18" } }, "node_modules/@commitlint/top-level/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz", + "integrity": "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==", "dev": true, "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" + "locate-path": "^7.2.0", + "path-exists": "^5.0.0", + "unicorn-magic": "^0.1.0" }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@commitlint/top-level/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", "dev": true, "dependencies": { - "p-locate": "^5.0.0" + "p-locate": "^6.0.0" }, "engines": { - "node": ">=10" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@commitlint/top-level/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", "dev": true, "dependencies": { - "yocto-queue": "^0.1.0" + "yocto-queue": "^1.0.0" }, "engines": { - "node": ">=10" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@commitlint/top-level/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", "dev": true, "dependencies": { - "p-limit": "^3.0.2" + "p-limit": "^4.0.0" }, "engines": { - "node": ">=10" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/top-level/node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/@commitlint/top-level/node_modules/yocto-queue": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", + "dev": true, + "engines": { + "node": ">=12.20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@commitlint/types": { - "version": "17.4.4", - "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-17.4.4.tgz", - "integrity": "sha512-amRN8tRLYOsxRr6mTnGGGvB5EmW/4DDjLMgiwK3CCVEmN6Sr/6xePGEpWaspKkckILuUORCwe6VfDBw6uj4axQ==", + "version": "19.0.3", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-19.0.3.tgz", + "integrity": "sha512-tpyc+7i6bPG9mvaBbtKUeghfyZSDgWquIDfMgqYtTbmZ9Y9VzEm2je9EYcQ0aoz5o7NvGS+rcDec93yO08MHYA==", "dev": true, "dependencies": { - "chalk": "^4.1.0" + "@types/conventional-commits-parser": "^5.0.0", + "chalk": "^5.3.0" }, "engines": { - "node": ">=v14" + "node": ">=v18" + } + }, + "node_modules/@commitlint/types/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/@comunica/actor-abstract-mediatyped": { @@ -4314,11 +4710,14 @@ } }, "node_modules/@es-joy/jsdoccomment": { - "version": "0.42.0", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.42.0.tgz", - "integrity": "sha512-R1w57YlVA6+YE01wch3GPYn6bCsrOV3YW/5oGGE2tmX6JcL9Nr+b5IikrjMPF+v9CV3ay+obImEdsDhovhJrzw==", + "version": "0.43.1", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.43.1.tgz", + "integrity": "sha512-I238eDtOolvCuvtxrnqtlBaw0BwdQuYqK7eA6XIonicMdOOOb75mqdIzkGDUbS04+1Di007rgm9snFRNeVrOog==", "dev": true, "dependencies": { + "@types/eslint": "^8.56.5", + "@types/estree": "^1.0.5", + "@typescript-eslint/types": "^7.2.0", "comment-parser": "1.4.1", "esquery": "^1.5.0", "jsdoc-type-pratt-parser": "~4.0.0" @@ -4327,6 +4726,19 @@ "node": ">=16" } }, + "node_modules/@es-joy/jsdoccomment/node_modules/@typescript-eslint/types": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", + "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@es-joy/jsdoccomment/node_modules/comment-parser": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", @@ -4352,9 +4764,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.9.1.tgz", - "integrity": "sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==", + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" @@ -4365,6 +4777,7 @@ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, + "peer": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -4387,13 +4800,15 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "dev": true, + "peer": true }, "node_modules/@eslint/eslintrc/node_modules/globals": { "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, + "peer": true, "dependencies": { "type-fest": "^0.20.2" }, @@ -4409,6 +4824,7 @@ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, + "peer": true, "dependencies": { "argparse": "^2.0.1" }, @@ -4421,6 +4837,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, + "peer": true, "engines": { "node": ">=10" }, @@ -4930,6 +5347,21 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, + "node_modules/@jsdevtools/ez-spawn": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@jsdevtools/ez-spawn/-/ez-spawn-3.0.4.tgz", + "integrity": "sha512-f5DRIOZf7wxogefH03RjMPMdBF7ADTWUMoOs9kaJo06EfwF+aFhMZMDZxHg/Xe12hptN9xoZjGso2fdjapBRIA==", + "dev": true, + "dependencies": { + "call-me-maybe": "^1.0.1", + "cross-spawn": "^7.0.3", + "string-argv": "^0.3.1", + "type-detect": "^4.0.8" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@koa/cors": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@koa/cors/-/cors-5.0.0.tgz", @@ -5006,6 +5438,18 @@ "node": ">= 8" } }, + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, "node_modules/@rdfjs/data-model": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/@rdfjs/data-model/-/data-model-1.3.4.tgz", @@ -5071,6 +5515,15 @@ "node": ">=v12.22.12" } }, + "node_modules/@shikijs/core": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.10.3.tgz", + "integrity": "sha512-D45PMaBaeDHxww+EkcDQtDAtzv00Gcsp72ukBtaLSmqRvh0WgGMq3Al0rl1QQBZfuneO75NXMIzEZGFitThWbg==", + "dev": true, + "dependencies": { + "@types/hast": "^3.0.4" + } + }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -5144,70 +5597,89 @@ } }, "node_modules/@stylistic/eslint-plugin": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-1.7.0.tgz", - "integrity": "sha512-ThMUjGIi/jeWYNvOdjZkoLw1EOVs0tEuKXDgWvTn8uWaEz55HuPlajKxjKLpv19C+qRDbKczJfzUODfCdME53A==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-2.3.0.tgz", + "integrity": "sha512-rtiz6u5gRyyEZp36FcF1/gHJbsbT3qAgXZ1qkad6Nr/xJ9wrSJkiSFFQhpYVTIZ7FJNRJurEcumZDCwN9dEI4g==", "dev": true, "dependencies": { - "@stylistic/eslint-plugin-js": "1.7.0", - "@stylistic/eslint-plugin-jsx": "1.7.0", - "@stylistic/eslint-plugin-plus": "1.7.0", - "@stylistic/eslint-plugin-ts": "1.7.0", - "@types/eslint": "^8.56.2" + "@stylistic/eslint-plugin-js": "2.3.0", + "@stylistic/eslint-plugin-jsx": "2.3.0", + "@stylistic/eslint-plugin-plus": "2.3.0", + "@stylistic/eslint-plugin-ts": "2.3.0", + "@types/eslint": "^8.56.10" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "peerDependencies": { "eslint": ">=8.40.0" } }, "node_modules/@stylistic/eslint-plugin-js": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-1.7.0.tgz", - "integrity": "sha512-PN6On/+or63FGnhhMKSQfYcWutRlzOiYlVdLM6yN7lquoBTqUJHYnl4TA4MHwiAt46X5gRxDr1+xPZ1lOLcL+Q==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-2.3.0.tgz", + "integrity": "sha512-lQwoiYb0Fs6Yc5QS3uT8+T9CPKK2Eoxc3H8EnYJgM26v/DgtW+1lvy2WNgyBflU+ThShZaHm3a6CdD9QeKx23w==", "dev": true, "dependencies": { - "@types/eslint": "^8.56.2", + "@types/eslint": "^8.56.10", "acorn": "^8.11.3", - "escape-string-regexp": "^4.0.0", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1" + "eslint-visitor-keys": "^4.0.0", + "espree": "^10.0.1" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "peerDependencies": { "eslint": ">=8.40.0" } }, + "node_modules/@stylistic/eslint-plugin-js/node_modules/eslint-visitor-keys": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@stylistic/eslint-plugin-js/node_modules/espree": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", + "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", + "dev": true, + "dependencies": { + "acorn": "^8.12.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@stylistic/eslint-plugin-jsx": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-jsx/-/eslint-plugin-jsx-1.7.0.tgz", - "integrity": "sha512-BACdBwXakQvjYIST5N2WWhRbvhRsIxa/F59BiZol+0IH4FSmDXhie7v/yaxDIIA9CbfElzOmIA5nWNYTVXcnwQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-jsx/-/eslint-plugin-jsx-2.3.0.tgz", + "integrity": "sha512-tsQ0IEKB195H6X9A4iUSgLLLKBc8gUBWkBIU8tp1/3g2l8stu+PtMQVV/VmK1+3bem5FJCyvfcZIQ/WF1fsizA==", "dev": true, "dependencies": { - "@stylistic/eslint-plugin-js": "^1.7.0", - "@types/eslint": "^8.56.2", + "@stylistic/eslint-plugin-js": "^2.3.0", + "@types/eslint": "^8.56.10", "estraverse": "^5.3.0", - "picomatch": "^4.0.1" + "picomatch": "^4.0.2" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "peerDependencies": { "eslint": ">=8.40.0" } }, - "node_modules/@stylistic/eslint-plugin-jsx/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, "node_modules/@stylistic/eslint-plugin-jsx/node_modules/picomatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", @@ -5221,283 +5693,35 @@ } }, "node_modules/@stylistic/eslint-plugin-plus": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-plus/-/eslint-plugin-plus-1.7.0.tgz", - "integrity": "sha512-AabDw8sXsc70Ydx3qnbeTlRHZnIwY6UKEenBPURPhY3bfYWX+/pDpZH40HkOu94v8D0DUrocPkeeEUxl4e0JDg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-plus/-/eslint-plugin-plus-2.3.0.tgz", + "integrity": "sha512-xboPWGUU5yaPlR+WR57GwXEuY4PSlPqA0C3IdNA/+1o2MuBi95XgDJcZiJ9N+aXsqBXAPIpFFb+WQ7QEHo4f7g==", "dev": true, "dependencies": { - "@types/eslint": "^8.56.2", - "@typescript-eslint/utils": "^6.21.0" + "@types/eslint": "^8.56.10", + "@typescript-eslint/utils": "^7.12.0" }, "peerDependencies": { "eslint": "*" } }, - "node_modules/@stylistic/eslint-plugin-plus/node_modules/@typescript-eslint/scope-manager": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", - "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@stylistic/eslint-plugin-plus/node_modules/@typescript-eslint/types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", - "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@stylistic/eslint-plugin-plus/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", - "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@stylistic/eslint-plugin-plus/node_modules/@typescript-eslint/utils": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", - "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "semver": "^7.5.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - } - }, - "node_modules/@stylistic/eslint-plugin-plus/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", - "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@stylistic/eslint-plugin-plus/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@stylistic/eslint-plugin-plus/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@stylistic/eslint-plugin-ts": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-ts/-/eslint-plugin-ts-1.7.0.tgz", - "integrity": "sha512-QsHv98mmW1xaucVYQTyLDgEpybPJ/6jPPxVBrIchntWWwj74xCWKUiw79hu+TpYj/Pbhd9rkqJYLNq3pQGYuyA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-ts/-/eslint-plugin-ts-2.3.0.tgz", + "integrity": "sha512-wqOR38/uz/0XPnHX68ftp8sNMSAqnYGjovOTN7w00xnjS6Lxr3Sk7q6AaxWWqbMvOj7V2fQiMC5HWAbTruJsCg==", "dev": true, "dependencies": { - "@stylistic/eslint-plugin-js": "1.7.0", - "@types/eslint": "^8.56.2", - "@typescript-eslint/utils": "^6.21.0" + "@stylistic/eslint-plugin-js": "2.3.0", + "@types/eslint": "^8.56.10", + "@typescript-eslint/utils": "^7.12.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "peerDependencies": { "eslint": ">=8.40.0" } }, - "node_modules/@stylistic/eslint-plugin-ts/node_modules/@typescript-eslint/scope-manager": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", - "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@stylistic/eslint-plugin-ts/node_modules/@typescript-eslint/types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", - "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@stylistic/eslint-plugin-ts/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", - "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@stylistic/eslint-plugin-ts/node_modules/@typescript-eslint/utils": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", - "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "semver": "^7.5.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - } - }, - "node_modules/@stylistic/eslint-plugin-ts/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", - "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@stylistic/eslint-plugin-ts/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@stylistic/eslint-plugin-ts/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@szmarczak/http-timer": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", @@ -5628,6 +5852,15 @@ "resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.3.tgz", "integrity": "sha512-P1bffQfhD3O4LW0ioENXUhZ9OIa0Zn+P7M+pWgkCKaT53wVLSq0mrKksCID/FGHpFhRSxRGhgrQmfhRuzwtKdg==" }, + "node_modules/@types/conventional-commits-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz", + "integrity": "sha512-loB369iXNmAZglwWATL+WRe+CRMmmBPtpolYzIebFaX4YA3x+BEfLqhUAV9WanycKI3TG1IMr5bMJDajDKLlUQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/cookie": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.5.2.tgz", @@ -5672,9 +5905,9 @@ } }, "node_modules/@types/eslint": { - "version": "8.56.6", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.6.tgz", - "integrity": "sha512-ymwc+qb1XkjT/gfoQwxIeHZ6ixH23A+tCT2ADSA/DPVKzAjwYkTXBMCQ/f6fe4wEa85Lhp26VPeUxI7wMhAi7A==", + "version": "8.56.10", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", + "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", "dev": true, "dependencies": { "@types/estree": "*", @@ -5726,6 +5959,15 @@ "@types/node": "*" } }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dev": true, + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/@types/http-assert": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.1.tgz", @@ -6331,16 +6573,46 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", + "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/scope-manager/node_modules/@typescript-eslint/types": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", + "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/scope-manager/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", + "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.16.1", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -6526,29 +6798,107 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", - "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.1.tgz", + "integrity": "sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==", "dev": true, "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/typescript-estree": "7.16.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "eslint": "^8.56.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", + "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", + "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", + "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.16.1", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@typescript-eslint/visitor-keys": { @@ -6576,63 +6926,63 @@ "peer": true }, "node_modules/@vue/compiler-core": { - "version": "3.4.21", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.21.tgz", - "integrity": "sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==", + "version": "3.4.32", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.32.tgz", + "integrity": "sha512-8tCVWkkLe/QCWIsrIvExUGnhYCAOroUs5dzhSoKL5w4MJS8uIYiou+pOPSVIOALOQ80B0jBs+Ri+kd5+MBnCDw==", "dev": true, "peer": true, "dependencies": { - "@babel/parser": "^7.23.9", - "@vue/shared": "3.4.21", + "@babel/parser": "^7.24.7", + "@vue/shared": "3.4.32", "entities": "^4.5.0", "estree-walker": "^2.0.2", - "source-map-js": "^1.0.2" + "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-dom": { - "version": "3.4.21", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.21.tgz", - "integrity": "sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==", + "version": "3.4.32", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.32.tgz", + "integrity": "sha512-PbSgt9KuYo4fyb90dynuPc0XFTfFPs3sCTbPLOLlo+PrUESW1gn/NjSsUvhR+mI2AmmEzexwYMxbHDldxSOr2A==", "dev": true, "peer": true, "dependencies": { - "@vue/compiler-core": "3.4.21", - "@vue/shared": "3.4.21" + "@vue/compiler-core": "3.4.32", + "@vue/shared": "3.4.32" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.4.21", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.21.tgz", - "integrity": "sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==", + "version": "3.4.32", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.32.tgz", + "integrity": "sha512-STy9im/WHfaguJnfKjjVpMHukxHUrOKjm2vVCxiojQJyo3Sb6Os8SMXBr/MI+ekpstEGkDONfqAQoSbZhspLYw==", "dev": true, "peer": true, "dependencies": { - "@babel/parser": "^7.23.9", - "@vue/compiler-core": "3.4.21", - "@vue/compiler-dom": "3.4.21", - "@vue/compiler-ssr": "3.4.21", - "@vue/shared": "3.4.21", + "@babel/parser": "^7.24.7", + "@vue/compiler-core": "3.4.32", + "@vue/compiler-dom": "3.4.32", + "@vue/compiler-ssr": "3.4.32", + "@vue/shared": "3.4.32", "estree-walker": "^2.0.2", - "magic-string": "^0.30.7", - "postcss": "^8.4.35", - "source-map-js": "^1.0.2" + "magic-string": "^0.30.10", + "postcss": "^8.4.39", + "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-ssr": { - "version": "3.4.21", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.21.tgz", - "integrity": "sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==", + "version": "3.4.32", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.32.tgz", + "integrity": "sha512-nyu/txTecF6DrxLrpLcI34xutrvZPtHPBj9yRoPxstIquxeeyywXpYZrQMsIeDfBhlw1abJb9CbbyZvDw2kjdg==", "dev": true, "peer": true, "dependencies": { - "@vue/compiler-dom": "3.4.21", - "@vue/shared": "3.4.21" + "@vue/compiler-dom": "3.4.32", + "@vue/shared": "3.4.32" } }, "node_modules/@vue/shared": { - "version": "3.4.21", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.21.tgz", - "integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==", + "version": "3.4.32", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.32.tgz", + "integrity": "sha512-ep4mF1IVnX/pYaNwxwOpJHyBtOMKWoKZMbnUyd+z0udqIxLUh7YCCd/JfDna8aUrmnG9SFORyIq2HzEATRrQsg==", "dev": true, "peer": true }, @@ -6666,9 +7016,9 @@ } }, "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -6752,12 +7102,6 @@ "node": ">=8" } }, - "node_modules/ansi-sequence-parser": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.0.tgz", - "integrity": "sha512-lEm8mt52to2fT8GhciPCGeCXACSz2UwIN4X2e2LJSnZ5uAbn2/dsYdOmUXq0AtWS5cpAupysIneExOgH0Vd2TQ==", - "dev": true - }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -7147,15 +7491,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/builtins": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", - "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", - "dev": true, - "dependencies": { - "semver": "^7.0.0" - } - }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -7215,6 +7550,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/call-me-maybe": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", + "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", + "dev": true + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -8328,9 +8669,9 @@ } }, "node_modules/core-js-compat": { - "version": "3.36.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.1.tgz", - "integrity": "sha512-Dk997v9ZCt3X/npqzyGdTlq6t7lDBhZwGvV94PKzDArjp7BTRm7WlDAXYd/OWdeFHO8OChQYRJNJvUCqCbrtKA==", + "version": "3.37.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", + "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", "dev": true, "dependencies": { "browserslist": "^4.23.0" @@ -8374,21 +8715,6 @@ "node": ">=10" } }, - "node_modules/cosmiconfig-typescript-loader": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.4.0.tgz", - "integrity": "sha512-BabizFdC3wBHhbI4kJh0VkQP9GkBfoHPydD0COMce1nJ1kJAB3F2TmJ/I7diULBKtmEWSwEbuN/KDtgnmUUVmw==", - "dev": true, - "engines": { - "node": ">=v14.21.3" - }, - "peerDependencies": { - "@types/node": "*", - "cosmiconfig": ">=7", - "ts-node": ">=10", - "typescript": ">=4" - } - }, "node_modules/create-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", @@ -8469,9 +8795,9 @@ } }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "dependencies": { "ms": "2.1.2" }, @@ -8896,6 +9222,19 @@ "once": "^1.4.0" } }, + "node_modules/enhanced-resolve": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", + "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -8907,6 +9246,15 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -8922,6 +9270,12 @@ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, + "node_modules/es-module-lexer": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "dev": true + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -9003,9 +9357,9 @@ } }, "node_modules/eslint-compat-utils": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.0.tgz", - "integrity": "sha512-dc6Y8tzEcSYZMHa+CMPLi/hyo1FzNeonbhJL7Ol0ccuKQkwopJcJBA9YL/xmMTLU1eKigXo9vj9nALElWYSowg==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", + "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", "dev": true, "dependencies": { "semver": "^7.5.4" @@ -9018,108 +9372,26 @@ } }, "node_modules/eslint-config-flat-gitignore": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/eslint-config-flat-gitignore/-/eslint-config-flat-gitignore-0.1.3.tgz", - "integrity": "sha512-oQD+dEZv3RThN60tFqGFt+NJcO1DmssUcP+T/nlX+ZzEoEvVUYH0GU9X/VlmDXsbMsS9mONI1HrlxLgtKojw7w==", + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eslint-config-flat-gitignore/-/eslint-config-flat-gitignore-0.1.8.tgz", + "integrity": "sha512-OEUbS2wzzYtUfshjOqzFo4Bl4lHykXUdM08TCnYNl7ki+niW4Q1R0j0FDFDr0vjVsI5ZFOz5LvluxOP+Ew+dYw==", "dev": true, "dependencies": { - "find-up": "^7.0.0", + "find-up-simple": "^1.0.0", "parse-gitignore": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/antfu" } }, - "node_modules/eslint-config-flat-gitignore/node_modules/find-up": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz", - "integrity": "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==", - "dev": true, - "dependencies": { - "locate-path": "^7.2.0", - "path-exists": "^5.0.0", - "unicorn-magic": "^0.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint-config-flat-gitignore/node_modules/locate-path": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", - "dev": true, - "dependencies": { - "p-locate": "^6.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint-config-flat-gitignore/node_modules/p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint-config-flat-gitignore/node_modules/p-locate": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", - "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", - "dev": true, - "dependencies": { - "p-limit": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint-config-flat-gitignore/node_modules/path-exists": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/eslint-config-flat-gitignore/node_modules/yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", - "dev": true, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/eslint-flat-config-utils": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/eslint-flat-config-utils/-/eslint-flat-config-utils-0.1.2.tgz", - "integrity": "sha512-NfeUJrbARSHGux2no/zz+YOjfMuPXpedcxRTqov3mlx9PJV2CYAJEj2EjbNSEyHMXQwNCfTtQVZXMSiktQTcpA==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/eslint-flat-config-utils/-/eslint-flat-config-utils-0.2.5.tgz", + "integrity": "sha512-iO+yLZtC/LKgACerkpvsZ6NoRVB2sxT04mOpnNcEM1aTwKy+6TsT46PUvrML4y2uVBS6I67hRCd2JiKAPaL/Uw==", "dev": true, "dependencies": { - "@types/eslint": "^8.56.6" + "@types/eslint": "^8.56.10", + "pathe": "^1.1.2" }, "funding": { "url": "https://github.com/sponsors/antfu" @@ -9158,10 +9430,28 @@ } }, "node_modules/eslint-plugin-antfu": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-antfu/-/eslint-plugin-antfu-2.1.2.tgz", - "integrity": "sha512-s7ZTOM3uq0iqpp6gF0UEotnvup7f2PHBUftCytLZX0+6C9j9KadKZQh6bVVngAyFgsmeD9+gcBopOYLClb2oDg==", + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-antfu/-/eslint-plugin-antfu-2.3.4.tgz", + "integrity": "sha512-5RIjJpBK1tuNHuLyFyZ90/iW9s439dP1u2cxA4dH70djx9sKq1CqI+O6Q95aVjgFNTDtQzSC9uYdAD5uEEKciQ==", "dev": true, + "dependencies": { + "@antfu/utils": "^0.7.10" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/eslint-plugin-command": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-command/-/eslint-plugin-command-0.2.3.tgz", + "integrity": "sha512-1bBYNfjZg60N2ZpLV5ATYSYyueIJ+zl5yKrTs0UFDdnyu07dNSZ7Xplnc+Wb6SXTdc1sIaoIrnuyhvztcltX6A==", + "dev": true, + "dependencies": { + "@es-joy/jsdoccomment": "^0.43.0" + }, "funding": { "url": "https://github.com/sponsors/antfu" }, @@ -9170,21 +9460,22 @@ } }, "node_modules/eslint-plugin-es-x": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.6.0.tgz", - "integrity": "sha512-I0AmeNgevgaTR7y2lrVCJmGYF0rjoznpDvqV/kIkZSZbZ8Rw3eu4cGlvBBULScfkSOCzqKbff5LR4CNrV7mZHA==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.8.0.tgz", + "integrity": "sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==", "dev": true, + "funding": [ + "https://github.com/sponsors/ota-meshi", + "https://opencollective.com/eslint" + ], "dependencies": { "@eslint-community/eslint-utils": "^4.1.2", - "@eslint-community/regexpp": "^4.6.0", - "eslint-compat-utils": "^0.5.0" + "@eslint-community/regexpp": "^4.11.0", + "eslint-compat-utils": "^0.5.1" }, "engines": { "node": "^14.18.0 || >=16.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ota-meshi" - }, "peerDependencies": { "eslint": ">=8" } @@ -9218,26 +9509,27 @@ } }, "node_modules/eslint-plugin-import-x": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-0.4.4.tgz", - "integrity": "sha512-+6vns/GOAL0K5tzQ7ZescD2vFBz3cICZqT9R5CQ9h/bTA+Jkae8DuHT2gYhFb2K97kzsLnmPmKM51Iq9g6vTRA==", + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-0.5.3.tgz", + "integrity": "sha512-hJ/wkMcsLQXAZL3+txXIDpbW5cqwdm1rLTqV4VRY03aIbzE3zWE7rPZKW6Gzf7xyl1u3V1iYC6tOG77d9NF4GQ==", "dev": true, "dependencies": { - "@typescript-eslint/utils": "^5.62.0", + "@typescript-eslint/utils": "^7.4.0", "debug": "^4.3.4", "doctrine": "^3.0.0", - "eslint-compat-utils": "^0.5.0", "eslint-import-resolver-node": "^0.3.9", "get-tsconfig": "^4.7.3", "is-glob": "^4.0.3", "minimatch": "^9.0.3", - "semver": "^7.6.0" + "semver": "^7.6.0", + "stable-hash": "^0.0.4", + "tslib": "^2.6.2" }, "engines": { "node": ">=16" }, "peerDependencies": { - "eslint": "^7.2.0 || ^8 || ^9.0.0-0" + "eslint": "^8.56.0 || ^9.0.0-0" } }, "node_modules/eslint-plugin-import-x/node_modules/brace-expansion": { @@ -9250,9 +9542,9 @@ } }, "node_modules/eslint-plugin-import-x/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -9264,20 +9556,11 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/eslint-plugin-import-x/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } + "node_modules/eslint-plugin-import-x/node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "dev": true }, "node_modules/eslint-plugin-jest": { "version": "28.6.0", @@ -9304,154 +9587,22 @@ } } }, - "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/scope-manager": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", - "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/types": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", - "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", - "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/utils": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.1.tgz", - "integrity": "sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.16.1", - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/typescript-estree": "7.16.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - } - }, - "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", - "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.16.1", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/eslint-plugin-jest/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/eslint-plugin-jest/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/eslint-plugin-jest/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/eslint-plugin-jsdoc": { - "version": "48.2.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.2.tgz", - "integrity": "sha512-S0Gk+rpT5w/ephKCncUY7kUsix9uE4B9XI8D/fS1/26d8okE+vZsuG1IvIt4B6sJUdQqsnzi+YXfmh+HJG11CA==", + "version": "48.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.7.0.tgz", + "integrity": "sha512-5oiVf7Y+ZxGYQTlLq81X72n+S+hjvS/u0upAdbpPEeaIZILK3MKN8lm/6QqKioBjm/qZ0B5XpMQUtc2fUkqXAg==", "dev": true, "dependencies": { - "@es-joy/jsdoccomment": "~0.42.0", + "@es-joy/jsdoccomment": "~0.46.0", "are-docs-informative": "^0.0.2", "comment-parser": "1.4.1", - "debug": "^4.3.4", + "debug": "^4.3.5", "escape-string-regexp": "^4.0.0", - "esquery": "^1.5.0", - "is-builtin-module": "^3.2.1", - "semver": "^7.6.0", - "spdx-expression-parse": "^4.0.0" + "esquery": "^1.6.0", + "parse-imports": "^2.1.1", + "semver": "^7.6.2", + "spdx-expression-parse": "^4.0.0", + "synckit": "^0.9.0" }, "engines": { "node": ">=18" @@ -9460,6 +9611,20 @@ "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" } }, + "node_modules/eslint-plugin-jsdoc/node_modules/@es-joy/jsdoccomment": { + "version": "0.46.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.46.0.tgz", + "integrity": "sha512-C3Axuq1xd/9VqFZpW4YAzOx5O9q/LP46uIQy/iNDpHG3fmPa6TBtvfglMCs3RBiBxAIi0Go97r8+jvTt55XMyQ==", + "dev": true, + "dependencies": { + "comment-parser": "1.4.1", + "esquery": "^1.6.0", + "jsdoc-type-pratt-parser": "~4.0.0" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/eslint-plugin-jsdoc/node_modules/comment-parser": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", @@ -9469,21 +9634,6 @@ "node": ">= 12.0.0" } }, - "node_modules/eslint-plugin-jsdoc/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/eslint-plugin-jsdoc/node_modules/spdx-expression-parse": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", @@ -9495,9 +9645,9 @@ } }, "node_modules/eslint-plugin-jsonc": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsonc/-/eslint-plugin-jsonc-2.14.1.tgz", - "integrity": "sha512-Tei6G4N7pZulP5MHi0EIdtseiCqUPkDMd0O8Zrw4muMIlsjJ5/B9X+U3Pfo6B7l0mTL9LN9FwuWT70dRJ6z7tg==", + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsonc/-/eslint-plugin-jsonc-2.16.0.tgz", + "integrity": "sha512-Af/ZL5mgfb8FFNleH6KlO4/VdmDuTqmM+SPnWcdoWywTetv7kq+vQe99UyQb9XO3b0OWLVuTH7H0d/PXYCMdSg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", @@ -9518,10 +9668,28 @@ "eslint": ">=6.0.0" } }, + "node_modules/eslint-plugin-jsonc/node_modules/synckit": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.6.2.tgz", + "integrity": "sha512-Vhf+bUa//YSTYKseDiiEuQmhGCoIF3CVBhunm3r/DQnYiGT4JssmnKQc44BIyOZRK2pKjXXAgbhfmbeoC9CJpA==", + "dev": true, + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/eslint-plugin-jsonc/node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "dev": true + }, "node_modules/eslint-plugin-markdown": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-markdown/-/eslint-plugin-markdown-4.0.1.tgz", - "integrity": "sha512-5/MnGvYU0i8MbHH5cg8S+Vl3DL+bqRNYshk1xUO86DilNBaxtTkhH+5FD0/yO03AmlI6+lfNFdk2yOw72EPzpA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-markdown/-/eslint-plugin-markdown-5.1.0.tgz", + "integrity": "sha512-SJeyKko1K6GwI0AN6xeCDToXDkfKZfXcexA6B+O2Wr2btUS9GrC+YgwSyVli5DJnctUHjFXcQ2cqTaAmVoLi2A==", "dev": true, "dependencies": { "mdast-util-from-markdown": "^0.8.5" @@ -9534,58 +9702,52 @@ } }, "node_modules/eslint-plugin-n": { - "version": "16.6.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.6.2.tgz", - "integrity": "sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==", + "version": "17.9.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-17.9.0.tgz", + "integrity": "sha512-CPSaXDXdrT4nsrOrO4mT4VB6FMUkoySRkHWuuJJHVqsIEjIeZgMY1H7AzSwPbDScikBmLN82KeM1u7ixV7PzGg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "builtins": "^5.0.1", + "enhanced-resolve": "^5.17.0", "eslint-plugin-es-x": "^7.5.0", "get-tsconfig": "^4.7.0", - "globals": "^13.24.0", + "globals": "^15.0.0", "ignore": "^5.2.4", - "is-builtin-module": "^3.2.1", - "is-core-module": "^2.12.1", - "minimatch": "^3.1.2", - "resolve": "^1.22.2", + "minimatch": "^9.0.0", "semver": "^7.5.3" }, "engines": { - "node": ">=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" + "url": "https://opencollective.com/eslint" }, "peerDependencies": { - "eslint": ">=7.0.0" + "eslint": ">=8.23.0" } }, - "node_modules/eslint-plugin-n/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "node_modules/eslint-plugin-n/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "balanced-match": "^1.0.0" } }, - "node_modules/eslint-plugin-n/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "node_modules/eslint-plugin-n/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, "engines": { - "node": ">=10" + "node": ">=16 || 14 >=14.17" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/eslint-plugin-no-only-tests": { @@ -9598,20 +9760,20 @@ } }, "node_modules/eslint-plugin-perfectionist": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-perfectionist/-/eslint-plugin-perfectionist-2.7.0.tgz", - "integrity": "sha512-RpSMc0T0DT9DlOj4APzwlAjCqQMxFdsIYlupe73eDkKLn1mMK7fVw2z3nj2y822szKOpvHA7bDa56ySOlr4GXw==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-perfectionist/-/eslint-plugin-perfectionist-2.11.0.tgz", + "integrity": "sha512-XrtBtiu5rbQv88gl+1e2RQud9te9luYNvKIgM9emttQ2zutHPzY/AQUucwxscDKV4qlTkvLTxjOFvxqeDpPorw==", "dev": true, "dependencies": { - "@typescript-eslint/utils": "^6.13.0", + "@typescript-eslint/utils": "^6.13.0 || ^7.0.0", "minimatch": "^9.0.3", "natural-compare-lite": "^1.4.0" }, "peerDependencies": { - "astro-eslint-parser": "^0.16.0", + "astro-eslint-parser": "^1.0.2", "eslint": ">=8.0.0", "svelte": ">=3.0.0", - "svelte-eslint-parser": "^0.33.0", + "svelte-eslint-parser": "^0.37.0", "vue-eslint-parser": ">=9.0.0" }, "peerDependenciesMeta": { @@ -9629,121 +9791,6 @@ } } }, - "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/scope-manager": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", - "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", - "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", - "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/utils": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", - "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "semver": "^7.5.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - } - }, - "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", - "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/eslint-plugin-perfectionist/node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -9754,9 +9801,9 @@ } }, "node_modules/eslint-plugin-perfectionist/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -9768,16 +9815,46 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/eslint-plugin-regexp": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-2.6.0.tgz", + "integrity": "sha512-FCL851+kislsTEQEMioAlpDuK5+E5vs0hi1bF8cFlPlHcEjeRhuAzEsGikXRreE+0j4WhW2uO54MqTjXtYOi3A==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.9.1", + "comment-parser": "^1.4.0", + "jsdoc-type-pratt-parser": "^4.0.0", + "refa": "^0.12.1", + "regexp-ast-analysis": "^0.7.1", + "scslre": "^0.3.0" + }, + "engines": { + "node": "^18 || >=20" + }, + "peerDependencies": { + "eslint": ">=8.44.0" + } + }, + "node_modules/eslint-plugin-regexp/node_modules/comment-parser": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", + "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", + "dev": true, + "engines": { + "node": ">= 12.0.0" + } + }, "node_modules/eslint-plugin-toml": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-toml/-/eslint-plugin-toml-0.10.0.tgz", - "integrity": "sha512-HzhRjePs4FDszPRY6ryHXV90MsSEkJsWnP175x33Iop/W6/hb80qjzImO5LlQfqhX3B0TkotOFSIigNI4AdGsw==", + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-toml/-/eslint-plugin-toml-0.11.1.tgz", + "integrity": "sha512-Y1WuMSzfZpeMIrmlP1nUh3kT8p96mThIq4NnHrYUhg10IKQgGfBZjAWnrg9fBqguiX4iFps/x/3Hb5TxBisfdw==", "dev": true, "dependencies": { "debug": "^4.1.1", "eslint-compat-utils": "^0.5.0", "lodash": "^4.17.19", - "toml-eslint-parser": "^0.9.0" + "toml-eslint-parser": "^0.10.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -9790,17 +9867,17 @@ } }, "node_modules/eslint-plugin-unicorn": { - "version": "51.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-51.0.1.tgz", - "integrity": "sha512-MuR/+9VuB0fydoI0nIn2RDA5WISRn4AsJyNSaNKLVwie9/ONvQhxOBbkfSICBPnzKrB77Fh6CZZXjgTt/4Latw==", + "version": "54.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-54.0.0.tgz", + "integrity": "sha512-XxYLRiYtAWiAjPv6z4JREby1TAE2byBC7wlh0V4vWDCpccOSU1KovWV//jqPXF6bq3WKxqX9rdjoRQ1EhdmNdQ==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-validator-identifier": "^7.24.5", "@eslint-community/eslint-utils": "^4.4.0", - "@eslint/eslintrc": "^2.1.4", + "@eslint/eslintrc": "^3.0.2", "ci-info": "^4.0.0", "clean-regexp": "^1.0.0", - "core-js-compat": "^3.34.0", + "core-js-compat": "^3.37.0", "esquery": "^1.5.0", "indent-string": "^4.0.0", "is-builtin-module": "^3.2.1", @@ -9809,11 +9886,11 @@ "read-pkg-up": "^7.0.1", "regexp-tree": "^0.1.27", "regjsparser": "^0.10.0", - "semver": "^7.5.4", + "semver": "^7.6.1", "strip-indent": "^3.0.0" }, "engines": { - "node": ">=16" + "node": ">=18.18" }, "funding": { "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" @@ -9822,6 +9899,35 @@ "eslint": ">=8.56.0" } }, + "node_modules/eslint-plugin-unicorn/node_modules/@eslint/eslintrc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", + "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "node_modules/eslint-plugin-unicorn/node_modules/ci-info": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.0.0.tgz", @@ -9837,6 +9943,59 @@ "node": ">=8" } }, + "node_modules/eslint-plugin-unicorn/node_modules/eslint-visitor-keys": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/espree": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", + "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", + "dev": true, + "dependencies": { + "acorn": "^8.12.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/eslint-plugin-unicorn/node_modules/jsesc": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", @@ -9850,9 +10009,9 @@ } }, "node_modules/eslint-plugin-unused-imports": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-3.1.0.tgz", - "integrity": "sha512-9l1YFCzXKkw1qtAru1RWUtG2EVDZY0a0eChKXcL+EZ5jitG7qxdctu4RnvhOJHv4xfmUf7h+JJPINlVpGhZMrw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-3.2.0.tgz", + "integrity": "sha512-6uXyn6xdINEpxE1MtDjxQsyXB37lfyO2yKGVVgtD7WEWQGORSOZjgrD6hBhvGv4/SO+TOlS+UnC6JppRqbuwGQ==", "dev": true, "dependencies": { "eslint-rule-composer": "^0.3.0" @@ -9871,18 +10030,18 @@ } }, "node_modules/eslint-plugin-vitest": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vitest/-/eslint-plugin-vitest-0.4.0.tgz", - "integrity": "sha512-3oWgZIwdWVBQ5plvkmOBjreIGLQRdYb7x54OP8uIRHeZyRVJIdOn9o/qWVb9292fDMC8jn7H7d9TSFBZqhrykQ==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-vitest/-/eslint-plugin-vitest-0.5.4.tgz", + "integrity": "sha512-um+odCkccAHU53WdKAw39MY61+1x990uXjSPguUCq3VcEHdqJrOb8OTMrbYlY6f9jAKx7x98kLVlIe3RJeJqoQ==", "dev": true, "dependencies": { - "@typescript-eslint/utils": "^7.2.0" + "@typescript-eslint/utils": "^7.7.1" }, "engines": { "node": "^18.0.0 || >= 20.0.0" }, "peerDependencies": { - "eslint": ">=8.0.0", + "eslint": "^8.57.0 || ^9.0.0", "vitest": "*" }, "peerDependenciesMeta": { @@ -9894,134 +10053,10 @@ } } }, - "node_modules/eslint-plugin-vitest/node_modules/@typescript-eslint/scope-manager": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.4.0.tgz", - "integrity": "sha512-68VqENG5HK27ypafqLVs8qO+RkNc7TezCduYrx8YJpXq2QGZ30vmNZGJJJC48+MVn4G2dCV8m5ZTVnzRexTVtw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.4.0", - "@typescript-eslint/visitor-keys": "7.4.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/eslint-plugin-vitest/node_modules/@typescript-eslint/types": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.4.0.tgz", - "integrity": "sha512-mjQopsbffzJskos5B4HmbsadSJQWaRK0UxqQ7GuNA9Ga4bEKeiO6b2DnB6cM6bpc8lemaPseh0H9B/wyg+J7rw==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/eslint-plugin-vitest/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.4.0.tgz", - "integrity": "sha512-A99j5AYoME/UBQ1ucEbbMEmGkN7SE0BvZFreSnTd1luq7yulcHdyGamZKizU7canpGDWGJ+Q6ZA9SyQobipePg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.4.0", - "@typescript-eslint/visitor-keys": "7.4.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-vitest/node_modules/@typescript-eslint/utils": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.4.0.tgz", - "integrity": "sha512-NQt9QLM4Tt8qrlBVY9lkMYzfYtNz8/6qwZg8pI3cMGlPnj6mOpRxxAm7BMJN9K0AiY+1BwJ5lVC650YJqYOuNg==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "7.4.0", - "@typescript-eslint/types": "7.4.0", - "@typescript-eslint/typescript-estree": "7.4.0", - "semver": "^7.5.4" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - } - }, - "node_modules/eslint-plugin-vitest/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.4.0.tgz", - "integrity": "sha512-0zkC7YM0iX5Y41homUUeW1CHtZR01K3ybjM1l6QczoMuay0XKtrb93kv95AxUGwdjGr64nNqnOCwmEl616N8CA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.4.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/eslint-plugin-vitest/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/eslint-plugin-vitest/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/eslint-plugin-vue": { - "version": "9.24.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.24.0.tgz", - "integrity": "sha512-9SkJMvF8NGMT9aQCwFc5rj8Wo1XWSMSHk36i7ZwdI614BU7sIOR28ZjuFPKp8YGymZN12BSEbiSwa7qikp+PBw==", + "version": "9.27.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.27.0.tgz", + "integrity": "sha512-5Dw3yxEyuBSXTzT5/Ge1X5kIkRTQ3nvBn/VwPwInNiZBSJOO/timWMUaflONnFBzU6NhB68lxnCda7ULV5N7LA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", @@ -10030,14 +10065,14 @@ "nth-check": "^2.1.1", "postcss-selector-parser": "^6.0.15", "semver": "^7.6.0", - "vue-eslint-parser": "^9.4.2", + "vue-eslint-parser": "^9.4.3", "xml-name-validator": "^4.0.0" }, "engines": { "node": "^14.17.0 || >=16.0.0" }, "peerDependencies": { - "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0" + "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" } }, "node_modules/eslint-plugin-vue/node_modules/globals": { @@ -10055,21 +10090,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-plugin-vue/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/eslint-plugin-vue/node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -10083,9 +10103,9 @@ } }, "node_modules/eslint-plugin-yml": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-1.13.2.tgz", - "integrity": "sha512-1i71VhmsG5UxE41rIJmJjhlTTxYy7upAY5Hqj8AdBc7rfJzRIZr3a2spuOS8+N7ZDCWsHAWY3J6lzQNQHDv6Uw==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-1.14.0.tgz", + "integrity": "sha512-ESUpgYPOcAYQO9czugcX5OqRvn/ydDVwGCPXY4YjPqc09rHaUVUA6IE6HLQys4rXk/S+qx3EwTd1wHCwam/OWQ==", "dev": true, "dependencies": { "debug": "^4.3.2", @@ -10105,16 +10125,16 @@ } }, "node_modules/eslint-processor-vue-blocks": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/eslint-processor-vue-blocks/-/eslint-processor-vue-blocks-0.1.1.tgz", - "integrity": "sha512-9+dU5lU881log570oBwpelaJmOfOzSniben7IWEDRYQPPWwlvaV7NhOtsTuUWDqpYT+dtKKWPsgz4OkOi+aZnA==", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/eslint-processor-vue-blocks/-/eslint-processor-vue-blocks-0.1.2.tgz", + "integrity": "sha512-PfpJ4uKHnqeL/fXUnzYkOax3aIenlwewXRX8jFinA1a2yCFnLgMuiH3xvCgvHHUlV2xJWQHbCTdiJWGwb3NqpQ==", "dev": true, "funding": { "url": "https://github.com/sponsors/antfu" }, "peerDependencies": { "@vue/compiler-sfc": "^3.3.0", - "eslint": "^8.50.0" + "eslint": "^8.50.0 || ^9.0.0" } }, "node_modules/eslint-rule-composer": { @@ -10127,16 +10147,19 @@ } }, "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "estraverse": "^5.2.0" }, "engines": { - "node": ">=8.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-visitor-keys": { @@ -10158,33 +10181,6 @@ "dev": true, "peer": true }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "peer": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4.0" - } - }, "node_modules/eslint/node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -10336,9 +10332,9 @@ } }, "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -10347,15 +10343,6 @@ "node": ">=0.10" } }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", @@ -10368,19 +10355,10 @@ "node": ">=4.0" } }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { "node": ">=4.0" @@ -10517,6 +10495,12 @@ "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", "dev": true }, + "node_modules/fast-uri": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", + "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", + "dev": true + }, "node_modules/fastq": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", @@ -10661,6 +10645,18 @@ "node": ">=8" } }, + "node_modules/find-up-simple": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.0.tgz", + "integrity": "sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/find-versions": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-4.0.0.tgz", @@ -10929,9 +10925,9 @@ } }, "node_modules/get-tsconfig": { - "version": "4.7.3", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz", - "integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==", + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.5.tgz", + "integrity": "sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==", "dev": true, "dependencies": { "resolve-pkg-maps": "^1.0.0" @@ -11038,22 +11034,34 @@ "node": ">= 6" } }, - "node_modules/global-dirs": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", - "integrity": "sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==", + "node_modules/global-directory": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", + "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==", "dev": true, "dependencies": { - "ini": "^1.3.4" + "ini": "4.1.1" }, "engines": { - "node": ">=4" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/global-directory/node_modules/ini": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", + "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/globals": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.0.0.tgz", - "integrity": "sha512-m/C/yR4mjO6pXDTm9/R/SpYTAIyaUB4EOzcaaMEl7mds7Mshct9GfejiJNQGjHHbdMPey13Kpu4TMbYi9ex1pw==", + "version": "15.8.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.8.0.tgz", + "integrity": "sha512-VZAJ4cewHTExBWDHR6yptdIBlx9YSSZuwojj9Nt5mBRXQzrKakDsVKQ1J63sklLvzAJm0X5+RpO4i3Y2hcOnFw==", "dev": true, "engines": { "node": ">=18" @@ -11554,9 +11562,9 @@ ] }, "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, "engines": { "node": ">= 4" @@ -11608,6 +11616,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/import-meta-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", + "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -12610,6 +12628,15 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/jiti": { + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "dev": true, + "bin": { + "jiti": "bin/jiti.js" + } + }, "node_modules/jose": { "version": "4.15.5", "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.5.tgz", @@ -13103,12 +13130,6 @@ "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=" }, - "node_modules/lodash.isfunction": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", - "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==", - "dev": true - }, "node_modules/lodash.ismatch": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", @@ -13215,22 +13236,19 @@ "dev": true }, "node_modules/magic-string": { - "version": "0.30.8", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", - "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", + "version": "0.30.10", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", "dev": true, "peer": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" } }, "node_modules/magic-string/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", "dev": true, "peer": true }, @@ -13699,9 +13717,12 @@ } }, "node_modules/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/minimist-options": { "version": "4.1.0", @@ -14299,6 +14320,19 @@ "node": ">=14" } }, + "node_modules/parse-imports": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/parse-imports/-/parse-imports-2.1.1.tgz", + "integrity": "sha512-TDT4HqzUiTMO1wJRwg/t/hYk8Wdp3iF/ToMIlAoVQfL1Xs/sTxq1dKWSMjMbQmIarfWKymOyly40+zmPHXMqCA==", + "dev": true, + "dependencies": { + "es-module-lexer": "^1.5.3", + "slashes": "^3.0.12" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -14373,15 +14407,15 @@ } }, "node_modules/pathe": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.1.tgz", - "integrity": "sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", "dev": true }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", "dev": true }, "node_modules/picomatch": { @@ -14456,9 +14490,9 @@ } }, "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "version": "8.4.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", + "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", "dev": true, "funding": [ { @@ -14477,7 +14511,7 @@ "peer": true, "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.0", + "picocolors": "^1.0.1", "source-map-js": "^1.2.0" }, "engines": { @@ -14485,9 +14519,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.0.16", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz", - "integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.1.tgz", + "integrity": "sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==", "dev": true, "dependencies": { "cssesc": "^3.0.0", @@ -15186,6 +15220,31 @@ "node": ">=4" } }, + "node_modules/refa": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/refa/-/refa-0.12.1.tgz", + "integrity": "sha512-J8rn6v4DBb2nnFqkqwy6/NnTYMcgLA+sLr0iIO41qpv0n+ngb7ksag2tMRl0inb1bbO/esUwzW1vbJi7K0sI0g==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.8.0" + }, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/regexp-ast-analysis": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/regexp-ast-analysis/-/regexp-ast-analysis-0.7.1.tgz", + "integrity": "sha512-sZuz1dYW/ZsfG17WSAG7eS85r5a0dDsvg+7BiiYR5o6lKCAtUrEwdmRmaGF6rwVj3LcmAeYkOWKEPlbPzN3Y3A==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.8.0", + "refa": "^0.12.1" + }, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, "node_modules/regexp-tree": { "version": "0.1.27", "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", @@ -15290,18 +15349,6 @@ "node": ">=4" } }, - "node_modules/resolve-global": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-global/-/resolve-global-1.0.0.tgz", - "integrity": "sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==", - "dev": true, - "dependencies": { - "global-dirs": "^0.1.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/resolve-pkg-maps": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", @@ -15423,13 +15470,24 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "node_modules/scslre": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/scslre/-/scslre-0.3.0.tgz", + "integrity": "sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==", + "dev": true, "dependencies": { - "lru-cache": "^6.0.0" + "@eslint-community/regexpp": "^4.8.0", + "refa": "^0.12.0", + "regexp-ast-analysis": "^0.7.0" }, + "engines": { + "node": "^14.0.0 || >=16.0.0" + } + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "bin": { "semver": "bin/semver.js" }, @@ -15522,15 +15580,13 @@ } }, "node_modules/shiki": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.1.tgz", - "integrity": "sha512-+Jz4nBkCBe0mEDqo1eKRcCdjRtrCjozmcbTUjbPTX7OOJfEbTZzlUWlZtGe3Gb5oV1/jnojhG//YZc3rs9zSEw==", + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.10.3.tgz", + "integrity": "sha512-eneCLncGuvPdTutJuLyUGS8QNPAVFO5Trvld2wgEq1e002mwctAhJKeMGWtWVXOIEzmlcLRqcgPSorR6AVzOmQ==", "dev": true, "dependencies": { - "ansi-sequence-parser": "^1.1.0", - "jsonc-parser": "^3.2.0", - "vscode-oniguruma": "^1.7.0", - "vscode-textmate": "^8.0.0" + "@shikijs/core": "1.10.3", + "@types/hast": "^3.0.4" } }, "node_modules/side-channel": { @@ -15602,6 +15658,12 @@ "node": ">=8" } }, + "node_modules/slashes": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/slashes/-/slashes-3.0.12.tgz", + "integrity": "sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==", + "dev": true + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -15790,6 +15852,12 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, + "node_modules/stable-hash": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.4.tgz", + "integrity": "sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==", + "dev": true + }, "node_modules/stack-trace": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", @@ -15858,6 +15926,15 @@ "safe-buffer": "~5.2.0" } }, + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true, + "engines": { + "node": ">=0.6.19" + } + }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -16007,23 +16084,36 @@ } }, "node_modules/synckit": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.6.2.tgz", - "integrity": "sha512-Vhf+bUa//YSTYKseDiiEuQmhGCoIF3CVBhunm3r/DQnYiGT4JssmnKQc44BIyOZRK2pKjXXAgbhfmbeoC9CJpA==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz", + "integrity": "sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==", "dev": true, "dependencies": { - "tslib": "^2.3.1" + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=12.20" + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" } }, "node_modules/synckit/node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", "dev": true }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -16115,9 +16205,9 @@ } }, "node_modules/toml-eslint-parser": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/toml-eslint-parser/-/toml-eslint-parser-0.9.3.tgz", - "integrity": "sha512-moYoCvkNUAPCxSW9jmHmRElhm4tVJpHL8ItC/+uYD0EpPSFXbck7yREz9tNdJVTSpHVod8+HoipcpbQ0oE6gsw==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/toml-eslint-parser/-/toml-eslint-parser-0.10.0.tgz", + "integrity": "sha512-khrZo4buq4qVmsGzS5yQjKe/WsFvV8fGfOjDQN0q4iy9FjRfPWRgTFrU8u1R2iu/SfWLhY9WnCi4Jhdrcbtg+g==", "dev": true, "dependencies": { "eslint-visitor-keys": "^3.0.0" @@ -16351,24 +16441,25 @@ "dev": true }, "node_modules/typedoc": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.2.tgz", - "integrity": "sha512-286F7BeATBiWe/qC4PCOCKlSTwfnsLbC/4cZ68oGBbvAqb9vV33quEOXx7q176OXotD+JdEerdQ1OZGJ818lnA==", + "version": "0.26.4", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.26.4.tgz", + "integrity": "sha512-FlW6HpvULDKgc3rK04V+nbFyXogPV88hurarDPOjuuB5HAwuAlrCMQ5NeH7Zt68a/ikOKu6Z/0hFXAeC9xPccQ==", "dev": true, "dependencies": { "lunr": "^2.3.9", - "marked": "^4.3.0", - "minimatch": "^9.0.3", - "shiki": "^0.14.1" + "markdown-it": "^14.1.0", + "minimatch": "^9.0.5", + "shiki": "^1.9.1", + "yaml": "^2.4.5" }, "bin": { "typedoc": "bin/typedoc" }, "engines": { - "node": ">= 16" + "node": ">= 18" }, "peerDependencies": { - "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x" + "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x" } }, "node_modules/typedoc/node_modules/brace-expansion": { @@ -16380,22 +16471,10 @@ "balanced-match": "^1.0.0" } }, - "node_modules/typedoc/node_modules/marked": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", - "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", - "dev": true, - "bin": { - "marked": "bin/marked.js" - }, - "engines": { - "node": ">= 12" - } - }, "node_modules/typedoc/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -16407,10 +16486,22 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/typedoc/node_modules/yaml": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", + "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", + "dev": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", + "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -16600,22 +16691,10 @@ "node": ">= 0.8" } }, - "node_modules/vscode-oniguruma": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", - "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==", - "dev": true - }, - "node_modules/vscode-textmate": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", - "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==", - "dev": true - }, "node_modules/vue-eslint-parser": { - "version": "9.4.2", - "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz", - "integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.3.tgz", + "integrity": "sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==", "dev": true, "dependencies": { "debug": "^4.3.4", @@ -16636,31 +16715,6 @@ "eslint": ">=6.0.0" } }, - "node_modules/vue-eslint-parser/node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/vue-eslint-parser/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, "node_modules/walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", @@ -16843,9 +16897,9 @@ } }, "node_modules/yaml-eslint-parser": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/yaml-eslint-parser/-/yaml-eslint-parser-1.2.2.tgz", - "integrity": "sha512-pEwzfsKbTrB8G3xc/sN7aw1v6A6c/pKxLAkjclnAyo5g5qOh6eL9WGu0o3cSDQZKrTNk4KL4lQSwZW+nBkANEg==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/yaml-eslint-parser/-/yaml-eslint-parser-1.2.3.tgz", + "integrity": "sha512-4wZWvE398hCP7O8n3nXKu/vdq1HcH01ixYlCREaJL5NUMwQ0g3MaGFUBNSlmBtKmhbtVG/Cm6lyYmSVTEVil8A==", "dev": true, "dependencies": { "eslint-visitor-keys": "^3.0.0", @@ -16860,9 +16914,9 @@ } }, "node_modules/yaml-eslint-parser/node_modules/yaml": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz", - "integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==", + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", + "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", "dev": true, "bin": { "yaml": "bin.mjs" @@ -16989,145 +17043,120 @@ } }, "@antfu/eslint-config": { - "version": "2.11.4", - "resolved": "https://registry.npmjs.org/@antfu/eslint-config/-/eslint-config-2.11.4.tgz", - "integrity": "sha512-kQC8XFKih5igRodfDBpXIi3KFsjYuCfX2F9VK4hk79+KkDETUF/14ymai4O+Y+vmSNdRFwjtDL5YhcRoaD0rAg==", + "version": "2.21.3", + "resolved": "https://registry.npmjs.org/@antfu/eslint-config/-/eslint-config-2.21.3.tgz", + "integrity": "sha512-nY2pYSJGo5utj8LSMHIkJVMv04PTX9Cpu78ciCgkO5R5DOHyilvXXAEe+iwXkvaaRTmtDqhnhbIPFxKCiaqFNA==", "dev": true, "requires": { - "@antfu/install-pkg": "^0.3.1", + "@antfu/install-pkg": "^0.3.3", "@clack/prompts": "^0.7.0", - "@stylistic/eslint-plugin": "^1.7.0", - "@typescript-eslint/eslint-plugin": "^7.4.0", - "@typescript-eslint/parser": "^7.4.0", - "eslint-config-flat-gitignore": "^0.1.3", - "eslint-flat-config-utils": "^0.1.1", + "@stylistic/eslint-plugin": "^2.3.0", + "@typescript-eslint/eslint-plugin": "^7.15.0", + "@typescript-eslint/parser": "^7.15.0", + "eslint-config-flat-gitignore": "^0.1.5", + "eslint-flat-config-utils": "^0.2.5", "eslint-merge-processors": "^0.1.0", - "eslint-plugin-antfu": "^2.1.2", + "eslint-plugin-antfu": "^2.3.4", + "eslint-plugin-command": "^0.2.3", "eslint-plugin-eslint-comments": "^3.2.0", - "eslint-plugin-import-x": "^0.4.4", - "eslint-plugin-jsdoc": "^48.2.1", - "eslint-plugin-jsonc": "^2.14.1", - "eslint-plugin-markdown": "^4.0.1", - "eslint-plugin-n": "^16.6.2", + "eslint-plugin-import-x": "^0.5.3", + "eslint-plugin-jsdoc": "^48.5.2", + "eslint-plugin-jsonc": "^2.16.0", + "eslint-plugin-markdown": "^5.0.0", + "eslint-plugin-n": "^17.9.0", "eslint-plugin-no-only-tests": "^3.1.0", - "eslint-plugin-perfectionist": "^2.7.0", - "eslint-plugin-toml": "^0.10.0", - "eslint-plugin-unicorn": "^51.0.1", - "eslint-plugin-unused-imports": "^3.1.0", - "eslint-plugin-vitest": "^0.4.0", - "eslint-plugin-vue": "^9.24.0", - "eslint-plugin-yml": "^1.13.2", - "eslint-processor-vue-blocks": "^0.1.1", - "globals": "^15.0.0", + "eslint-plugin-perfectionist": "^2.11.0", + "eslint-plugin-regexp": "^2.6.0", + "eslint-plugin-toml": "^0.11.1", + "eslint-plugin-unicorn": "^54.0.0", + "eslint-plugin-unused-imports": "^3.2.0", + "eslint-plugin-vitest": "^0.5.4", + "eslint-plugin-vue": "^9.27.0", + "eslint-plugin-yml": "^1.14.0", + "eslint-processor-vue-blocks": "^0.1.2", + "globals": "^15.8.0", "jsonc-eslint-parser": "^2.4.0", "local-pkg": "^0.5.0", "parse-gitignore": "^2.0.0", - "picocolors": "^1.0.0", - "toml-eslint-parser": "^0.9.3", - "vue-eslint-parser": "^9.4.2", - "yaml-eslint-parser": "^1.2.2", + "picocolors": "^1.0.1", + "toml-eslint-parser": "^0.10.0", + "vue-eslint-parser": "^9.4.3", + "yaml-eslint-parser": "^1.2.3", "yargs": "^17.7.2" }, "dependencies": { "@typescript-eslint/eslint-plugin": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.4.0.tgz", - "integrity": "sha512-yHMQ/oFaM7HZdVrVm/M2WHaNPgyuJH4WelkSVEWSSsir34kxW2kDJCxlXRhhGWEsMN0WAW/vLpKfKVcm8k+MPw==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz", + "integrity": "sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A==", "dev": true, "requires": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "7.4.0", - "@typescript-eslint/type-utils": "7.4.0", - "@typescript-eslint/utils": "7.4.0", - "@typescript-eslint/visitor-keys": "7.4.0", - "debug": "^4.3.4", + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/type-utils": "7.16.1", + "@typescript-eslint/utils": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", "graphemer": "^1.4.0", - "ignore": "^5.2.4", + "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "ts-api-utils": "^1.3.0" } }, "@typescript-eslint/parser": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.4.0.tgz", - "integrity": "sha512-ZvKHxHLusweEUVwrGRXXUVzFgnWhigo4JurEj0dGF1tbcGh6buL+ejDdjxOQxv6ytcY1uhun1p2sm8iWStlgLQ==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.16.1.tgz", + "integrity": "sha512-u+1Qx86jfGQ5i4JjK33/FnawZRpsLxRnKzGE6EABZ40KxVT/vWsiZFEBBHjFOljmmV3MBYOHEKi0Jm9hbAOClA==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "7.4.0", - "@typescript-eslint/types": "7.4.0", - "@typescript-eslint/typescript-estree": "7.4.0", - "@typescript-eslint/visitor-keys": "7.4.0", + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/typescript-estree": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", "debug": "^4.3.4" } }, - "@typescript-eslint/scope-manager": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.4.0.tgz", - "integrity": "sha512-68VqENG5HK27ypafqLVs8qO+RkNc7TezCduYrx8YJpXq2QGZ30vmNZGJJJC48+MVn4G2dCV8m5ZTVnzRexTVtw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "7.4.0", - "@typescript-eslint/visitor-keys": "7.4.0" - } - }, "@typescript-eslint/type-utils": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.4.0.tgz", - "integrity": "sha512-247ETeHgr9WTRMqHbbQdzwzhuyaJ8dPTuyuUEMANqzMRB1rj/9qFIuIXK7l0FX9i9FXbHeBQl/4uz6mYuCE7Aw==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.1.tgz", + "integrity": "sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "7.4.0", - "@typescript-eslint/utils": "7.4.0", + "@typescript-eslint/typescript-estree": "7.16.1", + "@typescript-eslint/utils": "7.16.1", "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" + "ts-api-utils": "^1.3.0" } }, "@typescript-eslint/types": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.4.0.tgz", - "integrity": "sha512-mjQopsbffzJskos5B4HmbsadSJQWaRK0UxqQ7GuNA9Ga4bEKeiO6b2DnB6cM6bpc8lemaPseh0H9B/wyg+J7rw==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", + "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.4.0.tgz", - "integrity": "sha512-A99j5AYoME/UBQ1ucEbbMEmGkN7SE0BvZFreSnTd1luq7yulcHdyGamZKizU7canpGDWGJ+Q6ZA9SyQobipePg==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", + "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", "dev": true, "requires": { - "@typescript-eslint/types": "7.4.0", - "@typescript-eslint/visitor-keys": "7.4.0", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/utils": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.4.0.tgz", - "integrity": "sha512-NQt9QLM4Tt8qrlBVY9lkMYzfYtNz8/6qwZg8pI3cMGlPnj6mOpRxxAm7BMJN9K0AiY+1BwJ5lVC650YJqYOuNg==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "7.4.0", - "@typescript-eslint/types": "7.4.0", - "@typescript-eslint/typescript-estree": "7.4.0", - "semver": "^7.5.4" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" } }, "@typescript-eslint/visitor-keys": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.4.0.tgz", - "integrity": "sha512-0zkC7YM0iX5Y41homUUeW1CHtZR01K3ybjM1l6QczoMuay0XKtrb93kv95AxUGwdjGr64nNqnOCwmEl616N8CA==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", + "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", "dev": true, "requires": { - "@typescript-eslint/types": "7.4.0", - "eslint-visitor-keys": "^3.4.1" + "@typescript-eslint/types": "7.16.1", + "eslint-visitor-keys": "^3.4.3" } }, "brace-expansion": { @@ -17140,9 +17169,9 @@ } }, "minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "requires": { "brace-expansion": "^2.0.1" @@ -17151,93 +17180,20 @@ } }, "@antfu/install-pkg": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-0.3.1.tgz", - "integrity": "sha512-A3zWY9VeTPnxlMiZtsGHw2lSd3ghwvL8s9RiGOtqvDxhhFfZ781ynsGBa/iUnDJ5zBrmTFQrJDud3TGgRISaxw==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-0.3.3.tgz", + "integrity": "sha512-nHHsk3NXQ6xkCfiRRC8Nfrg8pU5kkr3P3Y9s9dKqiuRmBD0Yap7fymNDjGFKeWhZQHqqbCS5CfeMy9wtExM24w==", "dev": true, "requires": { - "execa": "^8.0.1" - }, - "dependencies": { - "execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - } - }, - "get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "dev": true - }, - "human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "dev": true - }, - "is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true - }, - "mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true - }, - "npm-run-path": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", - "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", - "dev": true, - "requires": { - "path-key": "^4.0.0" - } - }, - "onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "requires": { - "mimic-fn": "^4.0.0" - } - }, - "path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true - }, - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true - }, - "strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true - } + "@jsdevtools/ez-spawn": "^3.0.4" } }, + "@antfu/utils": { + "version": "0.7.10", + "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-0.7.10.tgz", + "integrity": "sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==", + "dev": true + }, "@babel/code-frame": { "version": "7.22.13", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", @@ -17454,9 +17410,9 @@ "dev": true }, "@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", "dev": true }, "@babel/helper-validator-option": { @@ -17531,9 +17487,9 @@ } }, "@babel/parser": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.1.tgz", - "integrity": "sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.8.tgz", + "integrity": "sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w==", "dev": true }, "@babel/plugin-syntax-async-generators": { @@ -17770,60 +17726,140 @@ "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==" }, "@commitlint/cli": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-17.7.2.tgz", - "integrity": "sha512-t3N7TZq7lOeqTOyEgfGcaltHqEJf7YDlPg75MldeVPPyz14jZq/+mbGF9tueDLFX8R6RwdymrN6D+U5XwZ8Iwg==", + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-19.3.0.tgz", + "integrity": "sha512-LgYWOwuDR7BSTQ9OLZ12m7F/qhNY+NpAyPBgo4YNMkACE7lGuUnuQq1yi9hz1KA4+3VqpOYl8H1rY/LYK43v7g==", "dev": true, "requires": { - "@commitlint/format": "^17.4.4", - "@commitlint/lint": "^17.7.0", - "@commitlint/load": "^17.7.2", - "@commitlint/read": "^17.5.1", - "@commitlint/types": "^17.4.4", - "execa": "^5.0.0", - "lodash.isfunction": "^3.0.9", - "resolve-from": "5.0.0", - "resolve-global": "1.0.0", + "@commitlint/format": "^19.3.0", + "@commitlint/lint": "^19.2.2", + "@commitlint/load": "^19.2.0", + "@commitlint/read": "^19.2.1", + "@commitlint/types": "^19.0.3", + "execa": "^8.0.1", "yargs": "^17.0.0" }, "dependencies": { - "resolve-from": { + "execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + } + }, + "get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true + }, + "human-signals": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true + }, + "is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true + }, + "mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true + }, + "npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "requires": { + "path-key": "^4.0.0" + } + }, + "onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "requires": { + "mimic-fn": "^4.0.0" + } + }, + "path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true + }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true + }, + "strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true } } }, "@commitlint/config-conventional": { - "version": "17.7.0", - "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-17.7.0.tgz", - "integrity": "sha512-iicqh2o6et+9kWaqsQiEYZzfLbtoWv9uZl8kbI8EGfnc0HeGafQBF7AJ0ylN9D/2kj6txltsdyQs8+2fTMwWEw==", + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-19.2.2.tgz", + "integrity": "sha512-mLXjsxUVLYEGgzbxbxicGPggDuyWNkf25Ht23owXIH+zV2pv1eJuzLK3t1gDY5Gp6pxdE60jZnWUY5cvgL3ufw==", "dev": true, "requires": { - "conventional-changelog-conventionalcommits": "^6.1.0" + "@commitlint/types": "^19.0.3", + "conventional-changelog-conventionalcommits": "^7.0.2" + }, + "dependencies": { + "conventional-changelog-conventionalcommits": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-7.0.2.tgz", + "integrity": "sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==", + "dev": true, + "requires": { + "compare-func": "^2.0.0" + } + } } }, "@commitlint/config-validator": { - "version": "17.6.7", - "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-17.6.7.tgz", - "integrity": "sha512-vJSncmnzwMvpr3lIcm0I8YVVDJTzyjy7NZAeXbTXy+MPUdAr9pKyyg7Tx/ebOQ9kqzE6O9WT6jg2164br5UdsQ==", + "version": "19.0.3", + "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-19.0.3.tgz", + "integrity": "sha512-2D3r4PKjoo59zBc2auodrSCaUnCSALCx54yveOFwwP/i2kfEAQrygwOleFWswLqK0UL/F9r07MFi5ev2ohyM4Q==", "dev": true, "requires": { - "@commitlint/types": "^17.4.4", + "@commitlint/types": "^19.0.3", "ajv": "^8.11.0" }, "dependencies": { "ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "requires": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "require-from-string": "^2.0.2" } }, "json-schema-traverse": { @@ -17835,12 +17871,12 @@ } }, "@commitlint/ensure": { - "version": "17.6.7", - "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-17.6.7.tgz", - "integrity": "sha512-mfDJOd1/O/eIb/h4qwXzUxkmskXDL9vNPnZ4AKYKiZALz4vHzwMxBSYtyL2mUIDeU9DRSpEUins8SeKtFkYHSw==", + "version": "19.0.3", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-19.0.3.tgz", + "integrity": "sha512-SZEpa/VvBLoT+EFZVb91YWbmaZ/9rPH3ESrINOl0HD2kMYsjvl0tF7nMHh0EpTcv4+gTtZBAe1y/SS6/OhfZzQ==", "dev": true, "requires": { - "@commitlint/types": "^17.4.4", + "@commitlint/types": "^19.0.3", "lodash.camelcase": "^4.3.0", "lodash.kebabcase": "^4.1.1", "lodash.snakecase": "^4.1.1", @@ -17849,87 +17885,100 @@ } }, "@commitlint/execute-rule": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-17.4.0.tgz", - "integrity": "sha512-LIgYXuCSO5Gvtc0t9bebAMSwd68ewzmqLypqI2Kke1rqOqqDbMpYcYfoPfFlv9eyLIh4jocHWwCK5FS7z9icUA==", + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-19.0.0.tgz", + "integrity": "sha512-mtsdpY1qyWgAO/iOK0L6gSGeR7GFcdW7tIjcNFxcWkfLDF5qVbPHKuGATFqRMsxcO8OUKNj0+3WOHB7EHm4Jdw==", "dev": true }, "@commitlint/format": { - "version": "17.4.4", - "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-17.4.4.tgz", - "integrity": "sha512-+IS7vpC4Gd/x+uyQPTAt3hXs5NxnkqAZ3aqrHd5Bx/R9skyCAWusNlNbw3InDbAK6j166D9asQM8fnmYIa+CXQ==", + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-19.3.0.tgz", + "integrity": "sha512-luguk5/aF68HiF4H23ACAfk8qS8AHxl4LLN5oxPc24H+2+JRPsNr1OS3Gaea0CrH7PKhArBMKBz5RX9sA5NtTg==", "dev": true, "requires": { - "@commitlint/types": "^17.4.4", - "chalk": "^4.1.0" + "@commitlint/types": "^19.0.3", + "chalk": "^5.3.0" + }, + "dependencies": { + "chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true + } } }, "@commitlint/is-ignored": { - "version": "17.7.0", - "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-17.7.0.tgz", - "integrity": "sha512-043rA7m45tyEfW7Zv2vZHF++176MLHH9h70fnPoYlB1slKBeKl8BwNIlnPg4xBdRBVNPaCqvXxWswx2GR4c9Hw==", + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-19.2.2.tgz", + "integrity": "sha512-eNX54oXMVxncORywF4ZPFtJoBm3Tvp111tg1xf4zWXGfhBPKpfKG6R+G3G4v5CPlRROXpAOpQ3HMhA9n1Tck1g==", "dev": true, "requires": { - "@commitlint/types": "^17.4.4", - "semver": "7.5.4" + "@commitlint/types": "^19.0.3", + "semver": "^7.6.0" } }, "@commitlint/lint": { - "version": "17.7.0", - "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-17.7.0.tgz", - "integrity": "sha512-TCQihm7/uszA5z1Ux1vw+Nf3yHTgicus/+9HiUQk+kRSQawByxZNESeQoX9ujfVd3r4Sa+3fn0JQAguG4xvvbA==", + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-19.2.2.tgz", + "integrity": "sha512-xrzMmz4JqwGyKQKTpFzlN0dx0TAiT7Ran1fqEBgEmEj+PU98crOFtysJgY+QdeSagx6EDRigQIXJVnfrI0ratA==", "dev": true, "requires": { - "@commitlint/is-ignored": "^17.7.0", - "@commitlint/parse": "^17.7.0", - "@commitlint/rules": "^17.7.0", - "@commitlint/types": "^17.4.4" + "@commitlint/is-ignored": "^19.2.2", + "@commitlint/parse": "^19.0.3", + "@commitlint/rules": "^19.0.3", + "@commitlint/types": "^19.0.3" } }, "@commitlint/load": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-17.7.2.tgz", - "integrity": "sha512-XA7WTnsjHZ4YH6ZYsrnxgLdXzriwMMq+utZUET6spbOEEIPBCDLdOQXS26P+v3TTO4hUHOEhzUquaBv3jbBixw==", + "version": "19.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-19.2.0.tgz", + "integrity": "sha512-XvxxLJTKqZojCxaBQ7u92qQLFMMZc4+p9qrIq/9kJDy8DOrEa7P1yx7Tjdc2u2JxIalqT4KOGraVgCE7eCYJyQ==", "dev": true, "requires": { - "@commitlint/config-validator": "^17.6.7", - "@commitlint/execute-rule": "^17.4.0", - "@commitlint/resolve-extends": "^17.6.7", - "@commitlint/types": "^17.4.4", - "@types/node": "20.5.1", - "chalk": "^4.1.0", - "cosmiconfig": "^8.0.0", - "cosmiconfig-typescript-loader": "^4.0.0", + "@commitlint/config-validator": "^19.0.3", + "@commitlint/execute-rule": "^19.0.0", + "@commitlint/resolve-extends": "^19.1.0", + "@commitlint/types": "^19.0.3", + "chalk": "^5.3.0", + "cosmiconfig": "^9.0.0", + "cosmiconfig-typescript-loader": "^5.0.0", "lodash.isplainobject": "^4.0.6", "lodash.merge": "^4.6.2", - "lodash.uniq": "^4.5.0", - "resolve-from": "^5.0.0", - "ts-node": "^10.8.1", - "typescript": "^4.6.4 || ^5.0.0" + "lodash.uniq": "^4.5.0" }, "dependencies": { - "@types/node": { - "version": "20.5.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.1.tgz", - "integrity": "sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==", - "dev": true - }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true + }, "cosmiconfig": { - "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", "dev": true, "requires": { + "env-paths": "^2.2.1", "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", - "parse-json": "^5.2.0", - "path-type": "^4.0.0" + "parse-json": "^5.2.0" + } + }, + "cosmiconfig-typescript-loader": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-5.0.0.tgz", + "integrity": "sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==", + "dev": true, + "requires": { + "jiti": "^1.19.1" } }, "js-yaml": { @@ -17940,80 +17989,209 @@ "requires": { "argparse": "^2.0.1" } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true } } }, "@commitlint/message": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-17.4.2.tgz", - "integrity": "sha512-3XMNbzB+3bhKA1hSAWPCQA3lNxR4zaeQAQcHj0Hx5sVdO6ryXtgUBGGv+1ZCLMgAPRixuc6en+iNAzZ4NzAa8Q==", + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-19.0.0.tgz", + "integrity": "sha512-c9czf6lU+9oF9gVVa2lmKaOARJvt4soRsVmbR7Njwp9FpbBgste5i7l/2l5o8MmbwGh4yE1snfnsy2qyA2r/Fw==", "dev": true }, "@commitlint/parse": { - "version": "17.7.0", - "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-17.7.0.tgz", - "integrity": "sha512-dIvFNUMCUHqq5Abv80mIEjLVfw8QNuA4DS7OWip4pcK/3h5wggmjVnlwGCDvDChkw2TjK1K6O+tAEV78oxjxag==", + "version": "19.0.3", + "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-19.0.3.tgz", + "integrity": "sha512-Il+tNyOb8VDxN3P6XoBBwWJtKKGzHlitEuXA5BP6ir/3loWlsSqDr5aecl6hZcC/spjq4pHqNh0qPlfeWu38QA==", "dev": true, "requires": { - "@commitlint/types": "^17.4.4", - "conventional-changelog-angular": "^6.0.0", - "conventional-commits-parser": "^4.0.0" + "@commitlint/types": "^19.0.3", + "conventional-changelog-angular": "^7.0.0", + "conventional-commits-parser": "^5.0.0" }, "dependencies": { "conventional-changelog-angular": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz", - "integrity": "sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz", + "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==", "dev": true, "requires": { "compare-func": "^2.0.0" } }, "conventional-commits-parser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz", - "integrity": "sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz", + "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==", "dev": true, "requires": { - "is-text-path": "^1.0.1", + "is-text-path": "^2.0.0", "JSONStream": "^1.3.5", - "meow": "^8.1.2", - "split2": "^3.2.2" + "meow": "^12.0.1", + "split2": "^4.0.0" } + }, + "is-text-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz", + "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==", + "dev": true, + "requires": { + "text-extensions": "^2.0.0" + } + }, + "meow": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", + "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", + "dev": true + }, + "split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true + }, + "text-extensions": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz", + "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==", + "dev": true } } }, "@commitlint/read": { - "version": "17.5.1", - "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-17.5.1.tgz", - "integrity": "sha512-7IhfvEvB//p9aYW09YVclHbdf1u7g7QhxeYW9ZHSO8Huzp8Rz7m05aCO1mFG7G8M+7yfFnXB5xOmG18brqQIBg==", + "version": "19.2.1", + "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-19.2.1.tgz", + "integrity": "sha512-qETc4+PL0EUv7Q36lJbPG+NJiBOGg7SSC7B5BsPWOmei+Dyif80ErfWQ0qXoW9oCh7GTpTNRoaVhiI8RbhuaNw==", "dev": true, "requires": { - "@commitlint/top-level": "^17.4.0", - "@commitlint/types": "^17.4.4", - "fs-extra": "^11.0.0", - "git-raw-commits": "^2.0.11", - "minimist": "^1.2.6" + "@commitlint/top-level": "^19.0.0", + "@commitlint/types": "^19.0.3", + "execa": "^8.0.1", + "git-raw-commits": "^4.0.0", + "minimist": "^1.2.8" + }, + "dependencies": { + "dargs": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-8.1.0.tgz", + "integrity": "sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==", + "dev": true + }, + "execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + } + }, + "get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true + }, + "git-raw-commits": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-4.0.0.tgz", + "integrity": "sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==", + "dev": true, + "requires": { + "dargs": "^8.0.0", + "meow": "^12.0.1", + "split2": "^4.0.0" + } + }, + "human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true + }, + "is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true + }, + "meow": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", + "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", + "dev": true + }, + "mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true + }, + "npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "requires": { + "path-key": "^4.0.0" + } + }, + "onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "requires": { + "mimic-fn": "^4.0.0" + } + }, + "path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true + }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true + }, + "split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true + }, + "strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true + } } }, "@commitlint/resolve-extends": { - "version": "17.6.7", - "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-17.6.7.tgz", - "integrity": "sha512-PfeoAwLHtbOaC9bGn/FADN156CqkFz6ZKiVDMjuC2N5N0740Ke56rKU7Wxdwya8R8xzLK9vZzHgNbuGhaOVKIg==", + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-19.1.0.tgz", + "integrity": "sha512-z2riI+8G3CET5CPgXJPlzftH+RiWYLMYv4C9tSLdLXdr6pBNimSKukYP9MS27ejmscqCTVA4almdLh0ODD2KYg==", "dev": true, "requires": { - "@commitlint/config-validator": "^17.6.7", - "@commitlint/types": "^17.4.4", - "import-fresh": "^3.0.0", + "@commitlint/config-validator": "^19.0.3", + "@commitlint/types": "^19.0.3", + "global-directory": "^4.0.1", + "import-meta-resolve": "^4.0.0", "lodash.mergewith": "^4.6.2", - "resolve-from": "^5.0.0", - "resolve-global": "^1.0.0" + "resolve-from": "^5.0.0" }, "dependencies": { "resolve-from": { @@ -18025,79 +18203,180 @@ } }, "@commitlint/rules": { - "version": "17.7.0", - "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-17.7.0.tgz", - "integrity": "sha512-J3qTh0+ilUE5folSaoK91ByOb8XeQjiGcdIdiB/8UT1/Rd1itKo0ju/eQVGyFzgTMYt8HrDJnGTmNWwcMR1rmA==", + "version": "19.0.3", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-19.0.3.tgz", + "integrity": "sha512-TspKb9VB6svklxNCKKwxhELn7qhtY1rFF8ls58DcFd0F97XoG07xugPjjbVnLqmMkRjZDbDIwBKt9bddOfLaPw==", "dev": true, "requires": { - "@commitlint/ensure": "^17.6.7", - "@commitlint/message": "^17.4.2", - "@commitlint/to-lines": "^17.4.0", - "@commitlint/types": "^17.4.4", - "execa": "^5.0.0" + "@commitlint/ensure": "^19.0.3", + "@commitlint/message": "^19.0.0", + "@commitlint/to-lines": "^19.0.0", + "@commitlint/types": "^19.0.3", + "execa": "^8.0.1" + }, + "dependencies": { + "execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + } + }, + "get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true + }, + "human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true + }, + "is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true + }, + "mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true + }, + "npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "requires": { + "path-key": "^4.0.0" + } + }, + "onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "requires": { + "mimic-fn": "^4.0.0" + } + }, + "path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true + }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true + }, + "strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true + } } }, "@commitlint/to-lines": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-17.4.0.tgz", - "integrity": "sha512-LcIy/6ZZolsfwDUWfN1mJ+co09soSuNASfKEU5sCmgFCvX5iHwRYLiIuoqXzOVDYOy7E7IcHilr/KS0e5T+0Hg==", + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-19.0.0.tgz", + "integrity": "sha512-vkxWo+VQU5wFhiP9Ub9Sre0FYe019JxFikrALVoD5UGa8/t3yOJEpEhxC5xKiENKKhUkTpEItMTRAjHw2SCpZw==", "dev": true }, "@commitlint/top-level": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-17.4.0.tgz", - "integrity": "sha512-/1loE/g+dTTQgHnjoCy0AexKAEFyHsR2zRB4NWrZ6lZSMIxAhBJnmCqwao7b4H8888PsfoTBCLBYIw8vGnej8g==", + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-19.0.0.tgz", + "integrity": "sha512-KKjShd6u1aMGNkCkaX4aG1jOGdn7f8ZI8TR1VEuNqUOjWTOdcDSsmglinglJ18JTjuBX5I1PtjrhQCRcixRVFQ==", "dev": true, "requires": { - "find-up": "^5.0.0" + "find-up": "^7.0.0" }, "dependencies": { "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz", + "integrity": "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==", "dev": true, "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" + "locate-path": "^7.2.0", + "path-exists": "^5.0.0", + "unicorn-magic": "^0.1.0" } }, "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", "dev": true, "requires": { - "p-locate": "^5.0.0" + "p-locate": "^6.0.0" } }, "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", "dev": true, "requires": { - "yocto-queue": "^0.1.0" + "yocto-queue": "^1.0.0" } }, "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", "dev": true, "requires": { - "p-limit": "^3.0.2" + "p-limit": "^4.0.0" } + }, + "path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true + }, + "yocto-queue": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", + "dev": true } } }, "@commitlint/types": { - "version": "17.4.4", - "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-17.4.4.tgz", - "integrity": "sha512-amRN8tRLYOsxRr6mTnGGGvB5EmW/4DDjLMgiwK3CCVEmN6Sr/6xePGEpWaspKkckILuUORCwe6VfDBw6uj4axQ==", + "version": "19.0.3", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-19.0.3.tgz", + "integrity": "sha512-tpyc+7i6bPG9mvaBbtKUeghfyZSDgWquIDfMgqYtTbmZ9Y9VzEm2je9EYcQ0aoz5o7NvGS+rcDec93yO08MHYA==", "dev": true, "requires": { - "chalk": "^4.1.0" + "@types/conventional-commits-parser": "^5.0.0", + "chalk": "^5.3.0" + }, + "dependencies": { + "chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true + } } }, "@comunica/actor-abstract-mediatyped": { @@ -20626,16 +20905,25 @@ } }, "@es-joy/jsdoccomment": { - "version": "0.42.0", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.42.0.tgz", - "integrity": "sha512-R1w57YlVA6+YE01wch3GPYn6bCsrOV3YW/5oGGE2tmX6JcL9Nr+b5IikrjMPF+v9CV3ay+obImEdsDhovhJrzw==", + "version": "0.43.1", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.43.1.tgz", + "integrity": "sha512-I238eDtOolvCuvtxrnqtlBaw0BwdQuYqK7eA6XIonicMdOOOb75mqdIzkGDUbS04+1Di007rgm9snFRNeVrOog==", "dev": true, "requires": { + "@types/eslint": "^8.56.5", + "@types/estree": "^1.0.5", + "@typescript-eslint/types": "^7.2.0", "comment-parser": "1.4.1", "esquery": "^1.5.0", "jsdoc-type-pratt-parser": "~4.0.0" }, "dependencies": { + "@typescript-eslint/types": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", + "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", + "dev": true + }, "comment-parser": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", @@ -20654,9 +20942,9 @@ } }, "@eslint-community/regexpp": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.9.1.tgz", - "integrity": "sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==", + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", "dev": true }, "@eslint/eslintrc": { @@ -20664,6 +20952,7 @@ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, + "peer": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -20680,13 +20969,15 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "dev": true, + "peer": true }, "globals": { "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, + "peer": true, "requires": { "type-fest": "^0.20.2" } @@ -20696,6 +20987,7 @@ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, + "peer": true, "requires": { "argparse": "^2.0.1" } @@ -20704,7 +20996,8 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true + "dev": true, + "peer": true } } }, @@ -21111,6 +21404,18 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, + "@jsdevtools/ez-spawn": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@jsdevtools/ez-spawn/-/ez-spawn-3.0.4.tgz", + "integrity": "sha512-f5DRIOZf7wxogefH03RjMPMdBF7ADTWUMoOs9kaJo06EfwF+aFhMZMDZxHg/Xe12hptN9xoZjGso2fdjapBRIA==", + "dev": true, + "requires": { + "call-me-maybe": "^1.0.1", + "cross-spawn": "^7.0.3", + "string-argv": "^0.3.1", + "type-detect": "^4.0.8" + } + }, "@koa/cors": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@koa/cors/-/cors-5.0.0.tgz", @@ -21172,6 +21477,12 @@ "fastq": "^1.6.0" } }, + "@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true + }, "@rdfjs/data-model": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/@rdfjs/data-model/-/data-model-1.3.4.tgz", @@ -21225,6 +21536,15 @@ "xmlchars": "^2.2.0" } }, + "@shikijs/core": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.10.3.tgz", + "integrity": "sha512-D45PMaBaeDHxww+EkcDQtDAtzv00Gcsp72ukBtaLSmqRvh0WgGMq3Al0rl1QQBZfuneO75NXMIzEZGFitThWbg==", + "dev": true, + "requires": { + "@types/hast": "^3.0.4" + } + }, "@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -21285,49 +21605,61 @@ } }, "@stylistic/eslint-plugin": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-1.7.0.tgz", - "integrity": "sha512-ThMUjGIi/jeWYNvOdjZkoLw1EOVs0tEuKXDgWvTn8uWaEz55HuPlajKxjKLpv19C+qRDbKczJfzUODfCdME53A==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-2.3.0.tgz", + "integrity": "sha512-rtiz6u5gRyyEZp36FcF1/gHJbsbT3qAgXZ1qkad6Nr/xJ9wrSJkiSFFQhpYVTIZ7FJNRJurEcumZDCwN9dEI4g==", "dev": true, "requires": { - "@stylistic/eslint-plugin-js": "1.7.0", - "@stylistic/eslint-plugin-jsx": "1.7.0", - "@stylistic/eslint-plugin-plus": "1.7.0", - "@stylistic/eslint-plugin-ts": "1.7.0", - "@types/eslint": "^8.56.2" + "@stylistic/eslint-plugin-js": "2.3.0", + "@stylistic/eslint-plugin-jsx": "2.3.0", + "@stylistic/eslint-plugin-plus": "2.3.0", + "@stylistic/eslint-plugin-ts": "2.3.0", + "@types/eslint": "^8.56.10" } }, "@stylistic/eslint-plugin-js": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-1.7.0.tgz", - "integrity": "sha512-PN6On/+or63FGnhhMKSQfYcWutRlzOiYlVdLM6yN7lquoBTqUJHYnl4TA4MHwiAt46X5gRxDr1+xPZ1lOLcL+Q==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-2.3.0.tgz", + "integrity": "sha512-lQwoiYb0Fs6Yc5QS3uT8+T9CPKK2Eoxc3H8EnYJgM26v/DgtW+1lvy2WNgyBflU+ThShZaHm3a6CdD9QeKx23w==", "dev": true, "requires": { - "@types/eslint": "^8.56.2", + "@types/eslint": "^8.56.10", "acorn": "^8.11.3", - "escape-string-regexp": "^4.0.0", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1" + "eslint-visitor-keys": "^4.0.0", + "espree": "^10.0.1" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "dev": true + }, + "espree": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", + "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", + "dev": true, + "requires": { + "acorn": "^8.12.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.0.0" + } + } } }, "@stylistic/eslint-plugin-jsx": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-jsx/-/eslint-plugin-jsx-1.7.0.tgz", - "integrity": "sha512-BACdBwXakQvjYIST5N2WWhRbvhRsIxa/F59BiZol+0IH4FSmDXhie7v/yaxDIIA9CbfElzOmIA5nWNYTVXcnwQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-jsx/-/eslint-plugin-jsx-2.3.0.tgz", + "integrity": "sha512-tsQ0IEKB195H6X9A4iUSgLLLKBc8gUBWkBIU8tp1/3g2l8stu+PtMQVV/VmK1+3bem5FJCyvfcZIQ/WF1fsizA==", "dev": true, "requires": { - "@stylistic/eslint-plugin-js": "^1.7.0", - "@types/eslint": "^8.56.2", + "@stylistic/eslint-plugin-js": "^2.3.0", + "@types/eslint": "^8.56.10", "estraverse": "^5.3.0", - "picomatch": "^4.0.1" + "picomatch": "^4.0.2" }, "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, "picomatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", @@ -21337,178 +21669,24 @@ } }, "@stylistic/eslint-plugin-plus": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-plus/-/eslint-plugin-plus-1.7.0.tgz", - "integrity": "sha512-AabDw8sXsc70Ydx3qnbeTlRHZnIwY6UKEenBPURPhY3bfYWX+/pDpZH40HkOu94v8D0DUrocPkeeEUxl4e0JDg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-plus/-/eslint-plugin-plus-2.3.0.tgz", + "integrity": "sha512-xboPWGUU5yaPlR+WR57GwXEuY4PSlPqA0C3IdNA/+1o2MuBi95XgDJcZiJ9N+aXsqBXAPIpFFb+WQ7QEHo4f7g==", "dev": true, "requires": { - "@types/eslint": "^8.56.2", - "@typescript-eslint/utils": "^6.21.0" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", - "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0" - } - }, - "@typescript-eslint/types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", - "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", - "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/utils": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", - "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "semver": "^7.5.4" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", - "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.21.0", - "eslint-visitor-keys": "^3.4.1" - } - }, - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } + "@types/eslint": "^8.56.10", + "@typescript-eslint/utils": "^7.12.0" } }, "@stylistic/eslint-plugin-ts": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-ts/-/eslint-plugin-ts-1.7.0.tgz", - "integrity": "sha512-QsHv98mmW1xaucVYQTyLDgEpybPJ/6jPPxVBrIchntWWwj74xCWKUiw79hu+TpYj/Pbhd9rkqJYLNq3pQGYuyA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-ts/-/eslint-plugin-ts-2.3.0.tgz", + "integrity": "sha512-wqOR38/uz/0XPnHX68ftp8sNMSAqnYGjovOTN7w00xnjS6Lxr3Sk7q6AaxWWqbMvOj7V2fQiMC5HWAbTruJsCg==", "dev": true, "requires": { - "@stylistic/eslint-plugin-js": "1.7.0", - "@types/eslint": "^8.56.2", - "@typescript-eslint/utils": "^6.21.0" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", - "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0" - } - }, - "@typescript-eslint/types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", - "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", - "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/utils": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", - "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "semver": "^7.5.4" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", - "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.21.0", - "eslint-visitor-keys": "^3.4.1" - } - }, - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } + "@stylistic/eslint-plugin-js": "2.3.0", + "@types/eslint": "^8.56.10", + "@typescript-eslint/utils": "^7.12.0" } }, "@szmarczak/http-timer": { @@ -21638,6 +21816,15 @@ "resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.3.tgz", "integrity": "sha512-P1bffQfhD3O4LW0ioENXUhZ9OIa0Zn+P7M+pWgkCKaT53wVLSq0mrKksCID/FGHpFhRSxRGhgrQmfhRuzwtKdg==" }, + "@types/conventional-commits-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz", + "integrity": "sha512-loB369iXNmAZglwWATL+WRe+CRMmmBPtpolYzIebFaX4YA3x+BEfLqhUAV9WanycKI3TG1IMr5bMJDajDKLlUQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/cookie": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.5.2.tgz", @@ -21682,9 +21869,9 @@ } }, "@types/eslint": { - "version": "8.56.6", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.6.tgz", - "integrity": "sha512-ymwc+qb1XkjT/gfoQwxIeHZ6ixH23A+tCT2ADSA/DPVKzAjwYkTXBMCQ/f6fe4wEa85Lhp26VPeUxI7wMhAi7A==", + "version": "8.56.10", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", + "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", "dev": true, "requires": { "@types/estree": "*", @@ -21736,6 +21923,15 @@ "@types/node": "*" } }, + "@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dev": true, + "requires": { + "@types/unist": "*" + } + }, "@types/http-assert": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.1.tgz", @@ -22240,13 +22436,31 @@ } }, "@typescript-eslint/scope-manager": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", + "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", "dev": true, "requires": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1" + }, + "dependencies": { + "@typescript-eslint/types": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", + "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", + "dev": true + }, + "@typescript-eslint/visitor-keys": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", + "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "7.16.1", + "eslint-visitor-keys": "^3.4.3" + } + } } }, "@typescript-eslint/type-utils": { @@ -22353,19 +22567,67 @@ } }, "@typescript-eslint/utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", - "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.1.tgz", + "integrity": "sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==", "dev": true, "requires": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/typescript-estree": "7.16.1" + }, + "dependencies": { + "@typescript-eslint/types": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", + "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", + "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", + "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "7.16.1", + "eslint-visitor-keys": "^3.4.3" + } + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } } }, "@typescript-eslint/visitor-keys": { @@ -22386,63 +22648,63 @@ "peer": true }, "@vue/compiler-core": { - "version": "3.4.21", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.21.tgz", - "integrity": "sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==", + "version": "3.4.32", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.32.tgz", + "integrity": "sha512-8tCVWkkLe/QCWIsrIvExUGnhYCAOroUs5dzhSoKL5w4MJS8uIYiou+pOPSVIOALOQ80B0jBs+Ri+kd5+MBnCDw==", "dev": true, "peer": true, "requires": { - "@babel/parser": "^7.23.9", - "@vue/shared": "3.4.21", + "@babel/parser": "^7.24.7", + "@vue/shared": "3.4.32", "entities": "^4.5.0", "estree-walker": "^2.0.2", - "source-map-js": "^1.0.2" + "source-map-js": "^1.2.0" } }, "@vue/compiler-dom": { - "version": "3.4.21", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.21.tgz", - "integrity": "sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==", + "version": "3.4.32", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.32.tgz", + "integrity": "sha512-PbSgt9KuYo4fyb90dynuPc0XFTfFPs3sCTbPLOLlo+PrUESW1gn/NjSsUvhR+mI2AmmEzexwYMxbHDldxSOr2A==", "dev": true, "peer": true, "requires": { - "@vue/compiler-core": "3.4.21", - "@vue/shared": "3.4.21" + "@vue/compiler-core": "3.4.32", + "@vue/shared": "3.4.32" } }, "@vue/compiler-sfc": { - "version": "3.4.21", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.21.tgz", - "integrity": "sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==", + "version": "3.4.32", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.32.tgz", + "integrity": "sha512-STy9im/WHfaguJnfKjjVpMHukxHUrOKjm2vVCxiojQJyo3Sb6Os8SMXBr/MI+ekpstEGkDONfqAQoSbZhspLYw==", "dev": true, "peer": true, "requires": { - "@babel/parser": "^7.23.9", - "@vue/compiler-core": "3.4.21", - "@vue/compiler-dom": "3.4.21", - "@vue/compiler-ssr": "3.4.21", - "@vue/shared": "3.4.21", + "@babel/parser": "^7.24.7", + "@vue/compiler-core": "3.4.32", + "@vue/compiler-dom": "3.4.32", + "@vue/compiler-ssr": "3.4.32", + "@vue/shared": "3.4.32", "estree-walker": "^2.0.2", - "magic-string": "^0.30.7", - "postcss": "^8.4.35", - "source-map-js": "^1.0.2" + "magic-string": "^0.30.10", + "postcss": "^8.4.39", + "source-map-js": "^1.2.0" } }, "@vue/compiler-ssr": { - "version": "3.4.21", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.21.tgz", - "integrity": "sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==", + "version": "3.4.32", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.32.tgz", + "integrity": "sha512-nyu/txTecF6DrxLrpLcI34xutrvZPtHPBj9yRoPxstIquxeeyywXpYZrQMsIeDfBhlw1abJb9CbbyZvDw2kjdg==", "dev": true, "peer": true, "requires": { - "@vue/compiler-dom": "3.4.21", - "@vue/shared": "3.4.21" + "@vue/compiler-dom": "3.4.32", + "@vue/shared": "3.4.32" } }, "@vue/shared": { - "version": "3.4.21", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.21.tgz", - "integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==", + "version": "3.4.32", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.32.tgz", + "integrity": "sha512-ep4mF1IVnX/pYaNwxwOpJHyBtOMKWoKZMbnUyd+z0udqIxLUh7YCCd/JfDna8aUrmnG9SFORyIq2HzEATRrQsg==", "dev": true, "peer": true }, @@ -22470,9 +22732,9 @@ } }, "acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", "dev": true }, "acorn-jsx": { @@ -22528,12 +22790,6 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, - "ansi-sequence-parser": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.0.tgz", - "integrity": "sha512-lEm8mt52to2fT8GhciPCGeCXACSz2UwIN4X2e2LJSnZ5uAbn2/dsYdOmUXq0AtWS5cpAupysIneExOgH0Vd2TQ==", - "dev": true - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -22817,15 +23073,6 @@ "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", "dev": true }, - "builtins": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", - "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", - "dev": true, - "requires": { - "semver": "^7.0.0" - } - }, "bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -22870,6 +23117,12 @@ "set-function-length": "^1.1.1" } }, + "call-me-maybe": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", + "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", + "dev": true + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -23714,9 +23967,9 @@ } }, "core-js-compat": { - "version": "3.36.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.1.tgz", - "integrity": "sha512-Dk997v9ZCt3X/npqzyGdTlq6t7lDBhZwGvV94PKzDArjp7BTRm7WlDAXYd/OWdeFHO8OChQYRJNJvUCqCbrtKA==", + "version": "3.37.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", + "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", "dev": true, "requires": { "browserslist": "^4.23.0" @@ -23750,13 +24003,6 @@ "yaml": "^1.10.0" } }, - "cosmiconfig-typescript-loader": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.4.0.tgz", - "integrity": "sha512-BabizFdC3wBHhbI4kJh0VkQP9GkBfoHPydD0COMce1nJ1kJAB3F2TmJ/I7diULBKtmEWSwEbuN/KDtgnmUUVmw==", - "dev": true, - "requires": {} - }, "create-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", @@ -23816,9 +24062,9 @@ "dev": true }, "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "requires": { "ms": "2.1.2" }, @@ -24124,11 +24370,27 @@ "once": "^1.4.0" } }, + "enhanced-resolve": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", + "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, "entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" }, + "env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true + }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -24146,6 +24408,12 @@ } } }, + "es-module-lexer": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "dev": true + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -24215,24 +24483,6 @@ "dev": true, "peer": true }, - "eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "peer": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "peer": true - }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -24314,83 +24564,32 @@ } }, "eslint-compat-utils": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.0.tgz", - "integrity": "sha512-dc6Y8tzEcSYZMHa+CMPLi/hyo1FzNeonbhJL7Ol0ccuKQkwopJcJBA9YL/xmMTLU1eKigXo9vj9nALElWYSowg==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", + "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", "dev": true, "requires": { "semver": "^7.5.4" } }, "eslint-config-flat-gitignore": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/eslint-config-flat-gitignore/-/eslint-config-flat-gitignore-0.1.3.tgz", - "integrity": "sha512-oQD+dEZv3RThN60tFqGFt+NJcO1DmssUcP+T/nlX+ZzEoEvVUYH0GU9X/VlmDXsbMsS9mONI1HrlxLgtKojw7w==", + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eslint-config-flat-gitignore/-/eslint-config-flat-gitignore-0.1.8.tgz", + "integrity": "sha512-OEUbS2wzzYtUfshjOqzFo4Bl4lHykXUdM08TCnYNl7ki+niW4Q1R0j0FDFDr0vjVsI5ZFOz5LvluxOP+Ew+dYw==", "dev": true, "requires": { - "find-up": "^7.0.0", + "find-up-simple": "^1.0.0", "parse-gitignore": "^2.0.0" - }, - "dependencies": { - "find-up": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz", - "integrity": "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==", - "dev": true, - "requires": { - "locate-path": "^7.2.0", - "path-exists": "^5.0.0", - "unicorn-magic": "^0.1.0" - } - }, - "locate-path": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", - "dev": true, - "requires": { - "p-locate": "^6.0.0" - } - }, - "p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", - "dev": true, - "requires": { - "yocto-queue": "^1.0.0" - } - }, - "p-locate": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", - "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", - "dev": true, - "requires": { - "p-limit": "^4.0.0" - } - }, - "path-exists": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", - "dev": true - }, - "yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", - "dev": true - } } }, "eslint-flat-config-utils": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/eslint-flat-config-utils/-/eslint-flat-config-utils-0.1.2.tgz", - "integrity": "sha512-NfeUJrbARSHGux2no/zz+YOjfMuPXpedcxRTqov3mlx9PJV2CYAJEj2EjbNSEyHMXQwNCfTtQVZXMSiktQTcpA==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/eslint-flat-config-utils/-/eslint-flat-config-utils-0.2.5.tgz", + "integrity": "sha512-iO+yLZtC/LKgACerkpvsZ6NoRVB2sxT04mOpnNcEM1aTwKy+6TsT46PUvrML4y2uVBS6I67hRCd2JiKAPaL/Uw==", "dev": true, "requires": { - "@types/eslint": "^8.56.6" + "@types/eslint": "^8.56.10", + "pathe": "^1.1.2" } }, "eslint-import-resolver-node": { @@ -24423,21 +24622,32 @@ "requires": {} }, "eslint-plugin-antfu": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-antfu/-/eslint-plugin-antfu-2.1.2.tgz", - "integrity": "sha512-s7ZTOM3uq0iqpp6gF0UEotnvup7f2PHBUftCytLZX0+6C9j9KadKZQh6bVVngAyFgsmeD9+gcBopOYLClb2oDg==", + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-antfu/-/eslint-plugin-antfu-2.3.4.tgz", + "integrity": "sha512-5RIjJpBK1tuNHuLyFyZ90/iW9s439dP1u2cxA4dH70djx9sKq1CqI+O6Q95aVjgFNTDtQzSC9uYdAD5uEEKciQ==", "dev": true, - "requires": {} + "requires": { + "@antfu/utils": "^0.7.10" + } + }, + "eslint-plugin-command": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-command/-/eslint-plugin-command-0.2.3.tgz", + "integrity": "sha512-1bBYNfjZg60N2ZpLV5ATYSYyueIJ+zl5yKrTs0UFDdnyu07dNSZ7Xplnc+Wb6SXTdc1sIaoIrnuyhvztcltX6A==", + "dev": true, + "requires": { + "@es-joy/jsdoccomment": "^0.43.0" + } }, "eslint-plugin-es-x": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.6.0.tgz", - "integrity": "sha512-I0AmeNgevgaTR7y2lrVCJmGYF0rjoznpDvqV/kIkZSZbZ8Rw3eu4cGlvBBULScfkSOCzqKbff5LR4CNrV7mZHA==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.8.0.tgz", + "integrity": "sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.1.2", - "@eslint-community/regexpp": "^4.6.0", - "eslint-compat-utils": "^0.5.0" + "@eslint-community/regexpp": "^4.11.0", + "eslint-compat-utils": "^0.5.1" } }, "eslint-plugin-eslint-comments": { @@ -24459,114 +24669,23 @@ } }, "eslint-plugin-import-x": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-0.4.4.tgz", - "integrity": "sha512-+6vns/GOAL0K5tzQ7ZescD2vFBz3cICZqT9R5CQ9h/bTA+Jkae8DuHT2gYhFb2K97kzsLnmPmKM51Iq9g6vTRA==", + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-0.5.3.tgz", + "integrity": "sha512-hJ/wkMcsLQXAZL3+txXIDpbW5cqwdm1rLTqV4VRY03aIbzE3zWE7rPZKW6Gzf7xyl1u3V1iYC6tOG77d9NF4GQ==", "dev": true, "requires": { - "@typescript-eslint/utils": "^5.62.0", + "@typescript-eslint/utils": "^7.4.0", "debug": "^4.3.4", "doctrine": "^3.0.0", - "eslint-compat-utils": "^0.5.0", "eslint-import-resolver-node": "^0.3.9", "get-tsconfig": "^4.7.3", "is-glob": "^4.0.3", "minimatch": "^9.0.3", - "semver": "^7.6.0" + "semver": "^7.6.0", + "stable-hash": "^0.0.4", + "tslib": "^2.6.2" }, "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - }, - "semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } - } - }, - "eslint-plugin-jest": { - "version": "28.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.6.0.tgz", - "integrity": "sha512-YG28E1/MIKwnz+e2H7VwYPzHUYU4aMa19w0yGcwXnnmJH6EfgHahTJ2un3IyraUxNfnz/KUhJAFXNNwWPo12tg==", - "dev": true, - "requires": { - "@typescript-eslint/utils": "^6.0.0 || ^7.0.0" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", - "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1" - } - }, - "@typescript-eslint/types": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", - "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", - "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - } - }, - "@typescript-eslint/utils": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.1.tgz", - "integrity": "sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.16.1", - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/typescript-estree": "7.16.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", - "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "7.16.1", - "eslint-visitor-keys": "^3.4.3" - } - }, "brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -24585,46 +24704,58 @@ "brace-expansion": "^2.0.1" } }, - "semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", "dev": true } } }, - "eslint-plugin-jsdoc": { - "version": "48.2.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.2.tgz", - "integrity": "sha512-S0Gk+rpT5w/ephKCncUY7kUsix9uE4B9XI8D/fS1/26d8okE+vZsuG1IvIt4B6sJUdQqsnzi+YXfmh+HJG11CA==", + "eslint-plugin-jest": { + "version": "28.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.6.0.tgz", + "integrity": "sha512-YG28E1/MIKwnz+e2H7VwYPzHUYU4aMa19w0yGcwXnnmJH6EfgHahTJ2un3IyraUxNfnz/KUhJAFXNNwWPo12tg==", "dev": true, "requires": { - "@es-joy/jsdoccomment": "~0.42.0", + "@typescript-eslint/utils": "^6.0.0 || ^7.0.0" + } + }, + "eslint-plugin-jsdoc": { + "version": "48.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.7.0.tgz", + "integrity": "sha512-5oiVf7Y+ZxGYQTlLq81X72n+S+hjvS/u0upAdbpPEeaIZILK3MKN8lm/6QqKioBjm/qZ0B5XpMQUtc2fUkqXAg==", + "dev": true, + "requires": { + "@es-joy/jsdoccomment": "~0.46.0", "are-docs-informative": "^0.0.2", "comment-parser": "1.4.1", - "debug": "^4.3.4", + "debug": "^4.3.5", "escape-string-regexp": "^4.0.0", - "esquery": "^1.5.0", - "is-builtin-module": "^3.2.1", - "semver": "^7.6.0", - "spdx-expression-parse": "^4.0.0" + "esquery": "^1.6.0", + "parse-imports": "^2.1.1", + "semver": "^7.6.2", + "spdx-expression-parse": "^4.0.0", + "synckit": "^0.9.0" }, "dependencies": { + "@es-joy/jsdoccomment": { + "version": "0.46.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.46.0.tgz", + "integrity": "sha512-C3Axuq1xd/9VqFZpW4YAzOx5O9q/LP46uIQy/iNDpHG3fmPa6TBtvfglMCs3RBiBxAIi0Go97r8+jvTt55XMyQ==", + "dev": true, + "requires": { + "comment-parser": "1.4.1", + "esquery": "^1.6.0", + "jsdoc-type-pratt-parser": "~4.0.0" + } + }, "comment-parser": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", "dev": true }, - "semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, "spdx-expression-parse": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", @@ -24638,9 +24769,9 @@ } }, "eslint-plugin-jsonc": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsonc/-/eslint-plugin-jsonc-2.14.1.tgz", - "integrity": "sha512-Tei6G4N7pZulP5MHi0EIdtseiCqUPkDMd0O8Zrw4muMIlsjJ5/B9X+U3Pfo6B7l0mTL9LN9FwuWT70dRJ6z7tg==", + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsonc/-/eslint-plugin-jsonc-2.16.0.tgz", + "integrity": "sha512-Af/ZL5mgfb8FFNleH6KlO4/VdmDuTqmM+SPnWcdoWywTetv7kq+vQe99UyQb9XO3b0OWLVuTH7H0d/PXYCMdSg==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", @@ -24650,50 +24781,67 @@ "jsonc-eslint-parser": "^2.0.4", "natural-compare": "^1.4.0", "synckit": "^0.6.0" + }, + "dependencies": { + "synckit": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.6.2.tgz", + "integrity": "sha512-Vhf+bUa//YSTYKseDiiEuQmhGCoIF3CVBhunm3r/DQnYiGT4JssmnKQc44BIyOZRK2pKjXXAgbhfmbeoC9CJpA==", + "dev": true, + "requires": { + "tslib": "^2.3.1" + } + }, + "tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "dev": true + } } }, "eslint-plugin-markdown": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-markdown/-/eslint-plugin-markdown-4.0.1.tgz", - "integrity": "sha512-5/MnGvYU0i8MbHH5cg8S+Vl3DL+bqRNYshk1xUO86DilNBaxtTkhH+5FD0/yO03AmlI6+lfNFdk2yOw72EPzpA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-markdown/-/eslint-plugin-markdown-5.1.0.tgz", + "integrity": "sha512-SJeyKko1K6GwI0AN6xeCDToXDkfKZfXcexA6B+O2Wr2btUS9GrC+YgwSyVli5DJnctUHjFXcQ2cqTaAmVoLi2A==", "dev": true, "requires": { "mdast-util-from-markdown": "^0.8.5" } }, "eslint-plugin-n": { - "version": "16.6.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.6.2.tgz", - "integrity": "sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==", + "version": "17.9.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-17.9.0.tgz", + "integrity": "sha512-CPSaXDXdrT4nsrOrO4mT4VB6FMUkoySRkHWuuJJHVqsIEjIeZgMY1H7AzSwPbDScikBmLN82KeM1u7ixV7PzGg==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", - "builtins": "^5.0.1", + "enhanced-resolve": "^5.17.0", "eslint-plugin-es-x": "^7.5.0", "get-tsconfig": "^4.7.0", - "globals": "^13.24.0", + "globals": "^15.0.0", "ignore": "^5.2.4", - "is-builtin-module": "^3.2.1", - "is-core-module": "^2.12.1", - "minimatch": "^3.1.2", - "resolve": "^1.22.2", + "minimatch": "^9.0.0", "semver": "^7.5.3" }, "dependencies": { - "globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "requires": { - "type-fest": "^0.20.2" + "balanced-match": "^1.0.0" } }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true + "minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } } } }, @@ -24704,84 +24852,16 @@ "dev": true }, "eslint-plugin-perfectionist": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-perfectionist/-/eslint-plugin-perfectionist-2.7.0.tgz", - "integrity": "sha512-RpSMc0T0DT9DlOj4APzwlAjCqQMxFdsIYlupe73eDkKLn1mMK7fVw2z3nj2y822szKOpvHA7bDa56ySOlr4GXw==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-perfectionist/-/eslint-plugin-perfectionist-2.11.0.tgz", + "integrity": "sha512-XrtBtiu5rbQv88gl+1e2RQud9te9luYNvKIgM9emttQ2zutHPzY/AQUucwxscDKV4qlTkvLTxjOFvxqeDpPorw==", "dev": true, "requires": { - "@typescript-eslint/utils": "^6.13.0", + "@typescript-eslint/utils": "^6.13.0 || ^7.0.0", "minimatch": "^9.0.3", "natural-compare-lite": "^1.4.0" }, "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", - "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0" - } - }, - "@typescript-eslint/types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", - "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", - "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "dependencies": { - "minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, - "@typescript-eslint/utils": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", - "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "semver": "^7.5.4" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", - "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", - "dev": true, - "requires": { - "@typescript-eslint/types": "6.21.0", - "eslint-visitor-keys": "^3.4.1" - } - }, "brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -24792,9 +24872,9 @@ } }, "minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "requires": { "brace-expansion": "^2.0.1" @@ -24802,30 +24882,53 @@ } } }, + "eslint-plugin-regexp": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-2.6.0.tgz", + "integrity": "sha512-FCL851+kislsTEQEMioAlpDuK5+E5vs0hi1bF8cFlPlHcEjeRhuAzEsGikXRreE+0j4WhW2uO54MqTjXtYOi3A==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.9.1", + "comment-parser": "^1.4.0", + "jsdoc-type-pratt-parser": "^4.0.0", + "refa": "^0.12.1", + "regexp-ast-analysis": "^0.7.1", + "scslre": "^0.3.0" + }, + "dependencies": { + "comment-parser": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", + "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", + "dev": true + } + } + }, "eslint-plugin-toml": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-toml/-/eslint-plugin-toml-0.10.0.tgz", - "integrity": "sha512-HzhRjePs4FDszPRY6ryHXV90MsSEkJsWnP175x33Iop/W6/hb80qjzImO5LlQfqhX3B0TkotOFSIigNI4AdGsw==", + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-toml/-/eslint-plugin-toml-0.11.1.tgz", + "integrity": "sha512-Y1WuMSzfZpeMIrmlP1nUh3kT8p96mThIq4NnHrYUhg10IKQgGfBZjAWnrg9fBqguiX4iFps/x/3Hb5TxBisfdw==", "dev": true, "requires": { "debug": "^4.1.1", "eslint-compat-utils": "^0.5.0", "lodash": "^4.17.19", - "toml-eslint-parser": "^0.9.0" + "toml-eslint-parser": "^0.10.0" } }, "eslint-plugin-unicorn": { - "version": "51.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-51.0.1.tgz", - "integrity": "sha512-MuR/+9VuB0fydoI0nIn2RDA5WISRn4AsJyNSaNKLVwie9/ONvQhxOBbkfSICBPnzKrB77Fh6CZZXjgTt/4Latw==", + "version": "54.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-54.0.0.tgz", + "integrity": "sha512-XxYLRiYtAWiAjPv6z4JREby1TAE2byBC7wlh0V4vWDCpccOSU1KovWV//jqPXF6bq3WKxqX9rdjoRQ1EhdmNdQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-validator-identifier": "^7.24.5", "@eslint-community/eslint-utils": "^4.4.0", - "@eslint/eslintrc": "^2.1.4", + "@eslint/eslintrc": "^3.0.2", "ci-info": "^4.0.0", "clean-regexp": "^1.0.0", - "core-js-compat": "^3.34.0", + "core-js-compat": "^3.37.0", "esquery": "^1.5.0", "indent-string": "^4.0.0", "is-builtin-module": "^3.2.1", @@ -24834,16 +24937,71 @@ "read-pkg-up": "^7.0.1", "regexp-tree": "^0.1.27", "regjsparser": "^0.10.0", - "semver": "^7.5.4", + "semver": "^7.6.1", "strip-indent": "^3.0.0" }, "dependencies": { + "@eslint/eslintrc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", + "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "ci-info": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.0.0.tgz", "integrity": "sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==", "dev": true }, + "eslint-visitor-keys": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "dev": true + }, + "espree": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", + "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", + "dev": true, + "requires": { + "acorn": "^8.12.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.0.0" + } + }, + "globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, "jsesc": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", @@ -24853,104 +25011,27 @@ } }, "eslint-plugin-unused-imports": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-3.1.0.tgz", - "integrity": "sha512-9l1YFCzXKkw1qtAru1RWUtG2EVDZY0a0eChKXcL+EZ5jitG7qxdctu4RnvhOJHv4xfmUf7h+JJPINlVpGhZMrw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-3.2.0.tgz", + "integrity": "sha512-6uXyn6xdINEpxE1MtDjxQsyXB37lfyO2yKGVVgtD7WEWQGORSOZjgrD6hBhvGv4/SO+TOlS+UnC6JppRqbuwGQ==", "dev": true, "requires": { "eslint-rule-composer": "^0.3.0" } }, "eslint-plugin-vitest": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vitest/-/eslint-plugin-vitest-0.4.0.tgz", - "integrity": "sha512-3oWgZIwdWVBQ5plvkmOBjreIGLQRdYb7x54OP8uIRHeZyRVJIdOn9o/qWVb9292fDMC8jn7H7d9TSFBZqhrykQ==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-vitest/-/eslint-plugin-vitest-0.5.4.tgz", + "integrity": "sha512-um+odCkccAHU53WdKAw39MY61+1x990uXjSPguUCq3VcEHdqJrOb8OTMrbYlY6f9jAKx7x98kLVlIe3RJeJqoQ==", "dev": true, "requires": { - "@typescript-eslint/utils": "^7.2.0" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.4.0.tgz", - "integrity": "sha512-68VqENG5HK27ypafqLVs8qO+RkNc7TezCduYrx8YJpXq2QGZ30vmNZGJJJC48+MVn4G2dCV8m5ZTVnzRexTVtw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "7.4.0", - "@typescript-eslint/visitor-keys": "7.4.0" - } - }, - "@typescript-eslint/types": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.4.0.tgz", - "integrity": "sha512-mjQopsbffzJskos5B4HmbsadSJQWaRK0UxqQ7GuNA9Ga4bEKeiO6b2DnB6cM6bpc8lemaPseh0H9B/wyg+J7rw==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.4.0.tgz", - "integrity": "sha512-A99j5AYoME/UBQ1ucEbbMEmGkN7SE0BvZFreSnTd1luq7yulcHdyGamZKizU7canpGDWGJ+Q6ZA9SyQobipePg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "7.4.0", - "@typescript-eslint/visitor-keys": "7.4.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/utils": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.4.0.tgz", - "integrity": "sha512-NQt9QLM4Tt8qrlBVY9lkMYzfYtNz8/6qwZg8pI3cMGlPnj6mOpRxxAm7BMJN9K0AiY+1BwJ5lVC650YJqYOuNg==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "7.4.0", - "@typescript-eslint/types": "7.4.0", - "@typescript-eslint/typescript-estree": "7.4.0", - "semver": "^7.5.4" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.4.0.tgz", - "integrity": "sha512-0zkC7YM0iX5Y41homUUeW1CHtZR01K3ybjM1l6QczoMuay0XKtrb93kv95AxUGwdjGr64nNqnOCwmEl616N8CA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "7.4.0", - "eslint-visitor-keys": "^3.4.1" - } - }, - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } + "@typescript-eslint/utils": "^7.7.1" } }, "eslint-plugin-vue": { - "version": "9.24.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.24.0.tgz", - "integrity": "sha512-9SkJMvF8NGMT9aQCwFc5rj8Wo1XWSMSHk36i7ZwdI614BU7sIOR28ZjuFPKp8YGymZN12BSEbiSwa7qikp+PBw==", + "version": "9.27.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.27.0.tgz", + "integrity": "sha512-5Dw3yxEyuBSXTzT5/Ge1X5kIkRTQ3nvBn/VwPwInNiZBSJOO/timWMUaflONnFBzU6NhB68lxnCda7ULV5N7LA==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", @@ -24959,7 +25040,7 @@ "nth-check": "^2.1.1", "postcss-selector-parser": "^6.0.15", "semver": "^7.6.0", - "vue-eslint-parser": "^9.4.2", + "vue-eslint-parser": "^9.4.3", "xml-name-validator": "^4.0.0" }, "dependencies": { @@ -24972,15 +25053,6 @@ "type-fest": "^0.20.2" } }, - "semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, "type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -24990,9 +25062,9 @@ } }, "eslint-plugin-yml": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-1.13.2.tgz", - "integrity": "sha512-1i71VhmsG5UxE41rIJmJjhlTTxYy7upAY5Hqj8AdBc7rfJzRIZr3a2spuOS8+N7ZDCWsHAWY3J6lzQNQHDv6Uw==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-1.14.0.tgz", + "integrity": "sha512-ESUpgYPOcAYQO9czugcX5OqRvn/ydDVwGCPXY4YjPqc09rHaUVUA6IE6HLQys4rXk/S+qx3EwTd1wHCwam/OWQ==", "dev": true, "requires": { "debug": "^4.3.2", @@ -25003,9 +25075,9 @@ } }, "eslint-processor-vue-blocks": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/eslint-processor-vue-blocks/-/eslint-processor-vue-blocks-0.1.1.tgz", - "integrity": "sha512-9+dU5lU881log570oBwpelaJmOfOzSniben7IWEDRYQPPWwlvaV7NhOtsTuUWDqpYT+dtKKWPsgz4OkOi+aZnA==", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/eslint-processor-vue-blocks/-/eslint-processor-vue-blocks-0.1.2.tgz", + "integrity": "sha512-PfpJ4uKHnqeL/fXUnzYkOax3aIenlwewXRX8jFinA1a2yCFnLgMuiH3xvCgvHHUlV2xJWQHbCTdiJWGwb3NqpQ==", "dev": true, "requires": {} }, @@ -25016,13 +25088,13 @@ "dev": true }, "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "requires": { "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "estraverse": "^5.2.0" } }, "eslint-visitor-keys": { @@ -25049,20 +25121,12 @@ "dev": true }, "esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, "requires": { "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } } }, "esrecurse": { @@ -25072,20 +25136,12 @@ "dev": true, "requires": { "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } } }, "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true }, "estree-walker": { @@ -25189,6 +25245,12 @@ "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", "dev": true }, + "fast-uri": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", + "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", + "dev": true + }, "fastq": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", @@ -25315,6 +25377,12 @@ "path-exists": "^4.0.0" } }, + "find-up-simple": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.0.tgz", + "integrity": "sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==", + "dev": true + }, "find-versions": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-4.0.0.tgz", @@ -25521,9 +25589,9 @@ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==" }, "get-tsconfig": { - "version": "4.7.3", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz", - "integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==", + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.5.tgz", + "integrity": "sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==", "dev": true, "requires": { "resolve-pkg-maps": "^1.0.0" @@ -25602,19 +25670,27 @@ "is-glob": "^4.0.1" } }, - "global-dirs": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", - "integrity": "sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==", + "global-directory": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", + "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==", "dev": true, "requires": { - "ini": "^1.3.4" + "ini": "4.1.1" + }, + "dependencies": { + "ini": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", + "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", + "dev": true + } } }, "globals": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.0.0.tgz", - "integrity": "sha512-m/C/yR4mjO6pXDTm9/R/SpYTAIyaUB4EOzcaaMEl7mds7Mshct9GfejiJNQGjHHbdMPey13Kpu4TMbYi9ex1pw==", + "version": "15.8.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.8.0.tgz", + "integrity": "sha512-VZAJ4cewHTExBWDHR6yptdIBlx9YSSZuwojj9Nt5mBRXQzrKakDsVKQ1J63sklLvzAJm0X5+RpO4i3Y2hcOnFw==", "dev": true }, "globby": { @@ -25959,9 +26035,9 @@ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, "ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true }, "ignore-by-default": { @@ -25995,6 +26071,12 @@ "resolve-cwd": "^3.0.0" } }, + "import-meta-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", + "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", + "dev": true + }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -26753,6 +26835,12 @@ } } }, + "jiti": { + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "dev": true + }, "jose": { "version": "4.15.5", "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.5.tgz", @@ -27160,12 +27248,6 @@ "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=" }, - "lodash.isfunction": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", - "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==", - "dev": true - }, "lodash.ismatch": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", @@ -27263,9 +27345,9 @@ "dev": true }, "magic-string": { - "version": "0.30.8", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", - "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", + "version": "0.30.10", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", "dev": true, "peer": true, "requires": { @@ -27273,9 +27355,9 @@ }, "dependencies": { "@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", "dev": true, "peer": true } @@ -27614,9 +27696,9 @@ } }, "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" }, "minimist-options": { "version": "4.1.0", @@ -28064,6 +28146,16 @@ "integrity": "sha512-RmVuCHWsfu0QPNW+mraxh/xjQVw/lhUCUru8Zni3Ctq3AoMhpDTq0OVdKS6iesd6Kqb7viCV3isAL43dciOSog==", "dev": true }, + "parse-imports": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/parse-imports/-/parse-imports-2.1.1.tgz", + "integrity": "sha512-TDT4HqzUiTMO1wJRwg/t/hYk8Wdp3iF/ToMIlAoVQfL1Xs/sTxq1dKWSMjMbQmIarfWKymOyly40+zmPHXMqCA==", + "dev": true, + "requires": { + "es-module-lexer": "^1.5.3", + "slashes": "^3.0.12" + } + }, "parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -28117,15 +28209,15 @@ "dev": true }, "pathe": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.1.tgz", - "integrity": "sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", "dev": true }, "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", "dev": true }, "picomatch": { @@ -28182,14 +28274,14 @@ "dev": true }, "postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "version": "8.4.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", + "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", "dev": true, "peer": true, "requires": { "nanoid": "^3.3.7", - "picocolors": "^1.0.0", + "picocolors": "^1.0.1", "source-map-js": "^1.2.0" }, "dependencies": { @@ -28203,9 +28295,9 @@ } }, "postcss-selector-parser": { - "version": "6.0.16", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz", - "integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.1.tgz", + "integrity": "sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==", "dev": true, "requires": { "cssesc": "^3.0.0", @@ -28774,6 +28866,25 @@ "redis-errors": "^1.0.0" } }, + "refa": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/refa/-/refa-0.12.1.tgz", + "integrity": "sha512-J8rn6v4DBb2nnFqkqwy6/NnTYMcgLA+sLr0iIO41qpv0n+ngb7ksag2tMRl0inb1bbO/esUwzW1vbJi7K0sI0g==", + "dev": true, + "requires": { + "@eslint-community/regexpp": "^4.8.0" + } + }, + "regexp-ast-analysis": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/regexp-ast-analysis/-/regexp-ast-analysis-0.7.1.tgz", + "integrity": "sha512-sZuz1dYW/ZsfG17WSAG7eS85r5a0dDsvg+7BiiYR5o6lKCAtUrEwdmRmaGF6rwVj3LcmAeYkOWKEPlbPzN3Y3A==", + "dev": true, + "requires": { + "@eslint-community/regexpp": "^4.8.0", + "refa": "^0.12.1" + } + }, "regexp-tree": { "version": "0.1.27", "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", @@ -28852,15 +28963,6 @@ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, - "resolve-global": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-global/-/resolve-global-1.0.0.tgz", - "integrity": "sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==", - "dev": true, - "requires": { - "global-dirs": "^0.1.1" - } - }, "resolve-pkg-maps": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", @@ -28926,14 +29028,22 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "scslre": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/scslre/-/scslre-0.3.0.tgz", + "integrity": "sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==", + "dev": true, "requires": { - "lru-cache": "^6.0.0" + "@eslint-community/regexpp": "^4.8.0", + "refa": "^0.12.0", + "regexp-ast-analysis": "^0.7.0" } }, + "semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==" + }, "semver-compare": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", @@ -29004,15 +29114,13 @@ "dev": true }, "shiki": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.1.tgz", - "integrity": "sha512-+Jz4nBkCBe0mEDqo1eKRcCdjRtrCjozmcbTUjbPTX7OOJfEbTZzlUWlZtGe3Gb5oV1/jnojhG//YZc3rs9zSEw==", + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.10.3.tgz", + "integrity": "sha512-eneCLncGuvPdTutJuLyUGS8QNPAVFO5Trvld2wgEq1e002mwctAhJKeMGWtWVXOIEzmlcLRqcgPSorR6AVzOmQ==", "dev": true, "requires": { - "ansi-sequence-parser": "^1.1.0", - "jsonc-parser": "^3.2.0", - "vscode-oniguruma": "^1.7.0", - "vscode-textmate": "^8.0.0" + "@shikijs/core": "1.10.3", + "@types/hast": "^3.0.4" } }, "side-channel": { @@ -29071,6 +29179,12 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, + "slashes": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/slashes/-/slashes-3.0.12.tgz", + "integrity": "sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==", + "dev": true + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -29239,6 +29353,12 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, + "stable-hash": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.4.tgz", + "integrity": "sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==", + "dev": true + }, "stack-trace": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", @@ -29297,6 +29417,12 @@ "safe-buffer": "~5.2.0" } }, + "string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true + }, "string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -29403,22 +29529,29 @@ "dev": true }, "synckit": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.6.2.tgz", - "integrity": "sha512-Vhf+bUa//YSTYKseDiiEuQmhGCoIF3CVBhunm3r/DQnYiGT4JssmnKQc44BIyOZRK2pKjXXAgbhfmbeoC9CJpA==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz", + "integrity": "sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==", "dev": true, "requires": { - "tslib": "^2.3.1" + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" }, "dependencies": { "tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", "dev": true } } }, + "tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true + }, "test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -29495,9 +29628,9 @@ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" }, "toml-eslint-parser": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/toml-eslint-parser/-/toml-eslint-parser-0.9.3.tgz", - "integrity": "sha512-moYoCvkNUAPCxSW9jmHmRElhm4tVJpHL8ItC/+uYD0EpPSFXbck7yREz9tNdJVTSpHVod8+HoipcpbQ0oE6gsw==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/toml-eslint-parser/-/toml-eslint-parser-0.10.0.tgz", + "integrity": "sha512-khrZo4buq4qVmsGzS5yQjKe/WsFvV8fGfOjDQN0q4iy9FjRfPWRgTFrU8u1R2iu/SfWLhY9WnCi4Jhdrcbtg+g==", "dev": true, "requires": { "eslint-visitor-keys": "^3.0.0" @@ -29643,15 +29776,16 @@ "dev": true }, "typedoc": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.2.tgz", - "integrity": "sha512-286F7BeATBiWe/qC4PCOCKlSTwfnsLbC/4cZ68oGBbvAqb9vV33quEOXx7q176OXotD+JdEerdQ1OZGJ818lnA==", + "version": "0.26.4", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.26.4.tgz", + "integrity": "sha512-FlW6HpvULDKgc3rK04V+nbFyXogPV88hurarDPOjuuB5HAwuAlrCMQ5NeH7Zt68a/ikOKu6Z/0hFXAeC9xPccQ==", "dev": true, "requires": { "lunr": "^2.3.9", - "marked": "^4.3.0", - "minimatch": "^9.0.3", - "shiki": "^0.14.1" + "markdown-it": "^14.1.0", + "minimatch": "^9.0.5", + "shiki": "^1.9.1", + "yaml": "^2.4.5" }, "dependencies": { "brace-expansion": { @@ -29663,27 +29797,27 @@ "balanced-match": "^1.0.0" } }, - "marked": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", - "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", - "dev": true - }, "minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "requires": { "brace-expansion": "^2.0.1" } + }, + "yaml": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", + "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", + "dev": true } } }, "typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", + "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", "dev": true }, "uc.micro": { @@ -29811,22 +29945,10 @@ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" }, - "vscode-oniguruma": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", - "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==", - "dev": true - }, - "vscode-textmate": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", - "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==", - "dev": true - }, "vue-eslint-parser": { - "version": "9.4.2", - "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz", - "integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.3.tgz", + "integrity": "sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==", "dev": true, "requires": { "debug": "^4.3.4", @@ -29836,24 +29958,6 @@ "esquery": "^1.4.0", "lodash": "^4.17.21", "semver": "^7.3.6" - }, - "dependencies": { - "eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } } }, "walker": { @@ -29990,9 +30094,9 @@ "dev": true }, "yaml-eslint-parser": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/yaml-eslint-parser/-/yaml-eslint-parser-1.2.2.tgz", - "integrity": "sha512-pEwzfsKbTrB8G3xc/sN7aw1v6A6c/pKxLAkjclnAyo5g5qOh6eL9WGu0o3cSDQZKrTNk4KL4lQSwZW+nBkANEg==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/yaml-eslint-parser/-/yaml-eslint-parser-1.2.3.tgz", + "integrity": "sha512-4wZWvE398hCP7O8n3nXKu/vdq1HcH01ixYlCREaJL5NUMwQ0g3MaGFUBNSlmBtKmhbtVG/Cm6lyYmSVTEVil8A==", "dev": true, "requires": { "eslint-visitor-keys": "^3.0.0", @@ -30001,9 +30105,9 @@ }, "dependencies": { "yaml": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz", - "integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==", + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", + "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", "dev": true } } diff --git a/package.json b/package.json index 4bbccd183..ee8404f6b 100644 --- a/package.json +++ b/package.json @@ -143,9 +143,9 @@ "yup": "^1.3.2" }, "devDependencies": { - "@antfu/eslint-config": "2.11.4", - "@commitlint/cli": "^17.7.2", - "@commitlint/config-conventional": "^17.7.0", + "@antfu/eslint-config": "2.21.3", + "@commitlint/cli": "^19.3.0", + "@commitlint/config-conventional": "^19.2.2", "@inrupt/solid-client-authn-core": "^2.0.0", "@inrupt/solid-client-authn-node": "^2.0.0", "@tsconfig/node18": "^18.2.2", @@ -167,8 +167,8 @@ "supertest": "^6.3.3", "ts-jest": "^29.1.1", "ts-node": "^10.9.1", - "typedoc": "^0.25.2", - "typescript": "^5.2.2" + "typedoc": "^0.26.4", + "typescript": "^5.5.3" }, "husky": { "hooks": { diff --git a/scripts/formatChangelog.ts b/scripts/formatChangelog.ts index 266d6b664..2df275569 100644 --- a/scripts/formatChangelog.ts +++ b/scripts/formatChangelog.ts @@ -20,7 +20,7 @@ import { readFile, writeFile } from 'fs-extra'; * @returns Promise with output string */ async function capitalizeListEntries(input: string): Promise { - return input.replaceAll(/^(\W*\* [a-z])/gmu, (match): string => match.toUpperCase()); + return input.replaceAll(/^\W*\* [a-z]/gmu, (match): string => match.toUpperCase()); } /** diff --git a/src/authentication/UnsecureWebIdExtractor.ts b/src/authentication/UnsecureWebIdExtractor.ts index dd6eaba0c..4e2b73a34 100644 --- a/src/authentication/UnsecureWebIdExtractor.ts +++ b/src/authentication/UnsecureWebIdExtractor.ts @@ -19,7 +19,7 @@ export class UnsecureWebIdExtractor extends CredentialsExtractor { } public async handle({ headers }: HttpRequest): Promise { - const webId = /^WebID\s+(.*)/ui.exec(headers.authorization!)![1]; + const webId = /^WebID\s+(.*)/iu.exec(headers.authorization!)![1]; this.logger.info(`Agent unsecurely claims to be ${webId}`); return { agent: { webId }}; } diff --git a/src/authorization/AcpReader.ts b/src/authorization/AcpReader.ts index 80b4d3f6e..b1be9fe05 100644 --- a/src/authorization/AcpReader.ts +++ b/src/authorization/AcpReader.ts @@ -24,7 +24,7 @@ import { AclMode } from './permissions/AclPermissionSet'; import { AccessMode } from './permissions/Permissions'; import type { PermissionMap, PermissionSet } from './permissions/Permissions'; -const modesMap: Record> = { +const modesMap: Record = { [ACL.Read]: [ AccessMode.read ], [ACL.Write]: [ AccessMode.append, AccessMode.write ], [ACL.Append]: [ AccessMode.append ], diff --git a/src/authorization/WebAclReader.ts b/src/authorization/WebAclReader.ts index 8087da2cc..085305393 100644 --- a/src/authorization/WebAclReader.ts +++ b/src/authorization/WebAclReader.ts @@ -22,7 +22,7 @@ import type { PermissionMap } from './permissions/Permissions'; import { AccessMode } from './permissions/Permissions'; // Maps WebACL-specific modes to generic access modes. -const modesMap: Record> = { +const modesMap: Record = { [ACL.Read]: [ AccessMode.read ], [ACL.Write]: [ AccessMode.append, AccessMode.write ], [ACL.Append]: [ AccessMode.append ], @@ -69,7 +69,7 @@ export class WebAclReader extends PermissionReader { this.logger.debug(`Retrieving permissions of ${credentials.agent?.webId ?? 'an unknown agent'}`); const aclMap = await this.getAclMatches(requestedModes.distinctKeys()); const storeMap = await this.findAuthorizationStatements(aclMap); - return await this.findPermissions(storeMap, credentials); + return this.findPermissions(storeMap, credentials); } /** diff --git a/src/authorization/access/AgentGroupAccessChecker.ts b/src/authorization/access/AgentGroupAccessChecker.ts index a65020292..089a60eba 100644 --- a/src/authorization/access/AgentGroupAccessChecker.ts +++ b/src/authorization/access/AgentGroupAccessChecker.ts @@ -21,7 +21,7 @@ export class AgentGroupAccessChecker extends AccessChecker { const { webId } = credentials.agent; const groups = acl.getObjects(rule, ACL.terms.agentGroup, null); - return await promiseSome(groups.map(async(group: Term): Promise => + return promiseSome(groups.map(async(group: Term): Promise => this.isMemberOfGroup(webId, group))); } return false; @@ -51,6 +51,6 @@ export class AgentGroupAccessChecker extends AccessChecker { const representation = await fetchDataset(url); return readableToQuads(representation.data); })(); - return await prom; + return prom; } } diff --git a/src/http/UnsecureWebSocketsProtocol.ts b/src/http/UnsecureWebSocketsProtocol.ts index 0bcdd04cc..c6f4e8a39 100644 --- a/src/http/UnsecureWebSocketsProtocol.ts +++ b/src/http/UnsecureWebSocketsProtocol.ts @@ -79,7 +79,7 @@ class WebSocketListener extends WebSocketListenerEmitter { private onMessage(message: string): void { // Parse the message - const match = /^(\w+)\s+(.+)$/u.exec(message); + const match = /^(\w+)\s+(\S.+)$/u.exec(message); if (!match) { this.sendMessage('warning', `Unrecognized message format: ${message}`); return; diff --git a/src/identity/interaction/account/util/BaseCookieStore.ts b/src/identity/interaction/account/util/BaseCookieStore.ts index 633b22f0f..878146b1b 100644 --- a/src/identity/interaction/account/util/BaseCookieStore.ts +++ b/src/identity/interaction/account/util/BaseCookieStore.ts @@ -23,7 +23,7 @@ export class BaseCookieStore implements CookieStore { } public async get(cookie: string): Promise { - return await this.storage.get(cookie); + return this.storage.get(cookie); } public async refresh(cookie: string): Promise { diff --git a/src/identity/interaction/account/util/BaseLoginAccountStorage.ts b/src/identity/interaction/account/util/BaseLoginAccountStorage.ts index f33452ff3..5523aad52 100644 --- a/src/identity/interaction/account/util/BaseLoginAccountStorage.ts +++ b/src/identity/interaction/account/util/BaseLoginAccountStorage.ts @@ -103,7 +103,7 @@ export class BaseLoginAccountStorage> implement } public async findIds>(type: TType, query: IndexedQuery): Promise { - return await this.storage.findIds(type, query); + return this.storage.findIds(type, query); } public async set>(type: TType, value: TypeObject): Promise { diff --git a/src/init/migration/V6MigrationInitializer.ts b/src/init/migration/V6MigrationInitializer.ts index cff64ed34..6d765f21c 100644 --- a/src/init/migration/V6MigrationInitializer.ts +++ b/src/init/migration/V6MigrationInitializer.ts @@ -149,7 +149,7 @@ export class V6MigrationInitializer extends Initializer { ].join(' '), resolve); }); readline.close(); - if (!/^y(?:es)?$/ui.test(answer)) { + if (!/^y(?:es)?$/iu.test(answer)) { throw new Error('Stopping server as migration was cancelled.'); } } diff --git a/src/pods/generate/BaseComponentsJsFactory.ts b/src/pods/generate/BaseComponentsJsFactory.ts index 00ba376d5..607a89d27 100644 --- a/src/pods/generate/BaseComponentsJsFactory.ts +++ b/src/pods/generate/BaseComponentsJsFactory.ts @@ -40,6 +40,6 @@ export class BaseComponentsJsFactory implements ComponentsJsFactory { Promise { const manager = await this.buildManager(); await manager.configRegistry.register(configPath); - return await manager.instantiate(componentIri, { variables }); + return manager.instantiate(componentIri, { variables }); } } diff --git a/src/server/util/RedirectingHttpHandler.ts b/src/server/util/RedirectingHttpHandler.ts index 44e8d6071..4cafd6473 100644 --- a/src/server/util/RedirectingHttpHandler.ts +++ b/src/server/util/RedirectingHttpHandler.ts @@ -108,6 +108,6 @@ export class RedirectingHttpHandler extends HttpHandler { throw new NotImplementedHttpError('Target is already correct.'); } - return /^(?:[a-z]+:)?\/\//ui.test(redirect) ? redirect : joinUrl(this.baseUrl, redirect); + return /^(?:[a-z]+:)?\/\//iu.test(redirect) ? redirect : joinUrl(this.baseUrl, redirect); } } diff --git a/src/storage/DataAccessorBasedStore.ts b/src/storage/DataAccessorBasedStore.ts index 111e7ea15..b68fa2552 100644 --- a/src/storage/DataAccessorBasedStore.ts +++ b/src/storage/DataAccessorBasedStore.ts @@ -258,7 +258,7 @@ export class DataAccessorBasedStore implements ResourceStore { this.validateConditions(conditions, oldMetadata); if (this.metadataStrategy.isAuxiliaryIdentifier(identifier)) { - return await this.writeMetadata(identifier, representation); + return this.writeMetadata(identifier, representation); } // Potentially have to create containers if it didn't exist yet diff --git a/src/storage/accessors/FileDataAccessor.ts b/src/storage/accessors/FileDataAccessor.ts index d409004b8..a9caefcef 100644 --- a/src/storage/accessors/FileDataAccessor.ts +++ b/src/storage/accessors/FileDataAccessor.ts @@ -184,7 +184,7 @@ export class FileDataAccessor implements DataAccessor { */ private async getDirectoryMetadata(link: ResourceLink, stats: Stats): Promise { - return await this.getBaseMetadata(link, stats, true); + return this.getBaseMetadata(link, stats, true); } /** diff --git a/src/storage/accessors/SparqlDataAccessor.ts b/src/storage/accessors/SparqlDataAccessor.ts index 9efdb910f..7eef80963 100644 --- a/src/storage/accessors/SparqlDataAccessor.ts +++ b/src/storage/accessors/SparqlDataAccessor.ts @@ -73,7 +73,7 @@ export class SparqlDataAccessor implements DataAccessor { */ public async getData(identifier: ResourceIdentifier): Promise> { const name = namedNode(identifier.path); - return await this.sendSparqlConstruct(this.sparqlConstruct(name)); + return this.sendSparqlConstruct(this.sparqlConstruct(name)); } /** diff --git a/src/storage/conversion/ContainerToTemplateConverter.ts b/src/storage/conversion/ContainerToTemplateConverter.ts index f232dcf31..2ac32fef1 100644 --- a/src/storage/conversion/ContainerToTemplateConverter.ts +++ b/src/storage/conversion/ContainerToTemplateConverter.ts @@ -98,7 +98,7 @@ export class ContainerToTemplateConverter extends BaseTypedRepresentationConvert * Derives a short name for the given resource. */ private getLocalName(iri: string): string { - const match = /:\/+([^/]+).*?\/([^/]*)\/?$/u.exec(iri); + const match = /:\/+([^/]+)(?:\/[^/]*)*?\/([^/]*)\/?$/u.exec(iri); return match?.[2] ? decodeURIComponent(match[2]) : match?.[1] ?? iri; } } diff --git a/src/storage/keyvalue/JsonResourceStorage.ts b/src/storage/keyvalue/JsonResourceStorage.ts index 71aa0903d..43fa2773c 100644 --- a/src/storage/keyvalue/JsonResourceStorage.ts +++ b/src/storage/keyvalue/JsonResourceStorage.ts @@ -38,7 +38,8 @@ export class JsonResourceStorage implements KeyValueStorage { const identifier = this.keyToIdentifier(key); // eslint-disable-next-line ts/naming-convention const representation = await this.source.getRepresentation(identifier, { type: { 'application/json': 1 }}); - return JSON.parse(await readableToString(representation.data)) as Promise; + // eslint-disable-next-line ts/no-unsafe-return + return JSON.parse(await readableToString(representation.data)); } catch (error: unknown) { if (!NotFoundHttpError.isInstance(error)) { throw error; @@ -48,7 +49,7 @@ export class JsonResourceStorage implements KeyValueStorage { public async has(key: string): Promise { const identifier = this.keyToIdentifier(key); - return await this.source.hasResource(identifier); + return this.source.hasResource(identifier); } public async set(key: string, value: unknown): Promise { diff --git a/src/storage/mapping/ExtensionBasedMapper.ts b/src/storage/mapping/ExtensionBasedMapper.ts index 4b59e77c2..da148fcb9 100644 --- a/src/storage/mapping/ExtensionBasedMapper.ts +++ b/src/storage/mapping/ExtensionBasedMapper.ts @@ -48,7 +48,7 @@ export class ExtensionBasedMapper extends BaseFileIdentifierMapper { // Existing file if (!contentType) { // Find a matching file - const [ , folder, documentName ] = /^(.*\/)(.*)$/u.exec(filePath)!; + const [ , folder, documentName ] = /^(.*\/)([^/]*)$/u.exec(filePath)!; let fileName: string | undefined; try { const files = await fsPromises.readdir(folder); diff --git a/src/util/Header.ts b/src/util/Header.ts index dd5102633..62b127fc0 100644 --- a/src/util/Header.ts +++ b/src/util/Header.ts @@ -118,7 +118,7 @@ export interface LinkEntry { // // REUSED REGEXES -export const TCHAR = /[a-zA-Z0-9!#$%&'*+-.^_`|~]/u; +export const TCHAR = /[-\w!#$%&'*+.^`|~]/u; export const TOKEN = new RegExp(`^${TCHAR.source}+$`, 'u'); export const SIMPLE_MEDIA_RANGE = new RegExp(`^${TCHAR.source}+/${TCHAR.source}+$`, 'u'); export const QUOTED_STRING = diff --git a/src/util/HeaderUtil.ts b/src/util/HeaderUtil.ts index 443a4709a..ceddab8af 100644 --- a/src/util/HeaderUtil.ts +++ b/src/util/HeaderUtil.ts @@ -493,7 +493,7 @@ const authSchemeRegexCache: Map = new Map(); export function matchesAuthorizationScheme(scheme: string, authorization?: string): boolean { const lowerCaseScheme = scheme.toLowerCase(); if (!authSchemeRegexCache.has(lowerCaseScheme)) { - authSchemeRegexCache.set(lowerCaseScheme, new RegExp(`^${escapeStringRegexp(lowerCaseScheme)} `, 'ui')); + authSchemeRegexCache.set(lowerCaseScheme, new RegExp(`^${escapeStringRegexp(lowerCaseScheme)} `, 'iu')); } // Support authorization being undefined (for the sake of usability). return typeof authorization !== 'undefined' && authSchemeRegexCache.get(lowerCaseScheme)!.test(authorization); diff --git a/src/util/PathUtil.ts b/src/util/PathUtil.ts index 393b39a16..583ccd91a 100644 --- a/src/util/PathUtil.ts +++ b/src/util/PathUtil.ts @@ -126,7 +126,7 @@ export function getExtension(path: string): string { * preserving but normalizing path delimiters and their escaped forms. */ function transformPathComponents(path: string, transform: (part: string) => string): string { - const [ , base, queryString ] = /^([^?]*)(.*)$/u.exec(path)!; + const [ , base, queryString ] = /^([^?]*)(\?.*)?$/u.exec(path)!; const transformed = base // We split on actual URI path component delimiters (slash and backslash), // but also on things that could be wrongly interpreted as component delimiters, @@ -135,7 +135,7 @@ function transformPathComponents(path: string, transform: (part: string) => stri // since they would become _actual_ delimiters if accidentally decoded. // Additionally, we need to preserve any encoded percent signs (%25) // that precede them, because these might change their interpretation as well. - .split(/(\/|\\|%(?:25)*(?:2f|5c))/ui) + .split(/(\/|\\|%(?:25)*(?:2f|5c))/iu) // Even parts map to components that need to be transformed, // odd parts to (possibly escaped) delimiters that need to be normalized. .map((part, index): string => @@ -172,7 +172,7 @@ const forbiddenSymbols = { '*': '%2A', } as const; /* eslint-enable ts/naming-convention */ -const forbiddenRegex = new RegExp(`[${Object.keys(forbiddenSymbols).join('')}]`, 'ug'); +const forbiddenRegex = new RegExp(`[${Object.keys(forbiddenSymbols).join('')}]`, 'gu'); /** * This function is used when converting a URI to a file path. Decodes all components of a URI path, * with the exception of encoded slash characters, as this would lead to unexpected file locations diff --git a/src/util/RecordObject.ts b/src/util/RecordObject.ts index 5528ade2e..1d2325a7f 100644 --- a/src/util/RecordObject.ts +++ b/src/util/RecordObject.ts @@ -2,6 +2,7 @@ * Helper class for instantiating multiple objects with Components.js. * See https://github.com/LinkedSoftwareDependencies/Components.js/issues/26 */ +// eslint-disable-next-line ts/no-extraneous-class export class RecordObject implements Record { public constructor(record: Record = {}) { // eslint-disable-next-line no-constructor-return diff --git a/src/util/errors/ErrorUtil.ts b/src/util/errors/ErrorUtil.ts index 2ce634cc1..2762ee58e 100644 --- a/src/util/errors/ErrorUtil.ts +++ b/src/util/errors/ErrorUtil.ts @@ -6,9 +6,9 @@ import { types } from 'node:util'; export function isError(error: unknown): error is Error { return types.isNativeError(error) || (Boolean(error) && - typeof (error as Error).name === 'string' && - typeof (error as Error).message === 'string' && - (typeof (error as Error).stack === 'undefined' || typeof (error as Error).stack === 'string')); + typeof (error as Error).name === 'string' && + typeof (error as Error).message === 'string' && + (typeof (error as Error).stack === 'undefined' || typeof (error as Error).stack === 'string')); } /** diff --git a/src/util/errors/MethodNotAllowedHttpError.ts b/src/util/errors/MethodNotAllowedHttpError.ts index 65609fbac..41fc93f68 100644 --- a/src/util/errors/MethodNotAllowedHttpError.ts +++ b/src/util/errors/MethodNotAllowedHttpError.ts @@ -10,6 +10,8 @@ const BaseHttpError = generateHttpErrorClass(405, 'MethodNotAllowedHttpError'); * Can keep track of the methods that are not allowed. */ export class MethodNotAllowedHttpError extends BaseHttpError { + // Components.js can't parse `readonly` + // eslint-disable-next-line ts/array-type public readonly methods: Readonly; public constructor(methods: string[] = [], message?: string, options?: HttpErrorOptions) { diff --git a/test/integration/Config.ts b/test/integration/Config.ts index 23d252a81..1c0b5f373 100644 --- a/test/integration/Config.ts +++ b/test/integration/Config.ts @@ -31,7 +31,7 @@ export async function instantiateFromConfig( for (const configPath of configPaths) { await manager.configRegistry.register(configPath); } - return await manager.instantiate(componentUrl, { variables }); + return manager.instantiate(componentUrl, { variables }); } export function getTestConfigPath(configFile: string): string { diff --git a/test/unit/init/AppRunner.test.ts b/test/unit/init/AppRunner.test.ts index 1e338fafa..73165cccc 100644 --- a/test/unit/init/AppRunner.test.ts +++ b/test/unit/init/AppRunner.test.ts @@ -257,9 +257,9 @@ describe('AppRunner', (): void => { } catch (error: unknown) { caughtError = error as Error; } - expect(caughtError?.message).toMatch(/^Cannot run a singlethreaded-only component in a multithreaded setup!/mu); + expect(caughtError?.message).toMatch(/^Cannot run a singlethreaded-only component in a multithreaded setup!/u); expect(caughtError?.message).toMatch( - /\[ViolatingClass\] is not threadsafe and should not be run in multithreaded setups!/mu, + /\[ViolatingClass\] is not threadsafe and should not be run in multithreaded setups!/u, ); expect(write).toHaveBeenCalledTimes(0); @@ -295,7 +295,7 @@ describe('AppRunner', (): void => { } expect(caughtError?.message).toMatch(/^Cannot run a singlethreaded-only component in a multithreaded setup!/mu); expect(caughtError?.message).toMatch( - /\[ViolatingClass1, ViolatingClass2\] are not threadsafe and should not be run in multithreaded setups!/mu, + /\[ViolatingClass1, ViolatingClass2\] are not threadsafe and should not be run in multithreaded setups!/u, ); expect(write).toHaveBeenCalledTimes(0); @@ -481,7 +481,7 @@ describe('AppRunner', (): void => { } expect(caughtError.message).toMatch(/^Cannot run a singlethreaded-only component in a multithreaded setup!/mu); expect(caughtError?.message).toMatch( - /\[ViolatingClass\] is not threadsafe and should not be run in multithreaded setups!/mu, + /\[ViolatingClass\] is not threadsafe and should not be run in multithreaded setups!/u, ); expect(write).toHaveBeenCalledTimes(0); @@ -820,7 +820,7 @@ describe('AppRunner', (): void => { await flushPromises(); expect(write).toHaveBeenCalledTimes(1); - expect(write).toHaveBeenLastCalledWith(expect.stringMatching(/Error: Fatal/mu)); + expect(write).toHaveBeenLastCalledWith(expect.stringMatching(/Error: Fatal/u)); expect(exit).toHaveBeenCalledTimes(1); expect(exit).toHaveBeenLastCalledWith(1); diff --git a/test/unit/storage/DataAccessorBasedStore.test.ts b/test/unit/storage/DataAccessorBasedStore.test.ts index d254fdda4..7279987d0 100644 --- a/test/unit/storage/DataAccessorBasedStore.test.ts +++ b/test/unit/storage/DataAccessorBasedStore.test.ts @@ -302,7 +302,7 @@ describe('A DataAccessorBasedStore', (): void => { const generatedID = [ ...result.keys() ].find((id): boolean => id.path !== resourceID.path)!; expect(generatedID).toBeDefined(); - expect(generatedID.path).toMatch(new RegExp(`^${root}[^/]+?/$`, 'u')); + expect(generatedID.path).toMatch(new RegExp(`^${root}[^/]*/$`, 'u')); expect(accessor.data[generatedID.path]).toBeDefined(); expect(accessor.data[generatedID.path].metadata.contentType).toBeUndefined(); @@ -630,8 +630,7 @@ describe('A DataAccessorBasedStore', (): void => { data: guardedStreamFrom([ resourceData ]), metadata: new RepresentationMetadata({ [CONTENT_TYPE]: 'text/plain', - [RDF.type]: namedNode(LDP.Resource), - [RDF.type]: namedNode('http://example.org/Type'), + [RDF.type]: [ namedNode(LDP.Resource), namedNode('http://example.org/Type') ], }), isEmpty: false, }; @@ -659,8 +658,7 @@ describe('A DataAccessorBasedStore', (): void => { data: guardedStreamFrom([ ' ' ]), metadata: new RepresentationMetadata({ [CONTENT_TYPE]: 'text/turtle', - [RDF.type]: namedNode(LDP.Resource), - [RDF.type]: namedNode('http://example.org/Type'), + [RDF.type]: [ namedNode(LDP.Resource), namedNode('http://example.org/Type') ], }), isEmpty: false, }; diff --git a/test/unit/storage/keyvalue/JsonFileStorage.test.ts b/test/unit/storage/keyvalue/JsonFileStorage.test.ts index ae93b5118..8f6c66e88 100644 --- a/test/unit/storage/keyvalue/JsonFileStorage.test.ts +++ b/test/unit/storage/keyvalue/JsonFileStorage.test.ts @@ -17,9 +17,9 @@ describe('A JsonFileStorage', (): void => { cache = mockFileSystem(rootFilePath); locker = { withReadLock: - jest.fn(async(identifier: ResourceIdentifier, whileLocked: () => any): Promise => await whileLocked()), + jest.fn(async(identifier: ResourceIdentifier, whileLocked: () => any): Promise => whileLocked()), withWriteLock: - jest.fn(async(identifier: ResourceIdentifier, whileLocked: () => any): Promise => await whileLocked()), + jest.fn(async(identifier: ResourceIdentifier, whileLocked: () => any): Promise => whileLocked()), }; storage = new JsonFileStorage(`${rootFilePath}${jsonPath}`, locker); }); diff --git a/test/util/Util.ts b/test/util/Util.ts index 22f669e5a..d23899eab 100644 --- a/test/util/Util.ts +++ b/test/util/Util.ts @@ -78,7 +78,7 @@ export function getSocket(name: typeof socketNames[number]): string { export function describeIf(envFlag: string): Describe { const flag = `TEST_${envFlag.toUpperCase()}`; - const enabled = !/^(|0|false)$/iu.test(process.env[flag] ?? ''); + const enabled = !/^(?:0|false)?$/iu.test(process.env[flag] ?? ''); return enabled ? describe : describe.skip; } @@ -316,7 +316,7 @@ export function mockFileSystem(rootFilepath?: string, time?: Date): { data: any return mockFs.createWriteStream(path); }, async realpath(path: string): Promise { - return await mockFs.promises.realpath(path); + return mockFs.promises.realpath(path); }, async stat(path: string): Promise { return mockFs.promises.lstat(await mockFs.promises.realpath(path)); @@ -334,7 +334,7 @@ export function mockFileSystem(rootFilepath?: string, time?: Date): { data: any await mockFs.promises.rm(path); }, async readdir(path: string): Promise { - return await mockFs.promises.readdir(path); + return mockFs.promises.readdir(path); }, async* opendir(path: string): AsyncIterableIterator { for await (const entry of mockFs.promises.opendir(path)) { @@ -345,7 +345,7 @@ export function mockFileSystem(rootFilepath?: string, time?: Date): { data: any await mockFs.promises.mkdir(path); }, async readFile(path: string): Promise { - return await mockFs.promises.readFile(path); + return mockFs.promises.readFile(path); }, async writeFile(path: string, data: string): Promise { await mockFs.promises.writeFile(path, data); From 46f5fc239efa794f5309834fa818d17c96f83bd1 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Thu, 18 Jul 2024 14:48:33 +0200 Subject: [PATCH 57/71] chore: Depend on external eslint package --- eslint.config.js | 51 +--------------- eslint/file-names.js | 33 ----------- eslint/general.js | 136 ------------------------------------------- eslint/test.js | 47 --------------- eslint/typed.js | 57 ------------------ eslint/unicorn.js | 53 ----------------- package-lock.json | 27 +++++++-- package.json | 3 +- 8 files changed, 27 insertions(+), 380 deletions(-) delete mode 100644 eslint/file-names.js delete mode 100644 eslint/general.js delete mode 100644 eslint/test.js delete mode 100644 eslint/typed.js delete mode 100644 eslint/unicorn.js diff --git a/eslint.config.js b/eslint.config.js index 3829d0be2..47f295151 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,19 +1,6 @@ -const antfu = require('@antfu/eslint-config'); -const fileNamesConfig = require('./eslint/file-names'); -const generalConfig = require('./eslint/general'); -const testConfig = require('./eslint/test'); -const typedConfig = require('./eslint/typed'); -const unicornConfig = require('./eslint/unicorn'); +const opinionated = require('opinionated-eslint-config'); -// The default ignore list contains all `output` folders, which conflicts with our src/http/output folder -// See https://github.com/antfu/eslint-config/blob/7071af7024335aad319a91db41ce594ebc6a0899/src/globs.ts#L55 -const index = antfu.GLOB_EXCLUDE.indexOf('**/output'); -if (index < 0) { - throw new Error('Could not update GLOB_EXCLUDE. Check if antfu changed how it handles ignores.'); -} -antfu.GLOB_EXCLUDE.splice(index, 1); - -module.exports = antfu.default( +module.exports = opinionated( { // Don't want to lint test assets, or TS snippets in markdown files ignores: [ 'test/assets/*', '**/*.md' ], @@ -21,36 +8,4 @@ module.exports = antfu.default( tsconfigPath: [ './tsconfig.json', './scripts/tsconfig.json', './test/tsconfig.json' ], }, }, -) - .append(generalConfig) - .append(unicornConfig) - .append(fileNamesConfig) - // Using an override here so all the type settings are also applied correctly - .override('antfu/typescript/rules-type-aware', typedConfig) - .append({ - ...testConfig, - files: [ 'test/**/*.ts' ], - }) - .override('antfu/jsonc/rules', { - rules: { - // Consistent with how we do it in code - 'jsonc/array-bracket-spacing': [ 'error', 'always', { - singleValue: true, - objectsInArrays: false, - arraysInArrays: false, - }], - }, - }) - .append({ - // This is necessary to prevent filename checks caused by JSON being present in a README. - files: [ '**/README.md/**' ], - rules: { - 'unicorn/filename-case': 'off', - }, - }) - .override('antfu/markdown/parser', { - rules: { - // We want to be able to use these in Markdown text - 'no-irregular-whitespace': 'off', - }, - }); +); diff --git a/eslint/file-names.js b/eslint/file-names.js deleted file mode 100644 index a394deb12..000000000 --- a/eslint/file-names.js +++ /dev/null @@ -1,33 +0,0 @@ -module.exports = [ - { - name: 'opinionated/file-names/all', - rules: { - 'unicorn/filename-case': [ 'error', { - cases: { - camelCase: false, - pascalCase: false, - kebabCase: true, - snakeCase: false, - }, - ignore: [ - // CODE_OF_CONDUCT.md, etc. - /[A-Z_]+\.md$/u, - ], - }], - }, - }, - { - name: 'opinionated/file-names/ts', - files: [ '**/*.ts' ], - rules: { - 'unicorn/filename-case': [ 'error', { - cases: { - camelCase: true, - pascalCase: true, - kebabCase: false, - snakeCase: false, - }, - }], - }, - }, -]; diff --git a/eslint/general.js b/eslint/general.js deleted file mode 100644 index 7bc7ad31e..000000000 --- a/eslint/general.js +++ /dev/null @@ -1,136 +0,0 @@ -module.exports = { - name: 'opinionated/general', - rules: { - 'antfu/consistent-list-newline': 'error', - - 'arrow-body-style': [ 'error', 'as-needed', { requireReturnForObjectLiteral: false }], - 'capitalized-comments': [ 'error', 'always', { ignoreConsecutiveComments: true }], - 'callback-return': 'error', - 'consistent-this': 'error', - curly: [ 'error', 'all' ], - 'default-case': 'error', - eqeqeq: [ 'error', 'always' ], - 'for-direction': 'error', - 'func-style': [ 'error', 'declaration' ], - 'function-call-argument-newline': [ 'error', 'consistent' ], - 'function-paren-newline': [ 'error', 'consistent' ], - 'getter-return': [ 'error', { allowImplicit: true }], - 'global-require': 'error', - 'grouped-accessor-pairs': [ 'error', 'getBeforeSet' ], - 'guard-for-in': 'error', - 'line-comment-position': [ 'error', { position: 'above' }], - 'linebreak-style': [ 'error', 'unix' ], - 'multiline-comment-style': [ 'error', 'separate-lines' ], - // Need to override `allow` value - 'no-console': [ 'error', { allow: [ '' ]}], - 'no-constructor-return': 'error', - 'no-dupe-else-if': 'error', - 'no-else-return': [ 'error', { allowElseIf: false }], - 'no-implicit-coercion': 'error', - 'no-implicit-globals': 'error', - 'no-lonely-if': 'error', - 'no-plusplus': [ 'error', { allowForLoopAfterthoughts: true }], - 'no-sync': [ 'error', { allowAtRootLevel: false }], - 'no-useless-concat': 'error', - 'no-useless-escape': 'error', - 'operator-assignment': [ 'error', 'always' ], - 'prefer-object-spread': 'error', - radix: 'error', - 'require-unicode-regexp': 'error', - 'require-yield': 'error', - 'sort-imports': [ - 'error', - { - allowSeparatedGroups: false, - ignoreCase: true, - ignoreDeclarationSort: true, - ignoreMemberSort: false, - memberSyntaxSortOrder: [ 'none', 'all', 'multiple', 'single' ], - }, - ], - - 'import/extensions': 'error', - 'import/no-extraneous-dependencies': 'error', - - 'jsdoc/tag-lines': [ 'error', 'any', { startLines: 1 }], - 'jsdoc/no-multi-asterisks': [ 'error', { allowWhitespace: true }], - 'jsdoc/no-types': 'error', - 'jsdoc/sort-tags': [ 'error', { - tagSequence: [ - { tags: [ 'param' ]}, - { tags: [ 'returns' ]}, - { tags: [ 'throws' ]}, - ], - }], - 'jsdoc/valid-types': 'error', - - 'node/prefer-global/buffer': [ 'error', 'always' ], - 'node/prefer-global/console': [ 'error', 'always' ], - 'node/prefer-global/process': [ 'error', 'always' ], - 'node/prefer-global/url': [ 'error', 'always' ], - - 'style/array-bracket-spacing': [ 'error', 'always', { - singleValue: true, - objectsInArrays: false, - arraysInArrays: false, - }], - // Conflicts with style/object-curly-spacing - 'style/block-spacing': 'off', - 'style/brace-style': [ 'error', '1tbs', { allowSingleLine: false }], - 'style/generator-star-spacing': [ 'error', { before: false, after: true }], - 'style/indent-binary-ops': 'error', - 'style/member-delimiter-style': [ 'error', { - multiline: { delimiter: 'semi', requireLast: true }, - singleline: { delimiter: 'semi', requireLast: false }, - }], - 'style/no-extra-parens': [ 'error', 'all', { - // To prevent conflicts with style/no-mixed-operators - nestedBinaryExpressions: false, - }], - 'style/object-curly-spacing': [ 'error', 'always', { - objectsInObjects: false, - arraysInObjects: false, - }], - 'style/operator-linebreak': [ 'error', 'after' ], - 'style/semi': [ 'error', 'always' ], - 'style/semi-style': [ 'error', 'last' ], - 'style/space-before-function-paren': [ 'error', 'never' ], - 'style/switch-colon-spacing': 'error', - 'style/quote-props': [ 'error', 'as-needed', { - keywords: false, - unnecessary: true, - numbers: false, - }], - 'style/yield-star-spacing': [ 'error', 'after' ], - - 'ts/adjacent-overload-signatures': 'error', - 'ts/array-type': 'error', - 'ts/ban-ts-comment': [ 'error', { - 'ts-expect-error': true, - }], - 'ts/consistent-indexed-object-style': [ 'error', 'record' ], - 'ts/consistent-type-definitions': 'off', - 'ts/explicit-member-accessibility': 'error', - 'ts/method-signature-style': 'error', - 'ts/no-confusing-non-null-assertion': 'error', - 'ts/no-explicit-any': 'error', - 'ts/no-extraneous-class': [ 'error', { - allowConstructorOnly: false, - allowEmpty: false, - allowStaticOnly: false, - }], - 'ts/no-inferrable-types': [ 'error', { - ignoreParameters: false, - ignoreProperties: false, - }], - 'ts/prefer-for-of': 'error', - 'ts/prefer-function-type': 'error', - - // Only need 1 unused vars rule - 'no-unused-vars': 'off', - 'unused-imports/no-unused-vars': [ - 'error', - { args: 'after-used', vars: 'all', ignoreRestSiblings: true }, - ], - }, -}; diff --git a/eslint/test.js b/eslint/test.js deleted file mode 100644 index 5e0be0e57..000000000 --- a/eslint/test.js +++ /dev/null @@ -1,47 +0,0 @@ -const jest = require('eslint-plugin-jest'); - -// Specifically for tests -module.exports = { - name: 'opinionated/test', - // See https://github.com/jest-community/eslint-plugin-jest/issues/1408 - plugins: { - jest, - }, - rules: { - ...jest.configs.all.rules, - // Rule is not smart enough to check called function in the test - 'jest/expect-expect': 'off', - 'jest/valid-title': [ 'error', { - mustNotMatch: { - describe: /\.$/u.source, - }, - mustMatch: { - it: /\.$/u.source, - }, - }], - - // Default rules that are overkill - 'jest/no-hooks': 'off', - 'jest/max-expects': 'off', - 'jest/no-conditional-in-test': 'off', - 'jest/prefer-expect-assertions': 'off', - 'jest/prefer-importing-jest-globals': 'off', - 'jest/prefer-lowercase-title': 'off', - 'jest/prefer-strict-equal': 'off', - 'jest/require-hook': 'off', - - 'test/prefer-lowercase-title': 'off', - - 'ts/naming-convention': 'off', - 'ts/no-explicit-any': 'off', - 'ts/no-unsafe-argument': 'off', - 'ts/no-unsafe-assignment': 'off', - 'ts/no-unsafe-call': 'off', - 'ts/no-unsafe-member-access': 'off', - 'ts/no-unsafe-return': 'off', - 'ts/unbound-method': 'off', - - // Incorrectly detects usage of undefined in "toHaveBeenLastCalledWith" checks - 'unicorn/no-useless-undefined': 'off', - }, -}; diff --git a/eslint/typed.js b/eslint/typed.js deleted file mode 100644 index 092da2661..000000000 --- a/eslint/typed.js +++ /dev/null @@ -1,57 +0,0 @@ -module.exports = { - name: 'opinionated/typed', - rules: { - 'ts/consistent-type-assertions': [ 'error', { - assertionStyle: 'as', - }], - 'ts/naming-convention': [ - 'error', - { - selector: 'default', - format: [ 'camelCase' ], - leadingUnderscore: 'forbid', - trailingUnderscore: 'forbid', - }, - { - selector: 'import', - format: null, - }, - { - selector: 'variable', - format: [ 'camelCase', 'UPPER_CASE' ], - leadingUnderscore: 'forbid', - trailingUnderscore: 'forbid', - }, - { - selector: 'typeLike', - format: [ 'PascalCase' ], - }, - { - selector: [ 'typeParameter' ], - format: [ 'PascalCase' ], - prefix: [ 'T' ], - }, - ], - 'ts/explicit-function-return-type': [ 'error', { - allowExpressions: false, - allowTypedFunctionExpressions: false, - allowHigherOrderFunctions: false, - }], - 'ts/no-base-to-string': 'error', - 'ts/no-floating-promises': [ 'error', { ignoreVoid: false }], - 'ts/promise-function-async': 'error', - 'ts/no-unnecessary-boolean-literal-compare': 'error', - 'ts/no-unnecessary-qualifier': 'error', - 'ts/prefer-nullish-coalescing': 'error', - 'ts/prefer-readonly': 'error', - 'ts/prefer-reduce-type-parameter': 'error', - 'ts/prefer-regexp-exec': 'error', - // Not sure if this would make code better - 'ts/strict-boolean-expressions': 'off', - 'ts/prefer-string-starts-ends-with': 'error', - 'ts/require-array-sort-compare': 'error', - - // These are not type specific, but we only care about these in TS files - 'max-len': [ 'error', { code: 120, ignoreUrls: true }], - }, -}; diff --git a/eslint/unicorn.js b/eslint/unicorn.js deleted file mode 100644 index 8cf054908..000000000 --- a/eslint/unicorn.js +++ /dev/null @@ -1,53 +0,0 @@ -module.exports = { - name: 'opinionated/unicorn', - rules: { - 'unicorn/better-regex': 'error', - 'unicorn/empty-brace-spaces': 'error', - 'unicorn/consistent-function-scoping': 'error', - 'unicorn/expiring-todo-comments': [ 'error', { - ignoreDatesOnPullRequests: false, - terms: [ 'todo' ], - allowWarningComments: false, - }], - 'unicorn/explicit-length-check': 'error', - 'unicorn/new-for-builtins': 'error', - 'unicorn/no-array-for-each': 'error', - 'unicorn/no-array-reduce': 'error', - 'unicorn/no-for-loop': 'error', - 'unicorn/no-invalid-remove-event-listener': 'error', - 'unicorn/no-lonely-if': 'error', - 'unicorn/no-negated-condition': 'error', - 'unicorn/no-nested-ternary': 'error', - 'unicorn/no-object-as-default-parameter': 'error', - 'unicorn/no-process-exit': 'error', - 'unicorn/no-thenable': 'error', - 'unicorn/no-useless-fallback-in-spread': 'error', - 'unicorn/no-useless-length-check': 'error', - 'unicorn/no-useless-promise-resolve-reject': 'error', - 'unicorn/no-useless-spread': 'error', - 'unicorn/no-useless-undefined': 'error', - 'unicorn/no-zero-fractions': 'error', - 'unicorn/prefer-array-find': 'error', - 'unicorn/prefer-array-flat-map': 'error', - 'unicorn/prefer-array-index-of': 'error', - 'unicorn/prefer-array-some': 'error', - 'unicorn/prefer-at': 'error', - 'unicorn/prefer-code-point': 'error', - 'unicorn/prefer-date-now': 'error', - 'unicorn/prefer-default-parameters': 'error', - 'unicorn/prefer-math-trunc': 'error', - 'unicorn/prefer-native-coercion-functions': 'error', - 'unicorn/prefer-negative-index': 'error', - 'unicorn/prefer-object-from-entries': 'error', - 'unicorn/prefer-optional-catch-binding': 'error', - 'unicorn/prefer-reflect-apply': 'error', - 'unicorn/prefer-regexp-test': 'error', - 'unicorn/prefer-set-has': 'error', - 'unicorn/prefer-set-size': 'error', - 'unicorn/prefer-spread': 'error', - 'unicorn/prefer-string-replace-all': 'error', - 'unicorn/prefer-string-slice': 'error', - 'unicorn/require-array-join-separator': 'error', - 'unicorn/require-number-to-fixed-digits-argument': 'error', - }, -}; diff --git a/package-lock.json b/package-lock.json index 6376bfa29..63884be98 100644 --- a/package-lock.json +++ b/package-lock.json @@ -82,7 +82,6 @@ "community-solid-server": "bin/server.js" }, "devDependencies": { - "@antfu/eslint-config": "2.21.3", "@commitlint/cli": "^19.3.0", "@commitlint/config-conventional": "^19.2.2", "@inrupt/solid-client-authn-core": "^2.0.0", @@ -93,7 +92,6 @@ "@types/supertest": "^2.0.14", "commit-and-tag-version": "^11.3.0", "componentsjs-generator": "^3.1.2", - "eslint-plugin-jest": "^28.6.0", "husky": "^4.3.8", "jest": "^29.7.0", "jest-esm-transformer-2": "^1.0.0", @@ -101,6 +99,7 @@ "markdownlint-cli2": "^0.13.0", "node-mocks-http": "^1.13.0", "nodemon": "^3.0.1", + "opinionated-eslint-config": "0.1.0", "set-cookie-parser": "^2.6.0", "simple-git": "^3.20.0", "supertest": "^6.3.3", @@ -1122,7 +1121,7 @@ }, "node_modules/@clack/prompts/node_modules/is-unicode-supported": { "version": "1.3.0", - "dev": true, + "extraneous": true, "inBundle": true, "license": "MIT", "engines": { @@ -14219,6 +14218,16 @@ "url": "https://github.com/sponsors/panva" } }, + "node_modules/opinionated-eslint-config": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/opinionated-eslint-config/-/opinionated-eslint-config-0.1.0.tgz", + "integrity": "sha512-z6QHgG4I8I6XSHVss2PzjO4R4gvmvQrwqTNrMFj94I2+BZP5ZU6q/bVqlhRI0oGvGJTfZr/2bl0SXkufOrPt2g==", + "dev": true, + "dependencies": { + "@antfu/eslint-config": "2.21.3", + "eslint-plugin-jest": "28.6.0" + } + }, "node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -17716,7 +17725,7 @@ "is-unicode-supported": { "version": "1.3.0", "bundled": true, - "dev": true + "extraneous": true } } }, @@ -28073,6 +28082,16 @@ "oidc-token-hash": "^5.0.3" } }, + "opinionated-eslint-config": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/opinionated-eslint-config/-/opinionated-eslint-config-0.1.0.tgz", + "integrity": "sha512-z6QHgG4I8I6XSHVss2PzjO4R4gvmvQrwqTNrMFj94I2+BZP5ZU6q/bVqlhRI0oGvGJTfZr/2bl0SXkufOrPt2g==", + "dev": true, + "requires": { + "@antfu/eslint-config": "2.21.3", + "eslint-plugin-jest": "28.6.0" + } + }, "optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", diff --git a/package.json b/package.json index ee8404f6b..d3e3f141f 100644 --- a/package.json +++ b/package.json @@ -143,7 +143,6 @@ "yup": "^1.3.2" }, "devDependencies": { - "@antfu/eslint-config": "2.21.3", "@commitlint/cli": "^19.3.0", "@commitlint/config-conventional": "^19.2.2", "@inrupt/solid-client-authn-core": "^2.0.0", @@ -154,7 +153,6 @@ "@types/supertest": "^2.0.14", "commit-and-tag-version": "^11.3.0", "componentsjs-generator": "^3.1.2", - "eslint-plugin-jest": "^28.6.0", "husky": "^4.3.8", "jest": "^29.7.0", "jest-esm-transformer-2": "^1.0.0", @@ -162,6 +160,7 @@ "markdownlint-cli2": "^0.13.0", "node-mocks-http": "^1.13.0", "nodemon": "^3.0.1", + "opinionated-eslint-config": "0.1.0", "set-cookie-parser": "^2.6.0", "simple-git": "^3.20.0", "supertest": "^6.3.3", From 6b8223ba9c40c925940daa3f560357a94934d02e Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Thu, 18 Jul 2024 15:05:11 +0200 Subject: [PATCH 58/71] chore: Update ts-node --- package-lock.json | 18 ++++++++---------- package.json | 2 +- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 63884be98..97947be6f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -104,7 +104,7 @@ "simple-git": "^3.20.0", "supertest": "^6.3.3", "ts-jest": "^29.1.1", - "ts-node": "^10.9.1", + "ts-node": "^10.9.2", "typedoc": "^0.26.4", "typescript": "^5.5.3" }, @@ -1121,7 +1121,6 @@ }, "node_modules/@clack/prompts/node_modules/is-unicode-supported": { "version": "1.3.0", - "extraneous": true, "inBundle": true, "license": "MIT", "engines": { @@ -16329,9 +16328,9 @@ } }, "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", @@ -17724,8 +17723,7 @@ "dependencies": { "is-unicode-supported": { "version": "1.3.0", - "bundled": true, - "extraneous": true + "bundled": true } } }, @@ -29717,9 +29715,9 @@ } }, "ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, "requires": { "@cspotcode/source-map-support": "^0.8.0", diff --git a/package.json b/package.json index d3e3f141f..f2827486f 100644 --- a/package.json +++ b/package.json @@ -165,7 +165,7 @@ "simple-git": "^3.20.0", "supertest": "^6.3.3", "ts-jest": "^29.1.1", - "ts-node": "^10.9.1", + "ts-node": "^10.9.2", "typedoc": "^0.26.4", "typescript": "^5.5.3" }, From e45bce89aabc95b34ecbefcf46f899a88e60cfef Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Tue, 11 Jun 2024 08:53:45 +0200 Subject: [PATCH 59/71] docs: Add more explicit installation instructions --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1af55d574..b9fe79efa 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,9 @@ And, of course, for many others who like to experience Solid. ## ⚡ Running the Community Solid Server -Use [Node.js](https://nodejs.org/en/) 18.0 or up and execute: +Make sure you have [Node.js](https://nodejs.org/en/) 18.0 or higher. +If this is your first time using Node.js, +you can find instructions on how to do this [here](https://nodejs.org/en/download/package-manager). ```shell npx @solid/community-server @@ -45,7 +47,9 @@ To persist your pod's contents between restarts, use: npx @solid/community-server -c @css:config/file.json -f data/ ``` -Find more ways to run the server in the [documentation](https://communitysolidserver.github.io/CommunitySolidServer/latest/usage/starting-server/). +In case you prefer to use Docker instead, +you can find instructions for this and other methods in the +[documentation](https://communitysolidserver.github.io/CommunitySolidServer/latest/usage/starting-server/). ## 🔧 Configure your server From 3aa28fa03b4d1324998e7f6a5ebe5788d0e6b2c9 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Tue, 11 Jun 2024 11:40:40 +0200 Subject: [PATCH 60/71] docs: Add test instructions to documentation --- documentation/markdown/features/test.md | 75 +++++++++++++++++++++++++ documentation/mkdocs.yml | 3 +- 2 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 documentation/markdown/features/test.md diff --git a/documentation/markdown/features/test.md b/documentation/markdown/features/test.md new file mode 100644 index 000000000..f0147190a --- /dev/null +++ b/documentation/markdown/features/test.md @@ -0,0 +1,75 @@ +# Testing the server + +There are several test sets in place to ensure the server conforms to the necessary requirements, +and to prevent changes from breaking this. + +## Unit tests + +For every TypeScript file, +most of which correspond to a single class implementation, +there is a corresponding unit test file in the `test/unit` folder. +These tests require 100% code coverage over the corresponding implementation, +making sure every line is checked. + +These tests can be run using the `npm run test:unit` script. + +## Integration tests + +The `test/integration` folder contains several test suites that set up a complete server instance +and validate its functionality. +`test/intergration/config` contains the configurations used by these test suites. +These make sure that no features get lost after changes are made to the server. + +These tests can be run using the `npm run test:integration` script. + +## Specification conformance + +To make sure the server conforms to the Solid specification, +we run the [Conformance Test Harness (CTH)](https://github.com/solid-contrib/conformance-test-harness) +combined with the [specification test suite](https://github.com/solid-contrib/specification-tests/). +This test suite was made specifically so any Solid server can be tested +on how well it conforms to the Solid specifications. +The configuration that runs these tests in the repository can be found [here](https://github.com/CommunitySolidServer/CommunitySolidServer/blob/main/.github/workflows/cth-test.yml). + +You can also run this test suite locally. +Besides the standard requirements for running the server, +this also requires Docker. +First make sure you have a running CSS instance, +in this example we will assume it is running at `http://localhost:3000`. +After that you can run the following commands. +The paths are relative to the root folder of your CSS source folder, +and should be adjusted accordingly if you are not running this from the source folder. + +```bash +# Generate the folder where the reports will be located +mkdir -p ../conformance/reports/css + +# Pull the CTH Docker image +docker pull solidproject/conformance-test-harness + +# Set up the env file necessary for the CTH +echo 'SOLID_IDENTITY_PROVIDER=http://localhost:3000/idp/ +USERS_ALICE_WEBID=http://localhost:3000/alice/profile/card#me +USERS_BOB_WEBID=http://localhost:3000/bob/profile/card#me +RESOURCE_SERVER_ROOT=http://localhost:3000 +TEST_CONTAINER=/alice/ +quarkus.log.category."ResultLogger".level=INFO +quarkus.log.category."com.intuit.karate".level=DEBUG +quarkus.log.category."org.solid.testharness.http.Client".level=DEBUG +quarkus.log.category."org.solid.testharness.http.AuthManager".level=DEBUG +MAXTHREADS=1' > ../conformance/conformance.env + +# Generate the test users required by the CTH on the server to be tested +npx ts-node test/deploy/createAccountCredentials.ts http://localhost:3000/ >> ../conformance/conformance.env + +# Run the CTH +docker run -i --rm \ + -v $(pwd)/../conformance/reports/css:/reports \ + --env-file=../conformance/conformance.env \ + --network="host" \ + solidproject/conformance-test-harness \ + --skip-teardown \ + --output=/reports \ + --target=https://github.com/solid/conformance-test-harness/css +``` +When this process is finished you can find the conformance report in the `../reports/css` folder. diff --git a/documentation/mkdocs.yml b/documentation/mkdocs.yml index 70019bb1f..ad70d9b76 100644 --- a/documentation/mkdocs.yml +++ b/documentation/mkdocs.yml @@ -78,7 +78,8 @@ nav: - Welcome: - README.md - Features: - - features.md + - Overview: features.md + - Tests: features/test.md - Usage: - Starting the server: usage/starting-server.md - Example request: usage/example-requests.md From ed6f2ec8e953e84efa6701482d00f616cf6ecbc2 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Wed, 12 Jun 2024 13:57:31 +0200 Subject: [PATCH 61/71] docs: Explain the provided configs --- config/README.md | 145 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 100 insertions(+), 45 deletions(-) diff --git a/config/README.md b/config/README.md index 4b03b91be..dd8784a27 100644 --- a/config/README.md +++ b/config/README.md @@ -1,67 +1,122 @@ # Configuration This folder contains several configurations that can be used to start up the server. +These can be used directly, or used as inspiration on how you would want to configure your server. All those configurations are created in the same way: features are enabled or disabled by choosing a specific option for every component. All components are represented by the subfolders found in the folders here: `ldp` contains all LDP related components, `identity` all IDP components, etc. Options are then chosen by importing 1 entry from every component subfolder. -In case none of the available options have the exact feature configuration you want, -it is always possible to not choose any of them and create your own custom version instead. +More information on how this can be done manually, +can be found in this [tutorial](https://github.com/CommunitySolidServer/tutorials/blob/main/custom-configurations.md). -## How to use +As manually changing server options can be cumbersome, +there is also an online [configuration generator](https://communitysolidserver.github.io/configuration-generator/). -The easiest way to create a new config is by creating a JSON-LD file -that imports one option from every component subfolder -(such as either `allow-all.json` or `webacl.json` from `ldp/authorization`). -In case none of the available options suffice, there are 2 other ways to handle this: +Below we give an overview of the main identifying features of the configurations. +We start with all features of the default configuration, +after which we will explain in which features the other ones differ from it. -### Append to an existing config +## default.json -In case the options mostly suffice, but they just need to do a bit more, -it might be possible to append to one of the solutions. +This is the configuration that is used if no configuration is provided when starting the server. +It stores all data in memory, so this server is perfect for quickly trying some things out, +but not if you want a persistent server. -For example, in case all the existing metadata parsers can remain, -but an additional one needs to be added, -you could import `ldp/metadata-parser/default.json` -and then add the following in your root config: +For authorization, it uses [Web Access Control (WAC)](https://solid.github.io/web-access-control-spec/), +it supports all [notification methods](https://solidproject.org/TR/notifications-protocol) implemented in CSS, +allows users to create accounts, pods, WebIDs, and use them for [Solid-OIDC](https://solid.github.io/solid-oidc/). -```json -{ - "@id": "urn:solid-server:default:MetadataParser", - "@type": "ParallelHandler", - "handlers": [ - { "@type": "MyNewParser" } - ] -} -``` +It is also initialized with an `index.html` page at root level, +with permissions set in such a way that everyone has full access to the server. -This will add the new parser to the list of metadata parsers. -The `@id` value is needed so Components.js knows which object to add the values to, -and the `@type` is needed so it can interpret the other fields (`handlers` in this case). +Although strictly not allowed by the Solid specification, +this configuration allows users to both write data at root level of the server, +and also create pods in subcontainers. +In all other configurations only or the other (or neither) will be allowed, +but here both are enabled for maximum flexibility when testing things out. -Note that generally it is only advised to append to ParallelHandlers or key/value maps. -In case the order is important this can not be guaranteed over separate files. +## file.json -### Create a new option +The most important difference with the `default.json` configuration is that this one stores its data as files on disk, +thereby making the data persistent. +Besides that, it also prevents data from being written to the root, +the only way to add data is to create a pod and add data there. +To still show something at root level when the server is started, +a static page is shown which can not be modified using standard Solid requests. -If a more drastic change is required, -the solution is to not import anything from that folder but instead write your own. +## file-acp.json -For example, in case you only want the slug parser but not any of the others, -you would have to not import anything from `ldp/metadata-parser` folder, -but instead have the following in your root config: +The only difference with `file.json`is that this uses +[Access Control Policy (ACP)](https://solid.github.io/authorization-panel/acp-specification/) +for authorization instead of WAC. -```json -{ - "@id": "urn:solid-server:default:MetadataParser", - "@type": "ParallelHandler", - "handlers": [ - { "@type": "SlugParser" } - ] -} -``` +## file-root.json -Don't forget that in some cases you would also have to copy some imports! -The existing options can be used as inspiration. +This configuration starts from `file.json`, but does not allow the creation of accounts. +Instead, it allows data to be written directly to the root of the server. +To make sure users can write data there after starting the server, +permissions have been set to grant everyone full access, +so this needs to be changed after starting the server. + +## file-root-pod.json + +The same idea as `file-root.json`, +but here it is done by creating an account with a pod +in the root of the server the first time it is started. +The credentials to this account are stored in the configuration so should be changed afterwards. +This has the advantage of both having your data at root level, +but also allowing you to authenticate using Solid-OIDC. + +## https-file-cli.json + +A variant of `file.json` that uses HTTPS of HTTP. +The required key and cert file paths need to be defined using two new CLI options: `--httpsKey` and `-httpCert`. + +## example-https-file.json + +Another way to define HTTPS, but this time through the configuration file itself instead of the CLI. +As can be seen in the configuration itself, two paths are defined, pointing to the key and cert files. +To actually use this solution, you need to update the paths in that file before running the server. + +## sparql-endpoint.json + +Sets up a server that uses a SPARQL endpoint to store the data. +Only RDF data can be stored on a server using this configuration. +For internal data, such as accounts, temporary OIDC resources, etc, +the servers uses non-RDF data formats. +While other configurations store this kind of data in the same backend as the Solid data, +this is not feasible when using a SPARQL endpoint. +For this reason, this configuration stores all that data in memory, +meaning this solution should not be used if you want persistent accounts. + +## sparql-endpoint-root.json + +This differs from `sparql-endpoint.json` in the same way as `file-root.json` differs from `file.json`. + +## sparql-file-storage.json + +Similar to `sparql-endpoint.json` with the main difference being +that here internal data is stored on disk instead of in memory. + +## memory-subdomains.json + +A memory-based server whose main differentiating feature is how pod URLs are constructed. +In most other configurations, pods are created by appending the chosen name to the base URL of the server, +so for a server running at `http://example.com/`, +choosing the name `test` for your pod would result in `http://example.com/test/`. +With this configuration, the name is used as a subdomain of the url instead, +so the above values would result in a pod at `http://test.example.com/` instead. + +## quota-file.json + +A file-based server that limits the amount of data a user can put in a pod. +The values in the configuration determine the limit. + +## path-routing.json + +This configuration serves as an example of how a server can be configured +to serve data from different backends depending on the URL that is used. +In this example, all data in the `/sparql/` container will be stored in a SPARQL backend, +and similarly for `/memory/` and `/file/`. From ab419674df5a92054128588747c3abc06086c3ab Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Thu, 13 Jun 2024 09:21:45 +0200 Subject: [PATCH 62/71] docs: Explain WAC vs ACP --- documentation/markdown/README.md | 1 + .../markdown/usage/authorization-methods.md | 36 +++++++++++++++++++ documentation/mkdocs.yml | 1 + 3 files changed, 38 insertions(+) create mode 100644 documentation/markdown/usage/authorization-methods.md diff --git a/documentation/markdown/README.md b/documentation/markdown/README.md index be410a27c..b69754b8c 100644 --- a/documentation/markdown/README.md +++ b/documentation/markdown/README.md @@ -38,6 +38,7 @@ the [changelog](https://github.com/CommunitySolidServer/CommunitySolidServer/blo * [How to automatically seed pods on startup](usage/seeding-pods.md) * [Receiving notifications when resources change](usage/notifications.md) * [Using the CSS as a development server in another project](usage/dev-configuration.md) +* [Which authorization method to pick](usage/authorization-methods.md) ## What the internals look like diff --git a/documentation/markdown/usage/authorization-methods.md b/documentation/markdown/usage/authorization-methods.md new file mode 100644 index 000000000..0bd55965f --- /dev/null +++ b/documentation/markdown/usage/authorization-methods.md @@ -0,0 +1,36 @@ +# Choosing the authorization method for your server + +The CSS comes with support for two different authorization solutions: +[Web Access Control (WAC)](https://solidproject.org/TR/wac) +and [Access Control Policy (ACP)](https://solid.github.io/authorization-panel/acp-specification/). +When configuring a server, one of these needs to be picked if you do not want everyone to have full access to your data. +Both of these are similar in that they both make use of RDF resources to describe who can access which documents, + +WAC is the older specification of the two, +it was designed together with the beginning of the Solid specification. +Because of that, there is more tooling available that can interpret the corresponding authorization resources, +potentially making it easier to get started with Solid development. + +ACP is a more recent specification, +that was made to address certain concerns within WAC. +ACP provides more options in how to define who gets to access your data, +allowing you to have better security. + +When using WAC, you define which WebIDs have access to certain data. +When you then authenticate with a Solid client, +that client will identify with your WebID, +indicating to the server that it is allowed to access that data. +The problem is that there is no (safe) way to differentiate between clients. +This means that if you use a client to store your favorite movies in your pod, +and another one to store your bank details, +the movie client would be able to access your bank details if it was malicious. +ACP on the other hand allows you to set more specific restrictions, +where clients also have to identify themselves. +This way you can make sure the movie client can only access movie data. + +Currently, the CSS still enables WAC in most of the configurations bundled with the server, +as we want the server to be easily accessible for newer users, +for whom the chances are higher they are using apps only compatible with WAC. +However, we are planning to eventually phase this out in favor of ACP, +starting with logged warnings when WAC is enabled, +and in the end changing the bundled configurations to use ACP instead. diff --git a/documentation/mkdocs.yml b/documentation/mkdocs.yml index ad70d9b76..f69d9c234 100644 --- a/documentation/mkdocs.yml +++ b/documentation/mkdocs.yml @@ -93,6 +93,7 @@ nav: - Seeding pods: usage/seeding-pods.md - Notifications: usage/notifications.md - Development server: usage/dev-configuration.md + - Authorization methods: usage/authorization-methods.md - Architecture: - Overview: architecture/overview.md - Dependency injection: architecture/dependency-injection.md From 73619fda056d5a9b0b0fac271f29fbced0424169 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Fri, 28 Jun 2024 10:34:03 +0200 Subject: [PATCH 63/71] docs: Explain oidc.json --- config/README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/config/README.md b/config/README.md index dd8784a27..42d54f03e 100644 --- a/config/README.md +++ b/config/README.md @@ -120,3 +120,10 @@ This configuration serves as an example of how a server can be configured to serve data from different backends depending on the URL that is used. In this example, all data in the `/sparql/` container will be stored in a SPARQL backend, and similarly for `/memory/` and `/file/`. + +## oidc.json + +A configuration that sets up the server to only function as an Identity Provider. +It does not support creating pods or storing data on the server, +the only available options are creating accounts and linking them to WebIDs. +This way the server can be used to identify those WebIDs during an OIDC interaction. From 9c44f375f2537fa0277a6c6831c63c1c1cfc5373 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Mon, 1 Jul 2024 09:28:48 +0200 Subject: [PATCH 64/71] docs: Update server architecture documentation --- .../architecture/features/initialization.md | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/documentation/markdown/architecture/features/initialization.md b/documentation/markdown/architecture/features/initialization.md index 6ba829f80..59f5ca19b 100644 --- a/documentation/markdown/architecture/features/initialization.md +++ b/documentation/markdown/architecture/features/initialization.md @@ -108,32 +108,33 @@ to add any custom initializers that need to run. The `ServerInitializer` is the initializer that finally starts up the server by listening to the relevant port, once all the initialization described above is finished. -It takes as input 2 components: a `HttpServerFactory` and a `ServerListener`. +To do this it makes use of an `HttpServerFactory`. ```mermaid flowchart TD ServerInitializer("ServerInitializer
ServerInitializer") - ServerInitializer --> ServerInitializerArgs + ServerInitializer --> ServerFactory("ServerFactory
BaseServerFactory") + ServerFactory --> ServerConfigurator("ServerConfigurator
ParallelHandler") + ServerConfigurator --> ServerConfiguratorArgs - subgraph ServerInitializerArgs[" "] + subgraph ServerConfiguratorArgs[" "] direction LR - ServerFactory("ServerFactory
BaseServerFactory") - ServerListener("ServerListener
ParallelHandler") + HandlerServerConfigurator("HandlerServerConfigurator
HandlerServerConfigurator") + WebSocketServerConfigurator("WebSocketServerConfigurator
WebSocketServerConfigurator") end - ServerListener --> HandlerServerListener("HandlerServerListener
HandlerServerListener") - - HandlerServerListener --> HttpHandler("HttpHandler
HttpHandler") + HandlerServerConfigurator --> HttpHandler("HttpHandler
HttpHandler") + WebSocketServerConfigurator --> WebSocketHandler("WebSocketHandler
WebSocketHandler") ``` The `HttpServerFactory` is responsible for starting a server on a given port. Depending on the configuration this can be an HTTP or an HTTPS server. The created server emits events when it receives requests. -A `ServerListener` is a class that takes the created server as input and attaches a listener to interpret events. -One listener that is always used is the `urn:solid-server:default:HandlerServerListener`, -which calls an `HttpHandler` [to resolve HTTP requests](http-handler.md). - -Sometimes it is necessary to add additional listeners, -these can then be added to the `urn:solid-server:default:ServerListener` as it is a `ParallellHandler`. -An example of this is when WebSockets are used [to handle notifications](notifications.md). +Any requests it receives, it sends to its `ServerConfigurator`, +which handles the request as needed. +This is a `ParallelHandler`, supporting two kinds of requests: +HTTP requests go through a configurator that sends those +to an `HttpHandler` [to resolve HTTP requests](http-handler.md). +In case WebSockets are enabled [to handle notifications](notifications.md), +these are handled by the `WebSocketHandler`. From 576eefede63937f08b831b1e49cafe4a96a716f7 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Mon, 1 Jul 2024 09:28:59 +0200 Subject: [PATCH 65/71] docs: Add missing newline --- documentation/markdown/features/test.md | 1 + 1 file changed, 1 insertion(+) diff --git a/documentation/markdown/features/test.md b/documentation/markdown/features/test.md index f0147190a..665d72e31 100644 --- a/documentation/markdown/features/test.md +++ b/documentation/markdown/features/test.md @@ -72,4 +72,5 @@ docker run -i --rm \ --output=/reports \ --target=https://github.com/solid/conformance-test-harness/css ``` + When this process is finished you can find the conformance report in the `../reports/css` folder. From 3dd8602acce892b36d1ecaf584c938032e754213 Mon Sep 17 00:00:00 2001 From: elf Pavlik Date: Fri, 2 Aug 2024 15:50:07 -0600 Subject: [PATCH 66/71] fix: Ensure streaming HTTP streams the whole notification in a single chunk --- .../StreamingHttp2023Emitter.ts | 5 +- .../StreamingHttpRequestHandler.ts | 5 +- .../StreamingHttp2023Emitter.test.ts | 49 +++++++++++++------ .../StreamingHttpRequestHandler.test.ts | 36 ++++++++++++-- 4 files changed, 73 insertions(+), 22 deletions(-) diff --git a/src/server/notifications/StreamingHttpChannel2023/StreamingHttp2023Emitter.ts b/src/server/notifications/StreamingHttpChannel2023/StreamingHttp2023Emitter.ts index 873bd3e82..8b0c541ca 100644 --- a/src/server/notifications/StreamingHttpChannel2023/StreamingHttp2023Emitter.ts +++ b/src/server/notifications/StreamingHttpChannel2023/StreamingHttp2023Emitter.ts @@ -1,6 +1,7 @@ import { getLoggerFor } from '../../../logging/LogUtil'; import type { Representation } from '../../../http/representation/Representation'; import { AsyncHandler } from '../../../util/handlers/AsyncHandler'; +import { readableToString } from '../../../util/StreamUtil'; import type { NotificationChannel } from '../NotificationChannel'; import type { StreamingHttpMap } from './StreamingHttpMap'; @@ -27,8 +28,10 @@ export class StreamingHttp2023Emitter extends AsyncHandler { const channel: NotificationChannel = { @@ -13,32 +13,31 @@ describe('A StreamingHttp2023Emitter', (): void => { topic: 'http://example.com/foo', type: 'type', }; + const chunk = 'notification'; let stream: jest.Mocked; let streamMap: StreamingHttpMap; let emitter: StreamingHttp2023Emitter; + let representation: BasicRepresentation; beforeEach(async(): Promise => { stream = jest.mocked(new PassThrough()); - streamMap = new WrappedSetMultiMap(); - emitter = new StreamingHttp2023Emitter(streamMap); + representation = new BasicRepresentation(chunk, 'text/plain'); }); it('emits notifications to the stored Streams.', async(): Promise => { streamMap.add(channel.topic, stream); - const representation = new BasicRepresentation('notification', 'text/plain'); - const spy = jest.spyOn(representation.data, 'pipe'); + const spy = jest.spyOn(stream, 'write'); await expect(emitter.handle({ channel, representation })).resolves.toBeUndefined(); expect(spy).toHaveBeenCalledTimes(1); - expect(spy).toHaveBeenLastCalledWith(stream, { end: false }); + expect(spy).toHaveBeenLastCalledWith(chunk); }); it('destroys the representation if there is no matching Stream.', async(): Promise => { - const representation = new BasicRepresentation('notification', 'text/plain'); - const spy = jest.spyOn(representation.data, 'pipe'); + const spy = jest.spyOn(stream, 'write'); await expect(emitter.handle({ channel, representation })).resolves.toBeUndefined(); expect(spy).toHaveBeenCalledTimes(0); expect(representation.data.destroyed).toBe(true); @@ -50,12 +49,13 @@ describe('A StreamingHttp2023Emitter', (): void => { streamMap.add(channel.topic, stream); streamMap.add(channel.topic, stream2); - const representation = new BasicRepresentation('notification', 'text/plain'); - const spy = jest.spyOn(representation.data, 'pipe'); + const spy = jest.spyOn(stream, 'write'); + const spy2 = jest.spyOn(stream2, 'write'); await expect(emitter.handle({ channel, representation })).resolves.toBeUndefined(); - expect(spy).toHaveBeenCalledTimes(2); - expect(spy).toHaveBeenCalledWith(stream, { end: false }); - expect(spy).toHaveBeenLastCalledWith(stream2, { end: false }); + expect(spy).toHaveBeenCalledTimes(1); + expect(spy).toHaveBeenCalledWith(chunk); + expect(spy2).toHaveBeenCalledTimes(1); + expect(spy2).toHaveBeenCalledWith(chunk); }); it('only writes to the matching topic Streams.', async(): Promise => { @@ -69,10 +69,27 @@ describe('A StreamingHttp2023Emitter', (): void => { streamMap.add(channel.topic, stream); streamMap.add(channel2.topic, stream2); - const representation = new BasicRepresentation('notification', 'text/plain'); - const spy = jest.spyOn(representation.data, 'pipe'); + const spy = jest.spyOn(stream, 'write'); + const spy2 = jest.spyOn(stream2, 'write'); await expect(emitter.handle({ channel, representation })).resolves.toBeUndefined(); expect(spy).toHaveBeenCalledTimes(1); - expect(spy).toHaveBeenLastCalledWith(stream, { end: false }); + expect(spy).toHaveBeenLastCalledWith(chunk); + expect(spy2).not.toHaveBeenCalled(); + }); + + it('emits notifications in a single chunk.', async(): Promise => { + streamMap.add(channel.topic, stream); + const serializationStream = new PassThrough(); + // Use two chunks for the serialization stream + serializationStream.write('foo'); + serializationStream.end('bar'); + representation = { + data: serializationStream, + } as unknown as Representation; + + const spy = jest.spyOn(stream, 'write'); + await expect(emitter.handle({ channel, representation })).resolves.toBeUndefined(); + expect(spy).toHaveBeenCalledTimes(1); + expect(spy).toHaveBeenLastCalledWith('foobar'); }); }); diff --git a/test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttpRequestHandler.test.ts b/test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttpRequestHandler.test.ts index 246cb6970..756297008 100644 --- a/test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttpRequestHandler.test.ts +++ b/test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttpRequestHandler.test.ts @@ -1,3 +1,4 @@ +import { PassThrough } from 'node:stream'; import type { CredentialsExtractor } from '../../../../../src/authentication/CredentialsExtractor'; import type { Authorizer } from '../../../../../src/authorization/Authorizer'; import type { PermissionReader } from '../../../../../src/authorization/PermissionReader'; @@ -20,6 +21,8 @@ import { StreamingHttpMap } from '../../../../../src'; import type { Notification } from '../../../../../src/server/notifications/Notification'; import { flushPromises } from '../../../../util/Util'; +import * as GuardedStream from '../../../../../src/util/GuardedStream'; + jest.mock('../../../../../src/logging/LogUtil', (): any => { const logger: Logger = { error: jest.fn(), debug: jest.fn() } as any; return { getLoggerFor: (): Logger => logger }; @@ -45,9 +48,10 @@ describe('A StreamingHttpRequestHandler', (): void => { published: '123', state: '"123456-text/turtle"', }; - const representation = new BasicRepresentation(); + const chunk = 'notification'; const request: HttpRequest = {} as any; const response: HttpResponse = {} as any; + let representation: BasicRepresentation; let streamMap: StreamingHttpMap; let operation: Operation; let generator: jest.Mocked; @@ -64,6 +68,7 @@ describe('A StreamingHttpRequestHandler', (): void => { body: new BasicRepresentation(), preferences: {}, }; + representation = new BasicRepresentation(chunk, 'text/plain'); streamMap = new StreamingHttpMap(); @@ -129,10 +134,33 @@ describe('A StreamingHttpRequestHandler', (): void => { expect(description.data).toBeDefined(); }); - it('sends initial notification.', async(): Promise => { - const spy = jest.spyOn(representation.data, 'pipe'); + it('sends initial notification in a single chunk.', async(): Promise => { + const mockStream = { + write: jest.fn(), + on: jest.fn(), + } as unknown as GuardedStream.Guarded; + jest.spyOn(GuardedStream, 'guardStream').mockReturnValueOnce(mockStream); + const serializationStream = new PassThrough(); + // Use two chunks for the serialization stream + serializationStream.write('foo'); + serializationStream.end('bar'); + serializer = { + handleSafe: jest.fn().mockResolvedValue({ + data: serializationStream, + }), + } as any; + handler = new StreamingHttpRequestHandler( + streamMap, + pathPrefix, + generator, + serializer, + credentialsExtractor, + permissionReader, + authorizer, + ); await handler.handle({ operation, request, response }); - expect(spy).toHaveBeenCalledTimes(1); + expect(mockStream.write).toHaveBeenCalledTimes(1); + expect(mockStream.write).toHaveBeenCalledWith('foobar'); }); it('logs an error if sending initial notification fails.', async(): Promise => { From b93aa31c932935c21f1e3666fdab3d0947a645eb Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Wed, 7 Aug 2024 08:42:32 +0200 Subject: [PATCH 67/71] chore: Use correct markdownlint-cli2 fix command --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index f2827486f..bf8f87399 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,6 @@ "lint": "npm run lint:eslint && npm run lint:markdown", "lint:eslint": "eslint . --cache --max-warnings 0", "lint:markdown": "markdownlint-cli2", - "lint:markdown:fix": "markdownlint-cli2-fix", "prepare": "npm run build", "release": "commit-and-tag-version", "postrelease": "ts-node ./scripts/finalizeRelease.ts", @@ -178,7 +177,7 @@ "commit-and-tag-version": { "scripts": { "postbump": "ts-node ./scripts/upgradeConfig.ts", - "postchangelog": "ts-node ./scripts/formatChangelog.ts && markdownlint-cli2-fix" + "postchangelog": "ts-node ./scripts/formatChangelog.ts && markdownlint-cli2 --fix" }, "writerOpts": { "commitsSort": false From e15c59c157882181340fa87a7116b5b34252a79b Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Wed, 7 Aug 2024 08:53:38 +0200 Subject: [PATCH 68/71] chore: Increase jest timeout --- jest.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jest.config.js b/jest.config.js index 8aa7e84f2..9a1666bd8 100644 --- a/jest.config.js +++ b/jest.config.js @@ -70,7 +70,7 @@ module.exports = { '^jose/(.*)$': '/node_modules/jose/dist/node/cjs/$1', }, // Slower machines had problems calling the WebSocket integration callbacks on time - testTimeout: 60000, + testTimeout: 90000, reporters: ci ? [ 'default', 'github-actions' ] : [ 'default' ], ...ci && jestGithubRunnerSpecs(), From 4599bf413e0ca08725d22b5e01fe43e97ef7d714 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Wed, 7 Aug 2024 09:00:37 +0200 Subject: [PATCH 69/71] chore(release): Release version 7.1.1 of the npm package --- CHANGELOG.md | 23 +++++++++++++++++++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5be9d752..230cfc643 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,29 @@ All notable changes to this project will be documented in this file. +## [7.1.1](https://github.com/CommunitySolidServer/CommunitySolidServer/compare/v7.1.0...v7.1.1) (2024-08-07) + +### Fixes + +* Ensure streaming HTTP streams the whole notification in a single chunk ([3dd8602](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/3dd8602acce892b36d1ecaf584c938032e754213)) + +### Chores + +* Increase jest timeout ([e15c59c](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/e15c59c157882181340fa87a7116b5b34252a79b)) +* Use correct markdownlint-cli2 fix command ([b93aa31](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/b93aa31c932935c21f1e3666fdab3d0947a645eb)) +* Depend on external eslint package ([46f5fc2](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/46f5fc239efa794f5309834fa818d17c96f83bd1)) + +### Documentation + +* Update server architecture documentation ([9c44f37](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/9c44f375f2537fa0277a6c6831c63c1c1cfc5373)) +* Explain oidc.json ([73619fd](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/73619fda056d5a9b0b0fac271f29fbced0424169)) +* Explain WAC vs ACP ([ab41967](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/ab419674df5a92054128588747c3abc06086c3ab)) +* Explain the provided configs ([ed6f2ec](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/ed6f2ec8e953e84efa6701482d00f616cf6ecbc2)) +* Add test instructions to documentation ([3aa28fa](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/3aa28fa03b4d1324998e7f6a5ebe5788d0e6b2c9)) +* Add more explicit installation instructions ([e45bce8](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/e45bce89aabc95b34ecbefcf46f899a88e60cfef)) +* Add missing index for starting the server ([d350c14](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/d350c140fd184d33cbaf6880b9d4b1476d1ffb7c)) +* Add HTTP streaming notification option to docs ([556899d](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/556899dbdbf3bb285de71225d156c4891dce23a9)) + ## [7.1.0](https://github.com/CommunitySolidServer/CommunitySolidServer/compare/v7.0.5...v7.1.0) (2024-05-24) ### Features diff --git a/package-lock.json b/package-lock.json index 97947be6f..1e372debc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@solid/community-server", - "version": "7.1.0", + "version": "7.1.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@solid/community-server", - "version": "7.1.0", + "version": "7.1.1", "license": "MIT", "dependencies": { "@comunica/context-entries": "^2.8.2", diff --git a/package.json b/package.json index bf8f87399..1f5958276 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@solid/community-server", - "version": "7.1.0", + "version": "7.1.1", "description": "Community Solid Server: an open and modular implementation of the Solid specifications", "license": "MIT", "homepage": "https://github.com/CommunitySolidServer/CommunitySolidServer#readme", From 3e8365bb2613737fb28c376b5967a351a1300432 Mon Sep 17 00:00:00 2001 From: elf Pavlik Date: Mon, 19 Aug 2024 00:58:53 -0600 Subject: [PATCH 70/71] fix: Use full encoded topic iri in streaming http receiveFrom url template * fix: use full encoded topic iri in streaming http receiveFrom url template * clean up urls and routing --- config/http/notifications/streaming-http.json | 1 + .../http/notifications/streaming-http/http.json | 12 ++++++------ .../StreamingHttpMetadataWriter.ts | 9 +++++---- .../StreamingHttpRequestHandler.ts | 6 ++++-- test/integration/StreamingHttpChannel2023.test.ts | 12 ++++++++---- .../StreamingHttpMetadataWriter.test.ts | 15 ++++++++++----- .../StreamingHttpRequestHandler.test.ts | 13 ++++++++----- 7 files changed, 42 insertions(+), 26 deletions(-) diff --git a/config/http/notifications/streaming-http.json b/config/http/notifications/streaming-http.json index f9336ed34..c2274b113 100644 --- a/config/http/notifications/streaming-http.json +++ b/config/http/notifications/streaming-http.json @@ -1,6 +1,7 @@ { "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", "import": [ + "css:config/http/notifications/base/description.json", "css:config/http/notifications/base/handler.json", "css:config/http/notifications/base/http.json", "css:config/http/notifications/base/storage.json", diff --git a/config/http/notifications/streaming-http/http.json b/config/http/notifications/streaming-http/http.json index 264d5f042..e53227ee9 100644 --- a/config/http/notifications/streaming-http/http.json +++ b/config/http/notifications/streaming-http/http.json @@ -2,16 +2,16 @@ "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld", "@graph": [ { - "comment": "Path prefix used by streaming HTTP receiveFrom endpoints", - "@id": "urn:solid-server:default:variable:streamingHTTPReceiveFromPrefix", - "valueRaw": ".notifications/StreamingHTTPChannel2023/" + "@id": "urn:solid-server:default:StreamingHTTP2023Route", + "@type": "RelativePathInteractionRoute", + "base": { "@id": "urn:solid-server:default:NotificationRoute" }, + "relativePath": "/StreamingHTTPChannel2023/" }, { "comment": "Creates updatesViaStreamingHttp2023 Link relations", "@id": "urn:solid-server:default:StreamingHttpMetadataWriter", "@type": "StreamingHttpMetadataWriter", - "baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" }, - "pathPrefix": { "@id": "urn:solid-server:default:variable:streamingHTTPReceiveFromPrefix" } + "route": { "@id": "urn:solid-server:default:StreamingHTTP2023Route" } }, { "comment": "Allows discovery of the corresponding streaming HTTP channel", @@ -32,7 +32,7 @@ "@id": "urn:solid-server:default:StreamingHttp2023RequestHandler", "@type": "StreamingHttpRequestHandler", "streamMap": { "@id": "urn:solid-server:default:StreamingHttpMap" }, - "pathPrefix": { "@id": "urn:solid-server:default:variable:streamingHTTPReceiveFromPrefix" }, + "route": { "@id": "urn:solid-server:default:StreamingHTTP2023Route" }, "generator": { "@id": "urn:solid-server:default:BaseNotificationGenerator" }, "serializer": { "@id": "urn:solid-server:default:BaseNotificationSerializer" }, "credentialsExtractor": { "@id": "urn:solid-server:default:CredentialsExtractor" }, diff --git a/src/server/notifications/StreamingHttpChannel2023/StreamingHttpMetadataWriter.ts b/src/server/notifications/StreamingHttpChannel2023/StreamingHttpMetadataWriter.ts index b345853dd..7c88c4a20 100644 --- a/src/server/notifications/StreamingHttpChannel2023/StreamingHttpMetadataWriter.ts +++ b/src/server/notifications/StreamingHttpChannel2023/StreamingHttpMetadataWriter.ts @@ -1,6 +1,8 @@ import { getLoggerFor } from '../../../logging/LogUtil'; import type { HttpResponse } from '../../HttpResponse'; import { addHeader } from '../../../util/HeaderUtil'; +import { joinUrl } from '../../../util/PathUtil'; +import type { InteractionRoute } from '../../../identity/interaction/routing/InteractionRoute'; import type { RepresentationMetadata } from '../../../http/representation/RepresentationMetadata'; import { MetadataWriter } from '../../../http/output/metadata/MetadataWriter'; @@ -12,15 +14,14 @@ export class StreamingHttpMetadataWriter extends MetadataWriter { protected readonly logger = getLoggerFor(this); public constructor( - private readonly baseUrl: string, - private readonly pathPrefix: string, + private readonly route: InteractionRoute, ) { super(); } public async handle(input: { response: HttpResponse; metadata: RepresentationMetadata }): Promise { - const resourcePath = input.metadata.identifier.value.replace(this.baseUrl, ''); - const receiveFrom = `${this.baseUrl}${this.pathPrefix}${resourcePath}`; + const encodedUrl = encodeURIComponent(input.metadata.identifier.value); + const receiveFrom = joinUrl(this.route.getPath(), encodedUrl); const link = `<${receiveFrom}>; rel="http://www.w3.org/ns/solid/terms#updatesViaStreamingHttp2023"`; this.logger.debug('Adding updatesViaStreamingHttp2023 to the Link header'); addHeader(input.response, 'Link', link); diff --git a/src/server/notifications/StreamingHttpChannel2023/StreamingHttpRequestHandler.ts b/src/server/notifications/StreamingHttpChannel2023/StreamingHttpRequestHandler.ts index 6d060e5ea..0169ef5e3 100644 --- a/src/server/notifications/StreamingHttpChannel2023/StreamingHttpRequestHandler.ts +++ b/src/server/notifications/StreamingHttpChannel2023/StreamingHttpRequestHandler.ts @@ -7,6 +7,7 @@ import { AccessMode } from '../../../authorization/permissions/Permissions'; import { OkResponseDescription } from '../../../http/output/response/OkResponseDescription'; import type { ResponseDescription } from '../../../http/output/response/ResponseDescription'; import { BasicRepresentation } from '../../../http/representation/BasicRepresentation'; +import type { InteractionRoute } from '../../../identity/interaction/routing/InteractionRoute'; import { getLoggerFor } from '../../../logging/LogUtil'; import type { OperationHttpHandlerInput } from '../../OperationHttpHandler'; import { OperationHttpHandler } from '../../OperationHttpHandler'; @@ -28,7 +29,7 @@ export class StreamingHttpRequestHandler extends OperationHttpHandler { public constructor( private readonly streamMap: StreamingHttpMap, - private readonly pathPrefix: string, + private readonly route: InteractionRoute, private readonly generator: NotificationGenerator, private readonly serializer: NotificationSerializer, private readonly credentialsExtractor: CredentialsExtractor, @@ -39,7 +40,8 @@ export class StreamingHttpRequestHandler extends OperationHttpHandler { } public async handle({ operation, request }: OperationHttpHandlerInput): Promise { - const topic = operation.target.path.replace(this.pathPrefix, ''); + const encodedUrl = operation.target.path.replace(this.route.getPath(), ''); + const topic = decodeURIComponent(encodedUrl); // Verify if the client is allowed to connect const credentials = await this.credentialsExtractor.handleSafe(request); diff --git a/test/integration/StreamingHttpChannel2023.test.ts b/test/integration/StreamingHttpChannel2023.test.ts index 4368070b4..e2c69828a 100644 --- a/test/integration/StreamingHttpChannel2023.test.ts +++ b/test/integration/StreamingHttpChannel2023.test.ts @@ -17,6 +17,7 @@ import namedNode = DataFactory.namedNode; const port = getPort('StreamingHTTPChannel2023'); const baseUrl = `http://localhost:${port}/`; +const pathPrefix = '.notifications/StreamingHTTPChannel2023'; const rootFilePath = getTestFolder('StreamingHTTPChannel2023'); const stores: [string, any][] = [ @@ -38,13 +39,16 @@ async function readChunk(reader: ReadableStreamDefaultReader): Promise { return new Store(parser.parse(notification)); } +function endpoint(topic: string): string { + return joinUrl(baseUrl, pathPrefix, encodeURIComponent(topic)); +} + describe.each(stores)('A server supporting StreamingHTTPChannel2023 using %s', (name, { configs, teardown }): void => { let app: App; let store: ResourceStore; const webId = 'http://example.com/card/#me'; const topic = joinUrl(baseUrl, '/foo'); - const pathPrefix = '.notifications/StreamingHTTPChannel2023'; - const receiveFrom = joinUrl(baseUrl, pathPrefix, '/foo'); + const receiveFrom = endpoint(topic); beforeAll(async(): Promise => { const variables = { @@ -246,7 +250,7 @@ describe.each(stores)('A server supporting StreamingHTTPChannel2023 using %s', ( it('prevents connecting to channels of restricted topics.', async(): Promise => { const restricted = joinUrl(baseUrl, '/restricted'); - const restrictedReceiveFrom = joinUrl(baseUrl, pathPrefix, '/restricted'); + const restrictedReceiveFrom = endpoint(restricted); await store.setRepresentation({ path: restricted }, new BasicRepresentation('new', 'text/plain')); // Only allow our WebID to read @@ -285,7 +289,7 @@ describe.each(stores)('A server supporting StreamingHTTPChannel2023 using %s', ( it('emits container notifications if contents get added or removed.', async(): Promise => { const resource = joinUrl(baseUrl, '/resource'); - const baseReceiveFrom = joinUrl(baseUrl, pathPrefix, '/'); + const baseReceiveFrom = endpoint(joinUrl(baseUrl, '/')); // Connecting to the base URL, which is the parent container const streamingResponse = await fetch(baseReceiveFrom); diff --git a/test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttpMetadataWriter.test.ts b/test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttpMetadataWriter.test.ts index 7b2110895..6f9257e84 100644 --- a/test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttpMetadataWriter.test.ts +++ b/test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttpMetadataWriter.test.ts @@ -2,19 +2,24 @@ import { createResponse } from 'node-mocks-http'; import { StreamingHttpMetadataWriter, } from '../../../../../src/server/notifications/StreamingHttpChannel2023/StreamingHttpMetadataWriter'; +import { + AbsolutePathInteractionRoute, +} from '../../../../../src/identity/interaction/routing/AbsolutePathInteractionRoute'; import { RepresentationMetadata } from '../../../../../src/http/representation/RepresentationMetadata'; import type { HttpResponse } from '../../../../../src/server/HttpResponse'; +import type { ResourceIdentifier } from '../../../../../src/http/representation/ResourceIdentifier'; describe('A StreamingHttpMetadataWriter', (): void => { - const baseUrl = 'http://example.org/'; - const pathPrefix = '.notifications/StreamingHTTPChannel2023/'; - const writer = new StreamingHttpMetadataWriter(baseUrl, pathPrefix); + const path = 'http://example.org/.notifications/StreamingHTTPChannel2023/'; + const route = new AbsolutePathInteractionRoute(path); + const writer = new StreamingHttpMetadataWriter(route); const rel = 'http://www.w3.org/ns/solid/terms#updatesViaStreamingHttp2023'; it('adds the correct link header.', async(): Promise => { + const topic: ResourceIdentifier = { path: 'http://example.com/foo' }; const response = createResponse() as HttpResponse; - const metadata = new RepresentationMetadata({ path: 'http://example.org/foo/bar/baz' }); + const metadata = new RepresentationMetadata(topic); await expect(writer.handle({ response, metadata })).resolves.toBeUndefined(); - expect(response.getHeaders()).toEqual({ link: `; rel="${rel}"` }); + expect(response.getHeaders()).toEqual({ link: `; rel="${rel}"` }); }); }); diff --git a/test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttpRequestHandler.test.ts b/test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttpRequestHandler.test.ts index 756297008..1c4e19862 100644 --- a/test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttpRequestHandler.test.ts +++ b/test/unit/server/notifications/StreamingHttpChannel2023/StreamingHttpRequestHandler.test.ts @@ -16,8 +16,8 @@ import { getLoggerFor } from '../../../../../src/logging/LogUtil'; import { StreamingHttpRequestHandler, } from '../../../../../src/server/notifications/StreamingHttpChannel2023/StreamingHttpRequestHandler'; +import { AbsolutePathInteractionRoute, StreamingHttpMap } from '../../../../../src'; import type { NotificationGenerator, NotificationSerializer } from '../../../../../src'; -import { StreamingHttpMap } from '../../../../../src'; import type { Notification } from '../../../../../src/server/notifications/Notification'; import { flushPromises } from '../../../../util/Util'; @@ -31,7 +31,7 @@ jest.mock('../../../../../src/logging/LogUtil', (): any => { describe('A StreamingHttpRequestHandler', (): void => { const logger: jest.Mocked = getLoggerFor('mock') as any; const topic: ResourceIdentifier = { path: 'http://example.com/foo' }; - const pathPrefix = '.notifications/StreamingHTTPChannel2023/'; + const path = 'http://example.com/.notifications/StreamingHTTPChannel2023/'; const channel: NotificationChannel = { id: 'id', topic: topic.path, @@ -52,6 +52,7 @@ describe('A StreamingHttpRequestHandler', (): void => { const request: HttpRequest = {} as any; const response: HttpResponse = {} as any; let representation: BasicRepresentation; + let route: AbsolutePathInteractionRoute; let streamMap: StreamingHttpMap; let operation: Operation; let generator: jest.Mocked; @@ -64,12 +65,14 @@ describe('A StreamingHttpRequestHandler', (): void => { beforeEach(async(): Promise => { operation = { method: 'GET', - target: { path: 'http://example.com/.notifications/StreamingHTTPChannel2023/foo' }, + target: { path: `${path}${encodeURIComponent(topic.path)}` }, body: new BasicRepresentation(), preferences: {}, }; representation = new BasicRepresentation(chunk, 'text/plain'); + route = new AbsolutePathInteractionRoute(path); + streamMap = new StreamingHttpMap(); generator = { @@ -95,7 +98,7 @@ describe('A StreamingHttpRequestHandler', (): void => { handler = new StreamingHttpRequestHandler( streamMap, - pathPrefix, + route, generator, serializer, credentialsExtractor, @@ -151,7 +154,7 @@ describe('A StreamingHttpRequestHandler', (): void => { } as any; handler = new StreamingHttpRequestHandler( streamMap, - pathPrefix, + route, generator, serializer, credentialsExtractor, From 221dcc41cd4a2f10482d77ac1fe18716695db16c Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Tue, 20 Aug 2024 07:30:18 +0200 Subject: [PATCH 71/71] chore(release): Release version 7.1.2 of the npm package --- CHANGELOG.md | 6 ++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 230cfc643..3b15af9a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file. +## [7.1.2](https://github.com/CommunitySolidServer/CommunitySolidServer/compare/v7.1.1...v7.1.2) (2024-08-20) + +### Fixes + +* Use full encoded topic iri in streaming http receiveFrom url template ([3e8365b](https://github.com/CommunitySolidServer/CommunitySolidServer/commit/3e8365bb2613737fb28c376b5967a351a1300432)) + ## [7.1.1](https://github.com/CommunitySolidServer/CommunitySolidServer/compare/v7.1.0...v7.1.1) (2024-08-07) ### Fixes diff --git a/package-lock.json b/package-lock.json index 1e372debc..52f485619 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@solid/community-server", - "version": "7.1.1", + "version": "7.1.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@solid/community-server", - "version": "7.1.1", + "version": "7.1.2", "license": "MIT", "dependencies": { "@comunica/context-entries": "^2.8.2", diff --git a/package.json b/package.json index 1f5958276..9162e2720 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@solid/community-server", - "version": "7.1.1", + "version": "7.1.2", "description": "Community Solid Server: an open and modular implementation of the Solid specifications", "license": "MIT", "homepage": "https://github.com/CommunitySolidServer/CommunitySolidServer#readme",